-
Notifications
You must be signed in to change notification settings - Fork 1
/
cloudFormationProcessor.js
79 lines (67 loc) · 1.99 KB
/
cloudFormationProcessor.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
/**
* This module provides tools to traverse a given object and apply transformations
* to the object using a cloud formation like syntax. We're not trying to replace
* all CF functionality just what is needed to run the appsync emulator.
*/
const DynamoDBTable = 'AWS::DynamoDB::Table';
function lookupResourcesFromCtx(resource, ctx) {
return ctx.resources && ctx.resources.Resources[resource];
}
function lookupResourcePropertyFromCtx(cfObject, prop) {
return cfObject && cfObject.Properties && cfObject.Properties[prop];
}
function cfRef(value, ctx) {
const cfObject = lookupResourcesFromCtx(value, ctx);
if (!cfObject) {
return false;
}
const { Type: type } = cfObject;
if (!type) {
return false;
}
switch (type) {
case DynamoDBTable:
return lookupResourcePropertyFromCtx(cfObject, 'TableName');
default:
return false;
}
}
const cloudFormationHandlers = {
Ref: cfRef,
};
function processObject(object, ctx, objectPath = []) {
if (!object || typeof object !== 'object') {
return object;
}
if (Array.isArray(object)) {
return object.map((value, idx) =>
processObject(value, ctx, [...objectPath, idx]),
);
}
const entries = Object.entries(object);
return entries.reduce((sum, [key, value]) => {
const newObjectPath = [...objectPath, key];
if (entries.length === 1 && cloudFormationHandlers[key]) {
const resolvedResource = processObject(
cloudFormationHandlers[key](value, ctx),
ctx,
newObjectPath,
);
if (resolvedResource !== false) {
return resolvedResource;
}
}
return {
...sum,
[key]: processObject(value, ctx, newObjectPath),
};
}, {});
}
function cloudFormationProcessor(input) {
const config = { ...input };
const ctx = { resources: config.resources };
// remove useless serverless object so we do not traverse functions.
delete config.serverless;
return processObject(config, ctx);
}
module.exports = { cloudFormationProcessor };