mirror of https://github.com/lukechilds/node.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
137 lines
3.0 KiB
137 lines
3.0 KiB
|
|
/**
|
|
* Module dependencies.
|
|
*/
|
|
|
|
var inherits = require('util').inherits;
|
|
var delimiter = require('path').delimiter || ':';
|
|
var ArrayIndex = require('array-index');
|
|
|
|
/**
|
|
* Module exports.
|
|
*/
|
|
|
|
module.exports = PathArray;
|
|
|
|
/**
|
|
* `PathArray` constructor. Treat your `$PATH` like a mutable JavaScript Array!
|
|
*
|
|
* @param {Env} env - `process.env` object to use.
|
|
* @param {String} [property] - optional property name to use (`PATH` by default).
|
|
* @public
|
|
*/
|
|
|
|
function PathArray (env, property) {
|
|
if (!(this instanceof PathArray)) return new PathArray(env);
|
|
ArrayIndex.call(this);
|
|
|
|
this.property = property || 'PATH';
|
|
|
|
// overwrite only the `get` operator of the ".length" property
|
|
Object.defineProperty(this, 'length', {
|
|
get: this._getLength
|
|
});
|
|
|
|
// store the `process.env` object as a non-enumerable `_env`
|
|
Object.defineProperty(this, '_env', {
|
|
value: env || process.env,
|
|
writable: true,
|
|
enumerable: false,
|
|
configurable: true
|
|
});
|
|
|
|
// need to invoke the `length` getter to ensure that the
|
|
// indexed getters/setters are set up at this point
|
|
void(this.length);
|
|
}
|
|
|
|
// inherit from ArrayIndex
|
|
inherits(PathArray, ArrayIndex);
|
|
|
|
/**
|
|
* Returns the current $PATH representation as an Array.
|
|
*
|
|
* @api private
|
|
*/
|
|
|
|
PathArray.prototype._array = function () {
|
|
var path = this._env[this.property];
|
|
if (!path) return [];
|
|
return path.split(delimiter);
|
|
};
|
|
|
|
/**
|
|
* Sets the `env` object's `PATH` string to the values in the passed in Array
|
|
* instance.
|
|
*
|
|
* @api private
|
|
*/
|
|
|
|
PathArray.prototype._setArray = function (arr) {
|
|
// mutate the $PATH
|
|
this._env[this.property] = arr.join(delimiter);
|
|
};
|
|
|
|
/**
|
|
* `.length` getter operation implementation.
|
|
*
|
|
* @api private
|
|
*/
|
|
|
|
PathArray.prototype._getLength = function () {
|
|
var length = this._array().length;
|
|
|
|
// invoke the ArrayIndex internal `set` operator to ensure that
|
|
// there's getters/setters defined for the determined length so far...
|
|
this.length = length;
|
|
|
|
return length;
|
|
};
|
|
|
|
/**
|
|
* ArrayIndex [0] getter operator implementation.
|
|
*
|
|
* @api private
|
|
*/
|
|
|
|
PathArray.prototype[ArrayIndex.get] = function get (index) {
|
|
return this._array()[index];
|
|
};
|
|
|
|
/**
|
|
* ArrayIndex [0]= setter operator implementation.
|
|
*
|
|
* @api private
|
|
*/
|
|
|
|
PathArray.prototype[ArrayIndex.set] = function set (index, value) {
|
|
var arr = this._array();
|
|
arr[index] = value;
|
|
this._setArray(arr);
|
|
return value;
|
|
};
|
|
|
|
/**
|
|
* `toString()` returns the current $PATH string.
|
|
*
|
|
* @api public
|
|
*/
|
|
|
|
PathArray.prototype.toString = function toString () {
|
|
return this._env[this.property] || '';
|
|
};
|
|
|
|
// proxy the JavaScript Array functions, and mutate the $PATH
|
|
Object.getOwnPropertyNames(Array.prototype).forEach(function (name) {
|
|
if ('constructor' == name) return;
|
|
if ('function' != typeof Array.prototype[name]) return;
|
|
if (/to(Locale)?String/.test(name)) return;
|
|
//console.log('proxy %s', name);
|
|
|
|
PathArray.prototype[name] = function () {
|
|
var arr = this._array();
|
|
var rtn = arr[name].apply(arr, arguments);
|
|
this._setArray(arr);
|
|
return rtn;
|
|
};
|
|
});
|
|
|