@@ -42,7 +42,47 @@ function deepAssign(target, ...sources) {
42
42
return target
43
43
}
44
44
45
- async function keysAsFunctions ( obj , map ) {
45
+ async function keysAsFunctionsRecursive ( obj , suffix = '$map' ) {
46
+ const maps = [ ]
47
+
48
+ // process all descendants' maps first
49
+ const children = Object . entries ( obj ) . map ( ( [ key , value ] ) => {
50
+ if ( isObject ( value ) ) {
51
+ if ( key . endsWith ( suffix ) )
52
+ maps . push ( { key, value } )
53
+ else
54
+ return keysAsFunctionsRecursive ( value , suffix )
55
+ }
56
+ } )
57
+ await Promise . all ( children )
58
+
59
+ // process own maps
60
+ const ownMaps = await Promise . all ( maps . map ( async ( { key, value } ) => {
61
+ delete obj [ key ]
62
+ key = key . substr ( 0 , key . length - suffix . length )
63
+ const result = await keysAsFunctions ( obj [ key ] , value , key )
64
+ return {
65
+ key,
66
+ result
67
+ }
68
+ } ) )
69
+ ownMaps . forEach ( thing => obj [ thing . key ] = thing . result )
70
+
71
+ return obj
72
+ }
73
+
74
+ /**
75
+ * converts objects to arrays
76
+ * each field value is parsed through a function from the map which corresponds to the field's key
77
+ * map = { aPlugin: val => val + 'bar' }
78
+ * obj = { aPlugin: 'foo', _n: 123 }
79
+ * keysAsFunctions(obj, map) // ['foobar', 123]
80
+ * @param {object } obj
81
+ * @param {Object.<string, function> } map
82
+ */
83
+ async function keysAsFunctions ( obj , map , name ) {
84
+ if ( ! isObject ( obj ) )
85
+ throw new Error ( `expected an object for "${ name } ", but got ${ JSON . stringify ( obj , null , 2 ) } ` )
46
86
const { log } = require ( './log' )
47
87
const promises = Object . entries ( obj ) . map ( ( [ key , value ] ) => {
48
88
const isFn = ! key . startsWith ( '_' )
@@ -51,7 +91,9 @@ async function keysAsFunctions(obj, map) {
51
91
52
92
if ( ! fn && isFn ) log . info (
53
93
`there's no map method named ${ key } . Available methods: ${ Object . keys ( map ) } .` +
54
- `\nRenaming to "_${ key } " will hide this message.`
94
+ `\nRenaming to "_${ key } " will hide this message.` +
95
+ `\nvalue: ${ JSON . stringify ( value , null , 2 ) } ` +
96
+ `\nobj: ${ JSON . stringify ( obj , null , 2 ) } `
55
97
)
56
98
return fn && value ? fn ( value ) : value
57
99
} )
@@ -63,5 +105,6 @@ module.exports = {
63
105
isObject,
64
106
deepAssign,
65
107
keysAsFunctions,
108
+ keysAsFunctionsRecursive,
66
109
...require ( './log' )
67
110
}
0 commit comments