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}