mirror of
				https://github.com/optim-enterprises-bv/control-pane.git
				synced 2025-10-30 17:37:59 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			636 lines
		
	
	
		
			20 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			636 lines
		
	
	
		
			20 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| var fs = require('fs');
 | |
| var path = require('path');
 | |
| var relativePath = require('cached-path-relative');
 | |
| 
 | |
| var browserResolve = require('browser-resolve');
 | |
| var nodeResolve = require('resolve');
 | |
| var detective = require('detective');
 | |
| var through = require('through2');
 | |
| var concat = require('concat-stream');
 | |
| var parents = require('parents');
 | |
| var combine = require('stream-combiner2');
 | |
| var duplexer = require('duplexer2');
 | |
| var xtend = require('xtend');
 | |
| var defined = require('defined');
 | |
| 
 | |
| var inherits = require('inherits');
 | |
| var Transform = require('readable-stream').Transform;
 | |
| 
 | |
| module.exports = Deps;
 | |
| inherits(Deps, Transform);
 | |
| 
 | |
| function Deps (opts) {
 | |
|     var self = this;
 | |
|     if (!(this instanceof Deps)) return new Deps(opts);
 | |
|     Transform.call(this, { objectMode: true });
 | |
|     
 | |
|     if (!opts) opts = {};
 | |
|     
 | |
|     this.basedir = opts.basedir || process.cwd();
 | |
|     this.persistentCache = opts.persistentCache || function (file, id, pkg, fallback, cb) {
 | |
|         process.nextTick(function () {
 | |
|             fallback(null, cb);
 | |
|         });
 | |
|     };
 | |
|     this.cache = opts.cache;
 | |
|     this.fileCache = opts.fileCache;
 | |
|     this.pkgCache = opts.packageCache || {};
 | |
|     this.pkgFileCache = {};
 | |
|     this.pkgFileCachePending = {};
 | |
|     this._emittedPkg = {};
 | |
|     this._transformDeps = {};
 | |
|     this.visited = {};
 | |
|     this.walking = {};
 | |
|     this.entries = [];
 | |
|     this._input = [];
 | |
|     
 | |
|     this.paths = opts.paths || process.env.NODE_PATH || '';
 | |
|     if (typeof this.paths === 'string') {
 | |
|         var delimiter = path.delimiter || (process.platform === 'win32' ? ';' : ':');
 | |
|         this.paths = this.paths.split(delimiter);
 | |
|     }
 | |
|     this.paths = this.paths
 | |
|         .filter(Boolean)
 | |
|         .map(function (p) {
 | |
|             return path.resolve(self.basedir, p);
 | |
|         });
 | |
|     
 | |
|     this.transforms = [].concat(opts.transform).filter(Boolean);
 | |
|     this.globalTransforms = [].concat(opts.globalTransform).filter(Boolean);
 | |
|     this.resolver = opts.resolve || browserResolve;
 | |
|     this.detective = opts.detect || detective;
 | |
|     this.options = xtend(opts);
 | |
|     if (!this.options.modules) this.options.modules = {};
 | |
| 
 | |
|     // If the caller passes options.expose, store resolved pathnames for exposed
 | |
|     // modules in it. If not, set it anyway so it's defined later.
 | |
|     if (!this.options.expose) this.options.expose = {};
 | |
|     this.pending = 0;
 | |
|     this.inputPending = 0;
 | |
|     
 | |
|     var topfile = path.join(this.basedir, '__fake.js');
 | |
|     this.top = {
 | |
|         id: topfile,
 | |
|         filename: topfile,
 | |
|         paths: this.paths,
 | |
|         basedir: this.basedir
 | |
|     };
 | |
| }
 | |
| 
 | |
