1 | ;
|
2 |
|
3 | var hasOwn = Object.prototype.hasOwnProperty;
|
4 | var utils = require('./utils');
|
5 |
|
6 | /**
|
7 | * Specify a fallback value to use when the desired
|
8 | * value is undefined. Note that undefined variables
|
9 | * that are _not object properties_ with throw an error.
|
10 | *
|
11 | * ```js
|
12 | * // when `title` is undefined, use the generic `site.title`
|
13 | * <%= fallback(page.title, site.title) %>
|
14 | * ```
|
15 | *
|
16 | * @param {*} `a` The desired value.
|
17 | * @param {*} `b` The fallback ("default") value
|
18 | * @return {*} Either `a` or `b`
|
19 | * @api public
|
20 | */
|
21 |
|
22 | exports.fallback = function fallback(a, b) {
|
23 | return a != null ? a : b;
|
24 | };
|
25 |
|
26 | /**
|
27 | * Stringify an object using `JSON.stringify()`.
|
28 | *
|
29 | * ```js
|
30 | * <%= stringify({a: "a"}) %>
|
31 | * //=> '{"a":"a"}'
|
32 | * ```
|
33 | *
|
34 | * @param {Object} `object`
|
35 | * @return {String}
|
36 | * @api public
|
37 | */
|
38 |
|
39 | exports.stringify = function stringify(obj) {
|
40 | return JSON.stringify(obj);
|
41 | };
|
42 |
|
43 | /**
|
44 | * Parse a string into an object using `JSON.parse()`.
|
45 | *
|
46 | * ```js
|
47 | * <%= parse('{"foo":"bar"}')["foo"] %>
|
48 | * //=> 'bar'
|
49 | * ```
|
50 | *
|
51 | * @param {String} `str` The string to parse.
|
52 | * @return {Object} The parsed object.
|
53 | * @api public
|
54 | */
|
55 |
|
56 | exports.parse = function parse(str) {
|
57 | return JSON.parse(str);
|
58 | };
|
59 |
|
60 | /**
|
61 | * Use property paths (`a.b.c`) get a nested value from an object.
|
62 | *
|
63 | * ```js
|
64 | * <%= get({a: {b: 'c'}}, 'a.b') %>
|
65 | * //=> 'c'
|
66 | * ```
|
67 | *
|
68 | * @param {Object} `object`
|
69 | * @param {String} `path` Dot notation for the property to get.
|
70 | * @return {String}
|
71 | * @api public
|
72 | */
|
73 |
|
74 | exports.get = function get(obj, prop) {
|
75 | return utils.get.apply(utils.get, arguments);
|
76 | };
|
77 |
|
78 | /**
|
79 | * Returns an array of keys from the given `object`.
|
80 | *
|
81 | * ```js
|
82 | * <%= keys({a: 'b', c: 'd'}) %>
|
83 | * //=> '["a", "c"]'
|
84 | * ```
|
85 | *
|
86 | * @param {Object} `object`
|
87 | * @return {Array} Keys from `object`
|
88 | * @api public
|
89 | */
|
90 |
|
91 | exports.keys = function keys(obj) {
|
92 | return Object.keys(obj);
|
93 | };
|
94 |
|
95 | /**
|
96 | * Return true if the given `value` is an object, and
|
97 | * not `null` or an array.
|
98 | *
|
99 | * ```js
|
100 | * <%= isObject(['a', 'b', 'c']) %>
|
101 | * //=> 'false'
|
102 | *
|
103 | * <%= isObject({a: 'b'}) %>
|
104 | * //=> 'true'
|
105 | * ```
|
106 | *
|
107 | * @param {Object} `value` The value to check.
|
108 | * @return {Boolean}
|
109 | * @api public
|
110 | */
|
111 |
|
112 | exports.isObject = function isObject(val) {
|
113 | return utils.typeOf(val) === 'object';
|
114 | };
|
115 |
|
116 | /**
|
117 | * Return true if the given `value` is a plain object.
|
118 | *
|
119 | * ```js
|
120 | * <%= isPlainObject(['a', 'b', 'c']) %>
|
121 | * //=> 'false'
|
122 | *
|
123 | * <%= isPlainObject({a: 'b'}) %>
|
124 | * //=> 'true'
|
125 | *
|
126 | * <%= isPlainObject(/foo/g) %>
|
127 | * //=> 'false'
|
128 | * ```
|
129 | *
|
130 | * @param {Object} `value` The value to check.
|
131 | * @return {Boolean}
|
132 | * @api public
|
133 | */
|
134 |
|
135 | exports.isPlainObject = function isPlainObject(val) {
|
136 | return utils.isPlainObject(val);
|
137 | };
|
138 |
|
139 | /**
|
140 | * Return true if `key` is an own, enumerable property
|
141 | * of the given `obj`.
|
142 | *
|
143 | * @param {Object} `object`
|
144 | * @param {String} `key`
|
145 | * @return {Boolean}
|
146 | * @api public
|
147 | */
|
148 |
|
149 | exports.hasOwn = function hasOwn_(obj, key) {
|
150 | return hasOwn.call(obj, key);
|
151 | };
|
152 |
|
153 | /**
|
154 | * Return a copy of `object` exclusing the given `keys`.
|
155 | *
|
156 | * ```js
|
157 | * <%= omit({a: 'a', b: 'b', c: 'c'}, ['a', 'c']) %>
|
158 | * //=> '{b: "b"}'
|
159 | * ```
|
160 | *
|
161 | * @param {Object} `object` Object with keys to omit.
|
162 | * @param {String} `keys` Keys to omit.
|
163 | * @return {Boolean}
|
164 | * @api public
|
165 | */
|
166 |
|
167 | exports.omit = function omit(o, keys) {
|
168 | return utils.omit.apply(utils.omit, arguments);
|
169 | };
|
170 |
|
171 | /**
|
172 | * Return a copy of `object` exclusing the given `keys`.
|
173 | *
|
174 | * ```js
|
175 | * <%= omit({a: 'a', b: 'b', c: 'c'}, ['a', 'c']) %>
|
176 | * //=> '{b: "b"}'
|
177 | * ```
|
178 | *
|
179 | * @param {Object} `object` Object with keys to omit.
|
180 | * @param {String} `keys` Keys to omit.
|
181 | * @return {Boolean}
|
182 | * @api public
|
183 | */
|
184 |
|
185 | exports.forIn = function forIn(obj, fn, context) {
|
186 | for (var key in obj) {
|
187 | if (fn.call(context, obj[key], key, obj) === false) {
|
188 | break;
|
189 | }
|
190 | }
|
191 | };
|
192 |
|
193 | /**
|
194 | * Return a copy of `object` exclusing the given `keys`.
|
195 | *
|
196 | * ```js
|
197 | * <%= omit({a: 'a', b: 'b', c: 'c'}, ['a', 'c']) %>
|
198 | * //=> '{b: "b"}'
|
199 | * ```
|
200 | *
|
201 | * @param {Object} `object` Object with keys to omit.
|
202 | * @param {String} `keys` Keys to omit.
|
203 | * @return {Boolean}
|
204 | * @api public
|
205 | */
|
206 |
|
207 | exports.forOwn = function forOwn(obj, fn, context) {
|
208 | exports.forIn(obj, function(val, key) {
|
209 | if (hasOwn.call(obj, key)) {
|
210 | return fn.call(context, obj[key], key, obj);
|
211 | }
|
212 | });
|
213 | };
|
214 |
|
215 | /**
|
216 | * Extend `o` with properties of other `objects`.
|
217 | *
|
218 | * @param {Object} `o` The target object. Pass an empty object to shallow clone.
|
219 | * @param {Object} `objects`
|
220 | * @return {Object}
|
221 | * @api public
|
222 | */
|
223 |
|
224 | exports.extend = function extend(obj) {
|
225 | if (utils.typeOf(obj) !== 'object') { return ''; }
|
226 | var args = arguments;
|
227 | var len = args.length - 1;
|
228 |
|
229 | if (len === 0) {
|
230 | return obj;
|
231 | }
|
232 |
|
233 | for (var i = 0; i < len; i++) {
|
234 | var val = args[i + 1];
|
235 |
|
236 | if (utils.typeOf(val) === 'object') {
|
237 | for (var key in val) {
|
238 | if (exports.hasOwn(val, key)) {
|
239 | obj[key] = val[key];
|
240 | }
|
241 | }
|
242 | }
|
243 | }
|
244 | return obj;
|
245 | };
|
246 |
|
247 | /**
|
248 | * Recursively combine the properties of `o` with the
|
249 | * properties of other `objects`.
|
250 | *
|
251 | * @param {Object} `o` The target object. Pass an empty object to shallow clone.
|
252 | * @param {Object} `objects`
|
253 | * @return {Object}
|
254 | * @api public
|
255 | */
|
256 |
|
257 | exports.merge = function merge(obj) {
|
258 | if (utils.typeOf(obj) !== 'object') { return ''; }
|
259 | var args = arguments;
|
260 | var len = args.length - 1;
|
261 |
|
262 | if (len === 0) {
|
263 | return obj;
|
264 | }
|
265 |
|
266 | for (var i = 0; i < len; i++) {
|
267 | var val = args[i + 1];
|
268 |
|
269 | for (var key in val) {
|
270 | if (exports.hasOwn(val, key)) {
|
271 | if (utils.typeOf(val[key]) === 'object') {
|
272 | obj[key] = exports.merge(obj[key], val[key]);
|
273 | } else {
|
274 | obj[key] = val[key];
|
275 | }
|
276 | }
|
277 | }
|
278 | }
|
279 | return obj;
|
280 | };
|