|
1 | 1 | 'use strict'; |
2 | | -var _ = require('lodash'); |
| 2 | +var _ = require('lodash') |
| 3 | + , pointer = require('json-pointer'); |
| 4 | + |
| 5 | +var excludeList = [ |
| 6 | + '/substitution_data', |
| 7 | + '/tags', |
| 8 | + '/metadata', |
| 9 | + '/attributes', |
| 10 | + '/headers', |
| 11 | + '/content/email_rfc822' |
| 12 | +]; |
| 13 | + |
| 14 | +function snakedKeyClone(source) { |
| 15 | + |
| 16 | + if (!_.isObject(source)) { |
| 17 | + return source; |
| 18 | + } |
| 19 | + |
| 20 | + var target = {}; |
| 21 | + |
| 22 | + if (Array.isArray(source)) { |
| 23 | + target = []; |
| 24 | + for (var i = 0; i < source.length; i++) { |
| 25 | + target.push(snakedKeyClone(source[i])); |
| 26 | + } |
| 27 | + return target; |
| 28 | + } |
| 29 | + |
| 30 | + Object.keys(source).forEach(function(key) { |
| 31 | + target[_.snakeCase(key)] = snakedKeyClone(source[key]); |
| 32 | + }); |
| 33 | + |
| 34 | + return target; |
| 35 | +} |
3 | 36 |
|
4 | 37 | module.exports = function toApiFormat(source) { |
5 | 38 |
|
6 | | - var dest = {}; |
7 | | - // List of property names which we do not want to modify the sub-property names |
8 | | - var excludeList = ['substitution_data', 'tags', 'metadata', 'attributes', 'headers']; |
9 | | - |
10 | | - try{ |
11 | | - // Handle arrays (Only need to handle arrays of objects for our use case.) |
12 | | - if(Array.isArray(source) && _.isPlainObject(source[0])) { |
13 | | - dest = []; |
14 | | - for(var i = 0; i < source.length; i++) { |
15 | | - dest.push(toApiFormat(source[i])); |
16 | | - } |
17 | | - return dest; |
| 39 | + var excludedObjects = {}; |
| 40 | + |
| 41 | + // Look in the source object for the excluded pointers and take a copy of the |
| 42 | + // objects pointed to by those keys. Then remove them from the source object. |
| 43 | + excludeList.forEach(function(exclusionPointer) { |
| 44 | + if (pointer.has(source, exclusionPointer)) { |
| 45 | + pointer.set(excludedObjects, exclusionPointer, pointer.get(source, exclusionPointer)); |
| 46 | + pointer.remove(source, exclusionPointer); |
18 | 47 | } |
| 48 | + }); |
19 | 49 |
|
20 | | - // Handle objects |
21 | | - Object.keys(source).forEach(function(key) { |
22 | | - |
23 | | - // Cache snake_cased keys |
24 | | - var snakedKey = _.snakeCase(key); |
25 | | - |
26 | | - // Exclude appropriately |
27 | | - if( -1 === excludeList.indexOf(key)) { |
28 | | - dest[snakedKey] = source[key]; |
29 | | - if( _.isObject (source[key] ) ) { |
30 | | - dest[snakedKey] = toApiFormat(source[key]); |
31 | | - } |
32 | | - } else { |
33 | | - dest[snakedKey] = source[key]; |
34 | | - } |
35 | | - }); |
36 | | - } catch(e) { |
37 | | - // Errors |
38 | | - return e; |
39 | | - } |
40 | | - // No errors return results |
41 | | - return dest; |
| 50 | + // Make a clone of the remaining source object but with snaked case keys |
| 51 | + var target = snakedKeyClone(source); |
| 52 | + |
| 53 | + // Reinstated the un-modified objects into the target |
| 54 | + pointer.walk(excludedObjects, function(val, ptr) { |
| 55 | + pointer.set(target, ptr, val); |
| 56 | + }); |
| 57 | + |
| 58 | + return target; |
42 | 59 | }; |
0 commit comments