| Deps.prototype._isTopLevel = function (file) {
 | |
|     var isTopLevel = this.entries.some(function (main) {
 | |
|         var m = relativePath(path.dirname(main), file);
 | |
|         return m.split(/[\\\/]/).indexOf('node_modules') < 0;
 | |
|     });
 | |
|     if (!isTopLevel) {
 | |
|         var m = relativePath(this.basedir, file);
 | |
|         isTopLevel = m.split(/[\\\/]/).indexOf('node_modules') < 0;
 | |
|     }
 | |
|     return isTopLevel;
 | |
| };
 | |
| 
 | |
| Deps.prototype._transform = function (row, enc, next) {
 | |
|     var self = this;
 | |
|     if (typeof row === 'string') {
 | |
|         row = { file: row };
 | |
|     }
 | |
|     if (row.transform && row.global) {
 | |
|         this.globalTransforms.push([ row.transform, row.options ]);
 | |
|         return next();
 | |
|     }
 | |
|     else if (row.transform) {
 | |
|         this.transforms.push([ row.transform, row.options ]);
 | |
|         return next();
 | |
|     }
 | |
|     
 | |
|     self.pending ++;
 | |
|     var basedir = defined(row.basedir, self.basedir);
 | |
|     
 | |
|     if (row.entry !== false) {
 | |
|         self.entries.push(path.resolve(basedir, row.file || row.id));
 | |
|     }
 | |
|     
 | |
|     self.lookupPackage(row.file, function (err, pkg) {
 | |
|         if (err && self.options.ignoreMissing) {
 | |
|             self.emit('missing', row.file, self.top);
 | |
|             self.pending --;
 | |
|             return next();
 | |
|         }
 | |
|         if (err) return self.emit('error', err)
 | |
|         self.pending --;
 | |
|         self._input.push({ row: row, pkg: pkg });
 | |
|         next();
 | |
|     });
 | |
| };
 | |
| 
 | |
| Deps.prototype._flush = function () {
 | |
|     var self = this;
 | |
|     var files = {};
 | |
|     self._input.forEach(function (r) {
 | |
|         var w = r.row, f = files[w.file || w.id];
 | |
|         if (f) {
 | |
|             f.row.entry = f.row.entry || w.entry;
 | |
|             var ex = f.row.expose || w.expose;
 | |
|             f.row.expose = ex;
 | |
|             if (ex && f.row.file === f.row.id && w.file !== w.id) {
 | |
|                 f.row.id = w.id;
 | |
|             }
 | |
|         }
 | |
|         else files[w.file || w.id] = r;
 | |
|     });
 | |
|     
 | |
|     Object.keys(files).forEach(function (key) {
 | |
|         var r = files[key];
 | |
|         var pkg = r.pkg || {};
 | |
|         var dir = r.row.file ? path.dirname(r.row.file) : self.basedir;
 | |
|         if (!pkg.__dirname) pkg.__dirname = dir;
 | |
|         self.walk(r.row, xtend(self.top, {
 | |
|             filename: path.join(dir, '_fake.js')
 | |
|         }));
 | |
|     });
 | |
|     if (this.pending === 0) this.push(null);
 | |
|     this._ended = true;
 | |
| };
 | |
| 
 | |
