summaryrefslogtreecommitdiff
path: root/deps/npm/node_modules/path-array/index.js
blob: 40b982d2f17053245553a1d644d92ad26afc8363 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137

/**
 * 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.__get__ = function get (index) {
  return this._array()[index];
};

/**
 * ArrayIndex [0]= setter operator implementation.
 *
 * @api private
 */

PathArray.prototype.__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;
  };
});