1 | var mapping = require('./_mapping'),
|
2 | mutateMap = mapping.mutate,
|
3 | fallbackHolder = require('./placeholder');
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 | function baseArity(func, n) {
|
15 | return n == 2
|
16 | ? function(a, b) { return func.apply(undefined, arguments); }
|
17 | : function(a) { return func.apply(undefined, arguments); };
|
18 | }
|
19 |
|
20 |
|
21 |
|
22 |
|
23 |
|
24 |
|
25 |
|
26 |
|
27 |
|
28 |
|
29 | function baseAry(func, n) {
|
30 | return n == 2
|
31 | ? function(a, b) { return func(a, b); }
|
32 | : function(a) { return func(a); };
|
33 | }
|
34 |
|
35 |
|
36 |
|
37 |
|
38 |
|
39 |
|
40 |
|
41 |
|
42 | function cloneArray(array) {
|
43 | var length = array ? array.length : 0,
|
44 | result = Array(length);
|
45 |
|
46 | while (length--) {
|
47 | result[length] = array[length];
|
48 | }
|
49 | return result;
|
50 | }
|
51 |
|
52 |
|
53 |
|
54 |
|
55 |
|
56 |
|
57 |
|
58 |
|
59 | function createCloner(func) {
|
60 | return function(object) {
|
61 | return func({}, object);
|
62 | };
|
63 | }
|
64 |
|
65 |
|
66 |
|
67 |
|
68 |
|
69 |
|
70 |
|
71 |
|
72 |
|
73 |
|
74 | function immutWrap(func, cloner) {
|
75 | return function() {
|
76 | var length = arguments.length;
|
77 | if (!length) {
|
78 | return result;
|
79 | }
|
80 | var args = Array(length);
|
81 | while (length--) {
|
82 | args[length] = arguments[length];
|
83 | }
|
84 | var result = args[0] = cloner.apply(undefined, args);
|
85 | func.apply(undefined, args);
|
86 | return result;
|
87 | };
|
88 | }
|
89 |
|
90 |
|
91 |
|
92 |
|
93 |
|
94 |
|
95 |
|
96 |
|
97 |
|
98 |
|
99 |
|
100 |
|
101 |
|
102 |
|
103 |
|
104 |
|
105 | function baseConvert(util, name, func, options) {
|
106 | var setPlaceholder,
|
107 | isLib = typeof name == 'function',
|
108 | isObj = name === Object(name);
|
109 |
|
110 | if (isObj) {
|
111 | options = func;
|
112 | func = name;
|
113 | name = undefined;
|
114 | }
|
115 | if (func == null) {
|
116 | throw new TypeError;
|
117 | }
|
118 | options || (options = {});
|
119 |
|
120 | var config = {
|
121 | 'cap': 'cap' in options ? options.cap : true,
|
122 | 'curry': 'curry' in options ? options.curry : true,
|
123 | 'fixed': 'fixed' in options ? options.fixed : true,
|
124 | 'immutable': 'immutable' in options ? options.immutable : true,
|
125 | 'rearg': 'rearg' in options ? options.rearg : true
|
126 | };
|
127 |
|
128 | var forceCurry = ('curry' in options) && options.curry,
|
129 | forceFixed = ('fixed' in options) && options.fixed,
|
130 | forceRearg = ('rearg' in options) && options.rearg,
|
131 | placeholder = isLib ? func : fallbackHolder,
|
132 | pristine = isLib ? func.runInContext() : undefined;
|
133 |
|
134 | var helpers = isLib ? func : {
|
135 | 'ary': util.ary,
|
136 | 'assign': util.assign,
|
137 | 'clone': util.clone,
|
138 | 'curry': util.curry,
|
139 | 'forEach': util.forEach,
|
140 | 'isArray': util.isArray,
|
141 | 'isFunction': util.isFunction,
|
142 | 'iteratee': util.iteratee,
|
143 | 'keys': util.keys,
|
144 | 'rearg': util.rearg,
|
145 | 'spread': util.spread,
|
146 | 'toPath': util.toPath
|
147 | };
|
148 |
|
149 | var ary = helpers.ary,
|
150 | assign = helpers.assign,
|
151 | clone = helpers.clone,
|
152 | curry = helpers.curry,
|
153 | each = helpers.forEach,
|
154 | isArray = helpers.isArray,
|
155 | isFunction = helpers.isFunction,
|
156 | keys = helpers.keys,
|
157 | rearg = helpers.rearg,
|
158 | spread = helpers.spread,
|
159 | toPath = helpers.toPath;
|
160 |
|
161 | var aryMethodKeys = keys(mapping.aryMethod);
|
162 |
|
163 | var wrappers = {
|
164 | 'castArray': function(castArray) {
|
165 | return function() {
|
166 | var value = arguments[0];
|
167 | return isArray(value)
|
168 | ? castArray(cloneArray(value))
|
169 | : castArray.apply(undefined, arguments);
|
170 | };
|
171 | },
|
172 | 'iteratee': function(iteratee) {
|
173 | return function() {
|
174 | var func = arguments[0],
|
175 | arity = arguments[1],
|
176 | result = iteratee(func, arity),
|
177 | length = result.length;
|
178 |
|
179 | if (config.cap && typeof arity == 'number') {
|
180 | arity = arity > 2 ? (arity - 2) : 1;
|
181 | return (length && length <= arity) ? result : baseAry(result, arity);
|
182 | }
|
183 | return result;
|
184 | };
|
185 | },
|
186 | 'mixin': function(mixin) {
|
187 | return function(source) {
|
188 | var func = this;
|
189 | if (!isFunction(func)) {
|
190 | return mixin(func, Object(source));
|
191 | }
|
192 | var methods = [],
|
193 | methodNames = [];
|
194 |
|
195 | each(keys(source), function(key) {
|
196 | var value = source[key];
|
197 | if (isFunction(value)) {
|
198 | methodNames.push(key);
|
199 | methods.push(func.prototype[key]);
|
200 | }
|
201 | });
|
202 |
|
203 | mixin(func, Object(source));
|
204 |
|
205 | each(methodNames, function(methodName, index) {
|
206 | var method = methods[index];
|
207 | if (isFunction(method)) {
|
208 | func.prototype[methodName] = method;
|
209 | } else {
|
210 | delete func.prototype[methodName];
|
211 | }
|
212 | });
|
213 | return func;
|
214 | };
|
215 | },
|
216 | 'runInContext': function(runInContext) {
|
217 | return function(context) {
|
218 | return baseConvert(util, runInContext(context), options);
|
219 | };
|
220 | }
|
221 | };
|
222 |
|
223 |
|
224 |
|
225 | |
226 |
|
227 |
|
228 |
|
229 |
|
230 |
|
231 |
|
232 |
|
233 | function cloneByPath(object, path) {
|
234 | path = toPath(path);
|
235 |
|
236 | var index = -1,
|
237 | length = path.length,
|
238 | result = clone(Object(object)),
|
239 | nested = result;
|
240 |
|
241 | while (nested != null && ++index < length) {
|
242 | var key = path[index],
|
243 | value = nested[key];
|
244 |
|
245 | if (value != null) {
|
246 | nested[key] = clone(Object(value));
|
247 | }
|
248 | nested = nested[key];
|
249 | }
|
250 | return result;
|
251 | }
|
252 |
|
253 | |
254 |
|
255 |
|
256 |
|
257 |
|
258 |
|
259 |
|
260 | function convertLib(options) {
|
261 | return _.runInContext.convert(options)(undefined);
|
262 | }
|
263 |
|
264 | |
265 |
|
266 |
|
267 |
|
268 |
|
269 |
|
270 |
|
271 | function createConverter(name, func) {
|
272 | var oldOptions = options;
|
273 | return function(options) {
|
274 | var newUtil = isLib ? pristine : helpers,
|
275 | newFunc = isLib ? pristine[name] : func,
|
276 | newOptions = assign(assign({}, oldOptions), options);
|
277 |
|
278 | return baseConvert(newUtil, name, newFunc, newOptions);
|
279 | };
|
280 | }
|
281 |
|
282 | |
283 |
|
284 |
|
285 |
|
286 |
|
287 |
|
288 |
|
289 |
|
290 |
|
291 | function iterateeAry(func, n) {
|
292 | return overArg(func, function(func) {
|
293 | return typeof func == 'function' ? baseAry(func, n) : func;
|
294 | });
|
295 | }
|
296 |
|
297 | |
298 |
|
299 |
|
300 |
|
301 |
|
302 |
|
303 |
|
304 |
|
305 |
|
306 |
|
307 |
|
308 | function iterateeRearg(func, indexes) {
|
309 | return overArg(func, function(func) {
|
310 | var n = indexes.length;
|
311 | return baseArity(rearg(baseAry(func, n), indexes), n);
|
312 | });
|
313 | }
|
314 |
|
315 | |
316 |
|
317 |
|
318 |
|
319 |
|
320 |
|
321 |
|
322 |
|
323 |
|
324 | function overArg(func, transform) {
|
325 | return function() {
|
326 | var length = arguments.length;
|
327 | if (!length) {
|
328 | return func();
|
329 | }
|
330 | var args = Array(length);
|
331 | while (length--) {
|
332 | args[length] = arguments[length];
|
333 | }
|
334 | var index = config.rearg ? 0 : (length - 1);
|
335 | args[index] = transform(args[index]);
|
336 | return func.apply(undefined, args);
|
337 | };
|
338 | }
|
339 |
|
340 | |
341 |
|
342 |
|
343 |
|
344 |
|
345 |
|
346 |
|
347 |
|
348 |
|
349 | function wrap(name, func) {
|
350 | name = mapping.aliasToReal[name] || name;
|
351 |
|
352 | var result,
|
353 | wrapped = func,
|
354 | wrapper = wrappers[name];
|
355 |
|
356 | if (wrapper) {
|
357 | wrapped = wrapper(func);
|
358 | }
|
359 | else if (config.immutable) {
|
360 | if (mutateMap.array[name]) {
|
361 | wrapped = immutWrap(func, cloneArray);
|
362 | }
|
363 | else if (mutateMap.object[name]) {
|
364 | wrapped = immutWrap(func, createCloner(func));
|
365 | }
|
366 | else if (mutateMap.set[name]) {
|
367 | wrapped = immutWrap(func, cloneByPath);
|
368 | }
|
369 | }
|
370 | each(aryMethodKeys, function(aryKey) {
|
371 | each(mapping.aryMethod[aryKey], function(otherName) {
|
372 | if (name == otherName) {
|
373 | var aryN = !isLib && mapping.iterateeAry[name],
|
374 | reargIndexes = mapping.iterateeRearg[name],
|
375 | spreadStart = mapping.methodSpread[name];
|
376 |
|
377 | result = wrapped;
|
378 | if (config.fixed && (forceFixed || !mapping.skipFixed[name])) {
|
379 | result = spreadStart === undefined
|
380 | ? ary(result, aryKey)
|
381 | : spread(result, spreadStart);
|
382 | }
|
383 | if (config.rearg && aryKey > 1 && (forceRearg || !mapping.skipRearg[name])) {
|
384 | result = rearg(result, mapping.methodRearg[name] || mapping.aryRearg[aryKey]);
|
385 | }
|
386 | if (config.cap) {
|
387 | if (reargIndexes) {
|
388 | result = iterateeRearg(result, reargIndexes);
|
389 | } else if (aryN) {
|
390 | result = iterateeAry(result, aryN);
|
391 | }
|
392 | }
|
393 | if (forceCurry || (config.curry && aryKey > 1)) {
|
394 | forceCurry && console.log(forceCurry, name);
|
395 | result = curry(result, aryKey);
|
396 | }
|
397 | return false;
|
398 | }
|
399 | });
|
400 | return !result;
|
401 | });
|
402 |
|
403 | result || (result = wrapped);
|
404 | if (result == func) {
|
405 | result = forceCurry ? curry(result, 1) : function() {
|
406 | return func.apply(this, arguments);
|
407 | };
|
408 | }
|
409 | result.convert = createConverter(name, func);
|
410 | if (mapping.placeholder[name]) {
|
411 | setPlaceholder = true;
|
412 | result.placeholder = func.placeholder = placeholder;
|
413 | }
|
414 | return result;
|
415 | }
|
416 |
|
417 |
|
418 |
|
419 | if (!isObj) {
|
420 | return wrap(name, func);
|
421 | }
|
422 | var _ = func;
|
423 |
|
424 |
|
425 | var pairs = [];
|
426 | each(aryMethodKeys, function(aryKey) {
|
427 | each(mapping.aryMethod[aryKey], function(key) {
|
428 | var func = _[mapping.remap[key] || key];
|
429 | if (func) {
|
430 | pairs.push([key, wrap(key, func)]);
|
431 | }
|
432 | });
|
433 | });
|
434 |
|
435 |
|
436 | each(keys(_), function(key) {
|
437 | var func = _[key];
|
438 | if (typeof func == 'function') {
|
439 | var length = pairs.length;
|
440 | while (length--) {
|
441 | if (pairs[length][0] == key) {
|
442 | return;
|
443 | }
|
444 | }
|
445 | func.convert = createConverter(key, func);
|
446 | pairs.push([key, func]);
|
447 | }
|
448 | });
|
449 |
|
450 |
|
451 | each(pairs, function(pair) {
|
452 | _[pair[0]] = pair[1];
|
453 | });
|
454 |
|
455 | _.convert = convertLib;
|
456 | if (setPlaceholder) {
|
457 | _.placeholder = placeholder;
|
458 | }
|
459 |
|
460 | each(keys(_), function(key) {
|
461 | each(mapping.realToAlias[key] || [], function(alias) {
|
462 | _[alias] = _[key];
|
463 | });
|
464 | });
|
465 |
|
466 | return _;
|
467 | }
|
468 |
|
469 | module.exports = baseConvert;
|