| Deps.prototype.resolve = function (id, parent, cb) {
 | |
|     var self = this;
 | |
|     var opts = self.options;
 | |
|     
 | |
|     if (xhas(self.cache, parent.id, 'deps', id)
 | |
|     && self.cache[parent.id].deps[id]) {
 | |
|         var file = self.cache[parent.id].deps[id];
 | |
|         var pkg = self.pkgCache[file];
 | |
|         if (pkg) return cb(null, file, pkg);
 | |
|         return self.lookupPackage(file, function (err, pkg) {
 | |
|             cb(null, file, pkg);
 | |
|         });
 | |
|     }
 | |
|     
 | |
|     parent.packageFilter = function (p, x) {
 | |
|         var pkgdir = path.dirname(x);
 | |
|         if (opts.packageFilter) p = opts.packageFilter(p, x);
 | |
|         p.__dirname = pkgdir;
 | |
| 
 | |
|         return p;
 | |
|     };
 | |
| 
 | |
|     // have `resolve` do all the package.json lookups,
 | |
|     // see discussion in https://github.com/browserify/browser-resolve/issues/93#issuecomment-667837808
 | |
|     parent.package = undefined;
 | |
|     
 | |
|     if (opts.extensions) parent.extensions = opts.extensions;
 | |
|     if (opts.modules) parent.modules = opts.modules;
 | |
|     
 | |
|     self.resolver(id, parent, function onresolve (err, file, pkg, fakePath) {
 | |
|         if (err) return cb(err);
 | |
|         if (!file) return cb(new Error(
 | |
|             'module not found: "' + id + '" from file '
 | |
|             + parent.filename
 | |
|         ));
 | |
|         
 | |
|         if (!pkg || !pkg.__dirname) {
 | |
|             self.lookupPackage(file, function (err, p) {
 | |
|                 if (err) return cb(err);
 | |
|                 if (!p) p = {};
 | |
|                 if (!p.__dirname) p.__dirname = path.dirname(file);
 | |
|                 self.pkgCache[file] = p;
 | |
|                 onresolve(err, file, opts.packageFilter
 | |
|                     ? opts.packageFilter(p, p.__dirname) : p,
 | |
|                     fakePath
 | |
|                 );
 | |
|             });
 | |
|         }
 | |
|         else cb(err, file, pkg, fakePath);
 | |
|     });
 | |
| };
 | |
| 
 | |
| Deps.prototype.readFile = function (file, id, pkg) {
 | |
|     var self = this;
 | |
|     if (xhas(this.fileCache, file)) {
 | |
|         return toStream(this.fileCache[file]);
 | |
|     }
 | |
|     var rs = fs.createReadStream(file, {
 | |
|         encoding: 'utf8'
 | |
|     });
 | |
|     return rs;
 | |
| };
 | |
| 
 | |
