arnaucube
arnaucube/thoughtsPublic Self-hosted repository
thoughts/node_modules/mongoose/node_modules/mpath/lib/index.js
node_modules/mongoose/node_modules/mpath/lib/index.jsRaw
  1
  2/**
  3 * Returns the value of object `o` at the given `path`.
  4 *
  5 * ####Example:
  6 *
  7 *     var obj = {
  8 *         comments: [
  9 *             { title: 'exciting!', _doc: { title: 'great!' }}
 10 *           , { title: 'number dos' }
 11 *         ]
 12 *     }
 13 *
 14 *     mpath.get('comments.0.title', o)         // 'exciting!'
 15 *     mpath.get('comments.0.title', o, '_doc') // 'great!'
 16 *     mpath.get('comments.title', o)           // ['exciting!', 'number dos']
 17 *
 18 *     // summary
 19 *     mpath.get(path, o)
 20 *     mpath.get(path, o, special)
 21 *     mpath.get(path, o, map)
 22 *     mpath.get(path, o, special, map)
 23 *
 24 * @param {String} path
 25 * @param {Object} o
 26 * @param {String} [special] When this property name is present on any object in the path, walking will continue on the value of this property.
 27 * @param {Function} [map] Optional function which receives each individual found value. The value returned from `map` is used in the original values place.
 28 */
 29
 30exports.get = function (path, o, special, map) {
 31  if ('function' == typeof special) {
 32    map = special;
 33    special = undefined;
 34  }
 35
 36  map || (map = K);
 37
 38  var parts = 'string' == typeof path
 39    ? path.split('.')
 40    : path
 41
 42  if (!Array.isArray(parts)) {
 43    throw new TypeError('Invalid `path`. Must be either string or array');
 44  }
 45
 46  var obj = o
 47    , part;
 48
 49  for (var i = 0; i < parts.length; ++i) {
 50    part = parts[i];
 51
 52    if (Array.isArray(obj) && !/^\d+$/.test(part)) {
 53      // reading a property from the array items
 54      var paths = parts.slice(i);
 55
 56      return obj.map(function (item) {
 57        return item
 58          ? exports.get(paths, item, special, map)
 59          : map(undefined);
 60      });
 61    }
 62
 63    obj = special && obj[special]
 64      ? obj[special][part]
 65      : obj[part];
 66
 67    if (!obj) return map(obj);
 68  }
 69
 70  return map(obj);
 71}
 72
 73/**
 74 * Sets the `val` at the given `path` of object `o`.
 75 *
 76 * @param {String} path
 77 * @param {Anything} val
 78 * @param {Object} o
 79 * @param {String} [special] When this property name is present on any object in the path, walking will continue on the value of this property.
 80 * @param {Function} [map] Optional function which is passed each individual value before setting it. The value returned from `map` is used in the original values place.
 81
 82 */
 83
 84exports.set = function (path, val, o, special, map, _copying) {
 85  if ('function' == typeof special) {
 86    map = special;
 87    special = undefined;
 88  }
 89
 90  map || (map = K);
 91
 92  var parts = 'string' == typeof path
 93    ? path.split('.')
 94    : path
 95
 96  if (!Array.isArray(parts)) {
 97    throw new TypeError('Invalid `path`. Must be either string or array');
 98  }
 99
100  if (null == o) return;
101
102  // the existance of $ in a path tells us if the user desires
103  // the copying of an array instead of setting each value of
104  // the array to the one by one to matching positions of the
105  // current array.
106  var copy = _copying || /\$/.test(path)
107    , obj = o
108    , part
109
110  for (var i = 0, len = parts.length - 1; i < len; ++i) {
111    part = parts[i];
112
113    if ('$' == part) {
114      if (i == len - 1) {
115        break;
116      } else {
117        continue;
118      }
119    }
120
121    if (Array.isArray(obj) && !/^\d+$/.test(part)) {
122      var paths = parts.slice(i);
123      if (!copy && Array.isArray(val)) {
124        for (var j = 0; j < obj.length && j < val.length; ++j) {
125          // assignment of single values of array
126          exports.set(paths, val[j], obj[j], special, map, copy);
127        }
128      } else {
129        for (var j = 0; j < obj.length; ++j) {
130          // assignment of entire value
131          exports.set(paths, val, obj[j], special, map, copy);
132        }
133      }
134      return;
135    }
136
137    obj = special && obj[special]
138      ? obj[special][part]
139      : obj[part];
140
141    if (!obj) return;
142  }
143
144  // process the last property of the path
145
146  part = parts[len];
147
148  // use the special property if exists
149  if (special && obj[special]) {
150    obj = obj[special];
151  }
152
153  // set the value on the last branch
154  if (Array.isArray(obj) && !/^\d+$/.test(part)) {
155    if (!copy && Array.isArray(val)) {
156      for (var item, j = 0; j < obj.length && j < val.length; ++j) {
157        item = obj[j];
158        if (item) {
159          if (item[special]) item = item[special];
160          item[part] = map(val[j]);
161        }
162      }
163    } else {
164      for (var j = 0; j < obj.length; ++j) {
165        item = obj[j];
166        if (item) {
167          if (item[special]) item = item[special];
168          item[part] = map(val);
169        }
170      }
171    }
172  } else {
173    obj[part] = map(val);
174  }
175}
176
177/*!
178 * Returns the value passed to it.
179 */
180
181function K (v) {
182  return v;
183}