Skip to content

Commit 1eaf12c

Browse files
committed
fix dynamodb-toolbox#68 with dependency graphs
1 parent da68f46 commit 1eaf12c

File tree

2 files changed

+67
-5
lines changed

2 files changed

+67
-5
lines changed

lib/normalizeData.js

Lines changed: 63 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,36 @@ module.exports = (DocumentClient) => (schema,linked,data,filter=false) => {
1414

1515
// Intialize validate type
1616
const validateType = validateTypes(DocumentClient)
17+
18+
// Build and execute defaults dependency graph
19+
const dependsOn = (map,attr) => {
20+
// If the default depends on other attributes
21+
if (schema[attr].dependsOn) {
22+
(Array.isArray(schema[attr].dependsOn) ? schema[attr].dependsOn : [schema[attr].dependsOn]).forEach(dependent => {
23+
// If the dependent is a valid attribute or alias
24+
if (schema[dependent]) {
25+
// If the dependent is a function
26+
if (typeof map[dependent] === 'function') {
27+
// Resolve the dependency graph
28+
map = dependsOn(map,dependent)
29+
}
30+
} else {
31+
error(`'${dependent}' is not a valid attribute or alias name`)
32+
}
33+
}) // end dependency loop
34+
35+
map[attr] = map[attr](map)
36+
return map
37+
} else {
38+
map[attr] = map[attr](map)
39+
if (schema[attr].alias) map[schema[attr].alias] = map[attr]
40+
if (schema[attr].map) map[schema[attr].map] = map[attr]
41+
return map
42+
}
43+
} // end dependsOn
1744

1845
// Generate normalized data object
1946
let dataMap = Object.keys(data).reduce((acc,field) => {
20-
2147
// Return a map with normalized data and alias references
2248
return Object.assign(acc,
2349
schema[field] ? {
@@ -27,17 +53,28 @@ module.exports = (DocumentClient) => (schema,linked,data,filter=false) => {
2753
: filter ? {} // this will filter out non-mapped fields
2854
: field === '$remove' ? { data: { ...acc.data, $remove: data[field] } } // support for removes
2955
: error(`Field '${field}' does not have a mapping or alias`)
30-
)
31-
56+
)
3257
},{ data: {}, aliases: {} })
3358

34-
59+
// Create a combined data object for defaults
60+
let defaultMap = { ...dataMap.data, ...dataMap.aliases }
61+
const defaults = Object.keys(defaultMap).reduce((acc,attr) => {
62+
// If a function, resolve the dependency graph
63+
if (typeof defaultMap[attr] === 'function') {
64+
let map = dependsOn(defaultMap,attr)
65+
defaultMap = map
66+
}
67+
return Object.assign(acc, { [attr]: defaultMap[attr] })
68+
},{})
69+
70+
3571
// Generate final data and evaluate function expressions
3672
let _data = Object.keys(dataMap.data).reduce((acc,field) => {
3773
return Object.assign(acc, {
38-
[field]: typeof dataMap.data[field] === 'function' ? dataMap.data[field]({ ...dataMap.data, ...dataMap.aliases }) : dataMap.data[field]
74+
[field]: defaults[field]
3975
})
4076
},{})
77+
4178

4279
// Process linked
4380
let composites = Object.keys(linked).reduce((acc,attr) => {
@@ -70,3 +107,24 @@ module.exports = (DocumentClient) => (schema,linked,data,filter=false) => {
70107
return Object.assign(composites,_data)
71108

72109
} // end normalizeData
110+
111+
112+
113+
114+
115+
// Generate final data and evaluate function expressions
116+
// let _data = Object.keys(dataMap.data).reduce((acc,field) => {
117+
// return Object.assign(acc, {
118+
// [field]: typeof dataMap.data[field] === 'function' ? dataMap.data[field](defaults) : dataMap.data[field]
119+
// })
120+
// },{})
121+
122+
// console.log(_data)
123+
124+
125+
126+
// map[schema[attr].dependsOn] = typeof map[schema[attr].dependsOn] === 'function' ?
127+
// dependsOn(map,schema[attr].dependsOn) // map[schema[attr].dependsOn](map)
128+
// : map[schema[attr].dependsOn]
129+
// return { map, val: map[attr](map) }
130+
// return dependsOn(map,attr)

lib/parseMapping.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@ module.exports = (field,config,track) => {
1717
case 'type':
1818
case 'default':
1919
break
20+
case 'dependsOn':
21+
if (typeof config[prop] !== 'string' && !Array.isArray(config[prop]))
22+
error(`'dependsOn' must be the string name of an attribute or alias`)
23+
break
2024
case 'transform':
2125
if (typeof config[prop] !== 'function') error(`'${prop}' must be a function`)
2226
break

0 commit comments

Comments
 (0)