| Deps.prototype.getTransforms = function (file, pkg, opts) {
 | |
|     if (!opts) opts = {};
 | |
|     var self = this;
 | |
|     
 | |
|     var isTopLevel;
 | |
|     if (opts.builtin || opts.inNodeModules) isTopLevel = false;
 | |
|     else isTopLevel = this._isTopLevel(file);
 | |
|     
 | |
|     var transforms = [].concat(isTopLevel ? this.transforms : [])
 | |
|         .concat(getTransforms(pkg, {
 | |
|             globalTransform: this.globalTransforms,
 | |
|             transformKey: this.options.transformKey
 | |
|         }))
 | |
|     ;
 | |
|     if (transforms.length === 0) return through();
 | |
|     
 | |
|     var pending = transforms.length;
 | |
|     var streams = [];
 | |
|     var input = through();
 | |
|     var output = through();
 | |
|     var dup = duplexer(input, output);
 | |
|     
 | |
|     for (var i = 0; i < transforms.length; i++) (function (i) {
 | |
|         makeTransform(transforms[i], function (err, trs) {
 | |
|             if (err) {
 | |
|                 return dup.emit('error', err);
 | |
|             }
 | |
|             streams[i] = trs;
 | |
|             if (-- pending === 0) done();
 | |
|         });
 | |
|     })(i);
 | |
|     return dup;
 | |
|     
 | |
|     function done () {
 | |
|         var middle = combine.apply(null, streams);
 | |
|         middle.on('error', function (err) {
 | |
|             err.message += ' while parsing file: ' + file;
 | |
|             if (!err.filename) err.filename = file;
 | |
|             dup.emit('error', err);
 | |
|         });
 | |
|         input.pipe(middle).pipe(output);
 | |
|     }
 | |
|     
 | |
|     function makeTransform (tr, cb) {
 | |
|         var trOpts = {};
 | |
|         if (Array.isArray(tr)) {
 | |
|             trOpts = tr[1] || {};
 | |
|             tr = tr[0];
 | |
|         }
 | |
|         trOpts._flags = trOpts.hasOwnProperty('_flags') ? trOpts._flags : self.options;
 | |
|         if (typeof tr === 'function') {
 | |
|             var t = tr(file, trOpts);
 | |
|             // allow transforms to `stream.emit('dep', path)` to add dependencies for this file
 | |
|             t.on('dep', function (dep) {
 | |
|                 if (!self._transformDeps[file]) self._transformDeps[file] = [];
 | |
|                 self._transformDeps[file].push(dep);
 | |
|             });
 | |
|             self.emit('transform', t, file);
 | |
|             nextTick(cb, null, wrapTransform(t));
 | |
|         }
 | |
|         else {
 | |
|             loadTransform(tr, trOpts, function (err, trs) {
 | |
|                 if (err) return cb(err);
 | |
|                 cb(null, wrapTransform(trs));
 | |
|             });
 | |
|         }
 | |
|     }
 | |
|     
 | |
|     function loadTransform (id, trOpts, cb) {
 | |
|         var params = {
 | |
|             basedir: path.dirname(file),
 | |
|             preserveSymlinks: false
 | |
|         };
 | |
|         nodeResolve(id, params, function nr (err, res, again) {
 | |
|             if (err && again) return cb && cb(err);
 | |
|             
 | |
|             if (err) {
 | |
|                 params.basedir = pkg.__dirname;
 | |
|                 return nodeResolve(id, params, function (e, r) {
 | |
|                     nr(e, r, true);
 | |
|                 });
 | |
|             }
 | |
|             
 | |
|             if (!res) return cb(new Error(
 | |
|                 'cannot find transform module ' + tr
 | |
|                 + ' while transforming ' + file
 | |
|             ));
 | |
|             
 | |
|             var r = require(res);
 | |
|             if (typeof r !== 'function') {
 | |
|                 return cb(new Error(
 | |
|                     'Unexpected ' + typeof r + ' exported by the '
 | |
|                     + JSON.stringify(res) + ' package. '
 | |
|                     + 'Expected a transform function.'
 | |
|                 ));
 | |
|             }
 | |
|             
 | |
|             var trs = r(file, trOpts);
 | |
|             // allow transforms to `stream.emit('dep', path)` to add dependencies for this file
 | |
|             trs.on('dep', function (dep) {
 | |
|                 if (!self._transformDeps[file]) self._transformDeps[file] = [];
 | |
|                 self._transformDeps[file].push(dep);
 | |
|             });
 | |
|             self.emit('transform', trs, file);
 | |
|             cb(null, trs);
 | |
|         });
 | |
|     }
 | |
| };
 | |
| 
 | |
