@@ -42,7 +42,47 @@ function deepAssign(target, ...sources) {
4242 return target
4343}
4444
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 ) } ` )
4686 const { log } = require ( './log' )
4787 const promises = Object . entries ( obj ) . map ( ( [ key , value ] ) => {
4888 const isFn = ! key . startsWith ( '_' )
@@ -51,7 +91,9 @@ async function keysAsFunctions(obj, map) {
5191
5292 if ( ! fn && isFn ) log . info (
5393 `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 ) } `
5597 )
5698 return fn && value ? fn ( value ) : value
5799 } )
@@ -63,5 +105,6 @@ module.exports = {
63105 isObject,
64106 deepAssign,
65107 keysAsFunctions,
108+ keysAsFunctionsRecursive,
66109 ...require ( './log' )
67110}
0 commit comments