| Deps.prototype.walk = function (id, parent, cb) {
 | |
|     var self = this;
 | |
|     var opts = self.options;
 | |
|     this.pending ++;
 | |
|     
 | |
|     var rec = {};
 | |
|     var input;
 | |
|     if (typeof id === 'object') {
 | |
|         rec = xtend(id);
 | |
|         if (rec.entry === false) delete rec.entry;
 | |
|         id = rec.file || rec.id;
 | |
|         input = true;
 | |
|         this.inputPending ++;
 | |
|     }
 | |
|     
 | |
|     self.resolve(id, parent, function (err, file, pkg, fakePath) {
 | |
|         // this is checked early because parent.modules is also modified
 | |
|         // by this function.
 | |
|         var builtin = has(parent.modules, id);
 | |
| 
 | |
|         if (rec.expose) {
 | |
|             // Set options.expose to make the resolved pathname available to the
 | |
|             // caller. They may or may not have requested it, but it's harmless
 | |
|             // to set this if they didn't.
 | |
|             self.options.expose[rec.expose] =
 | |
|                 self.options.modules[rec.expose] = file;
 | |
|         }
 | |
|         if (pkg && !self._emittedPkg[pkg.__dirname]) {
 | |
|             self._emittedPkg[pkg.__dirname] = true;
 | |
|             self.emit('package', pkg);
 | |
|         }
 | |
|         
 | |
|         if (opts.postFilter && !opts.postFilter(id, file, pkg)) {
 | |
|             if (--self.pending === 0) self.push(null);
 | |
|             if (input) --self.inputPending;
 | |
|             return cb && cb(null, undefined);
 | |
|         }
 | |
|         if (err && rec.source) {
 | |
|             file = rec.file;
 | |
|             
 | |
|             var ts = self.getTransforms(file, pkg);
 | |
|             ts.on('error', function (err) {
 | |
|                 self.emit('error', err);
 | |
|             });
 | |
|             ts.pipe(concat(function (body) {
 | |
|                 rec.source = body.toString('utf8');
 | |
|                 fromSource(file, rec.source, pkg);
 | |
|             }));
 | |
|             return ts.end(rec.source);
 | |
|         }
 | |
|         if (err && self.options.ignoreMissing) {
 | |
|             if (--self.pending === 0) self.push(null);
 | |
|             if (input) --self.inputPending;
 | |
|             self.emit('missing', id, parent);
 | |
|             return cb && cb(null, undefined);
 | |
|         }
 | |
|         if (err) {
 | |
|             var message = 'Can\'t walk dependency graph: ' + err.message;
 | |
|             message += '\n    required by ' + parent.filename;
 | |
|             err.message = message;
 | |
|             return self.emit('error', err);
 | |
|         }
 | |
|         if (self.visited[file]) {
 | |
|             if (-- self.pending === 0) self.push(null);
 | |
|             if (input) --self.inputPending;
 | |
|             return cb && cb(null, file);
 | |
|         }
 | |
|         self.visited[file] = true;
 | |
|         
 | |
|         if (rec.source) {
 | |
|             var ts = self.getTransforms(file, pkg);
 | |
|             ts.on('error', function (err) {
 | |
|                 self.emit('error', err);
 | |
|             });
 | |
|             ts.pipe(concat(function (body) {
 | |
|                 rec.source = body.toString('utf8');
 | |
|                 fromSource(file, rec.source, pkg);
 | |
|             }));
 | |
|             return ts.end(rec.source);
 | |
|         }
 | |
|         
 | |
|         var c = self.cache && self.cache[file];
 | |
|         if (c) return fromDeps(file, c.source, c.package, fakePath, Object.keys(c.deps));
 | |
|         
 | |
|         self.persistentCache(file, id, pkg, persistentCacheFallback, function (err, c) {
 | |
|             self.emit('file', file, id);
 | |
|             if (err) {
 | |
|                 self.emit('error', err);
 | |
|                 return;
 | |
|             }
 | |
|             fromDeps(file, c.source, c.package, fakePath, Object.keys(c.deps));
 | |
|         });
 | |
| 
 | |
|         function persistentCacheFallback (dataAsString, cb) {
 | |
|             var stream = dataAsString ? toStream(dataAsString) : self.readFile(file, id, pkg).on('error', cb);
 | |
|             stream
 | |
|                 .pipe(self.getTransforms(fakePath || file, pkg, {
 | |
|                     builtin: builtin,
 | |
|                     inNodeModules: parent.inNodeModules
 | |
|                 }))
 | |
|                 .on('error', cb)
 | |
|                 .pipe(concat(function (body) {
 | |
|                     var src = body.toString('utf8');
 | |
|                     try { var deps = getDeps(file, src); }
 | |
|                     catch (err) { cb(err); }
 | |
|                     if (deps) {
 | |
|                         cb(null, {
 | |
|                             source: src,
 | |
|                             package: pkg,
 | |
|                             deps: deps.reduce(function (deps, dep) {
 | |
|                                 deps[dep] = true;
 | |
|                                 return deps;
 | |
|                             }, {})
 | |
|                         });
 | |
|                     }
 | |
|                 }));
 | |
|         }
 | |
|     });
 | |
| 
 | |
|     function getDeps (file, src) {
 | |
|         var deps = rec.noparse ? [] : self.parseDeps(file, src);
 | |
|         // dependencies emitted by transforms
 | |
|         if (self._transformDeps[file]) deps = deps.concat(self._transformDeps[file]);
 | |
|         return deps;
 | |
|     }
 | |
| 
 | |
|     function fromSource (file, src, pkg, fakePath) {
 | |
|         var deps = getDeps(file, src);
 | |
|         if (deps) fromDeps(file, src, pkg, fakePath, deps);
 | |
|     }
 | |
|     
 | |
|     function fromDeps (file, src, pkg, fakePath, deps) {
 | |
|         var p = deps.length;
 | |
|         var resolved = {};
 | |
|         
 | |
|         if (input) --self.inputPending;
 | |
|         
 | |
|         (function resolve () {
 | |
|             if (self.inputPending > 0) return setTimeout(resolve);
 | |
|             deps.forEach(function (id) {
 | |
|                 if (opts.filter && !opts.filter(id)) {
 | |
|                     resolved[id] = false;
 | |
|                     if (--p === 0) done();
 | |
|                     return;
 | |
|                 }
 | |
|                 var isTopLevel = self._isTopLevel(fakePath || file);
 | |
|                 var current = {
 | |
|                     id: file,
 | |
|                     filename: file,
 | |
|                     basedir: path.dirname(file),
 | |
|                     paths: self.paths,
 | |
|                     package: pkg,
 | |
|                     inNodeModules: parent.inNodeModules || !isTopLevel
 | |
|                 };
 | |
|                 self.walk(id, current, function (err, r) {
 | |
|                     resolved[id] = r;
 | |
|                     if (--p === 0) done();
 | |
|                 });
 | |
|             });
 | |
|             if (deps.length === 0) done();
 | |
|         })();
 | |
|         
 | |
|         function done () {
 | |
|             if (!rec.id) rec.id = file;
 | |
|             if (!rec.source) rec.source = src;
 | |
|             if (!rec.deps) rec.deps = resolved;
 | |
|             if (!rec.file) rec.file = file;
 | |
|             
 | |
|             if (self.entries.indexOf(file) >= 0) {
 | |
|                 rec.entry = true;
 | |
|             }
 | |
|             self.push(rec);
 | |
|             
 | |
|             if (cb) cb(null, file);
 | |
|             if (-- self.pending === 0) self.push(null);
 | |
|         }
 | |
|     }
 | |
| };
 | |
| 
 | |
| Deps.prototype.parseDeps = function (file, src, cb) {
 | |
|     var self = this;
 | |
|     if (this.options.noParse === true) return [];
 | |
|     if (/\.json$/.test(file)) return [];
 | |
|     
 | |
|     if (Array.isArray(this.options.noParse)
 | |
|     && this.options.noParse.indexOf(file) >= 0) {
 | |
|         return [];
 | |
|     }
 | |
|     
 | |
|     try { var deps = self.detective(src) }
 | |
|     catch (ex) {
 | |
|         var message = ex && ex.message ? ex.message : ex;
 | |
|         throw new Error(
 | |
|             'Parsing file ' + file + ': ' + message
 | |
|         );
 | |
|     }
 | |
|     return deps;
 | |
| };
 | |
| 
 | |
| Deps.prototype.lookupPackage = function (file, cb) {
 | |
|     var self = this;
 | |
|     
 | |
|     var cached = this.pkgCache[file];
 | |
|     if (cached) return nextTick(cb, null, cached);
 | |
|     if (cached === false) return nextTick(cb, null, undefined);
 | |
|     
 | |
|     var dirs = parents(file ? path.dirname(file) : self.basedir);
 | |
|     
 | |
|     (function next () {
 | |
|         if (dirs.length === 0) {
 | |
|             self.pkgCache[file] = false;
 | |
|             return cb(null, undefined);
 | |
|         }
 | |
|         var dir = dirs.shift();
 | |
|         if (dir.split(/[\\\/]/).slice(-1)[0] === 'node_modules') {
 | |
|             return cb(null, undefined);
 | |
|         }
 | |
|         
 | |
|         var pkgfile = path.join(dir, 'package.json');
 | |
|         
 | |
|         var cached = self.pkgCache[pkgfile];
 | |
|         if (cached) return nextTick(cb, null, cached);
 | |
|         else if (cached === false) return next();
 | |
|         
 | |
|         var pcached = self.pkgFileCachePending[pkgfile];
 | |
|         if (pcached) return pcached.push(onpkg);
 | |
|         pcached = self.pkgFileCachePending[pkgfile] = [];
 | |
|         
 | |
|         fs.readFile(pkgfile, function (err, src) {
 | |
|             if (err) return onpkg();
 | |
|             try { var pkg = JSON.parse(src) }
 | |
|             catch (err) {
 | |
|                 return onpkg(new Error([
 | |
|                     err + ' while parsing json file ' + pkgfile
 | |
|                 ].join('')));
 | |
|             }
 | |
|             pkg.__dirname = dir;
 | |
|             
 | |
|             self.pkgCache[pkgfile] = pkg;
 | |
|             self.pkgCache[file] = pkg;
 | |
|             onpkg(null, pkg);
 | |
|         });
 | |
|         
 | |
|         function onpkg (err, pkg) {
 | |
|             if (self.pkgFileCachePending[pkgfile]) {
 | |
|                 var fns = self.pkgFileCachePending[pkgfile];
 | |
|                 delete self.pkgFileCachePending[pkgfile];
 | |
|                 fns.forEach(function (f) { f(err, pkg) });
 | |
|             }
 | |
|             if (err) cb(err);
 | |
|             else if (pkg && typeof pkg === 'object') cb(null, pkg);
 | |
|             else {
 | |
|                 self.pkgCache[pkgfile] = false;
 | |
|                 next();
 | |
|             }
 | |
|         }
 | |
|     })();
 | |
| };
 | |
|  
 | |
| function getTransforms (pkg, opts) {
 | |
|     var trx = [];
 | |
|     if (opts.transformKey) {
 | |
|         var n = pkg;
 | |
|         var keys = opts.transformKey;
 | |
|         for (var i = 0; i < keys.length; i++) {
 | |
|             if (n && typeof n === 'object') n = n[keys[i]];
 | |
|             else break;
 | |
|         }
 | |
|         if (i === keys.length) {
 | |
|             trx = [].concat(n).filter(Boolean);
 | |
|         }
 | |
|     }
 | |
|     return trx.concat(opts.globalTransform || []);
 | |
| }
 | |
| 
 | |
| function nextTick (cb) {
 | |
|     var args = [].slice.call(arguments, 1);
 | |
|     process.nextTick(function () { cb.apply(null, args) });
 | |
| }
 | |
| 
 | |
| function xhas (obj) {
 | |
|     if (!obj) return false;
 | |
|     for (var i = 1; i < arguments.length; i++) {
 | |
|         var key = arguments[i];
 | |
|         if (!has(obj, key)) return false;
 | |
|         obj = obj[key];
 | |
|     }
 | |
|     return true;
 | |
| }
 | |
| 
 | |
| function toStream (dataAsString) {
 | |
|     var tr = through();
 | |
|     tr.push(dataAsString);
 | |
|     tr.push(null);
 | |
|     return tr;
 | |
| }
 | |
| 
 | |
| function has (obj, key) {
 | |
|     return obj && Object.prototype.hasOwnProperty.call(obj, key);
 | |
| }
 | |
| 
 | |
| function wrapTransform (tr) {
 | |
|     if (typeof tr.read === 'function') return tr;
 | |
|     var input = through(), output = through();
 | |
|     input.pipe(tr).pipe(output);
 | |
|     var wrapper = duplexer(input, output);
 | |
|     tr.on('error', function (err) { wrapper.emit('error', err) });
 | |
|     return wrapper;
 | |
| }
 | 
