forked from launchdarkly/integration-framework
-
Notifications
You must be signed in to change notification settings - Fork 0
/
preview.js
162 lines (144 loc) · 4.79 KB
/
preview.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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
const { readFileSync } = require('fs');
const Handlebars = require('handlebars');
const _ = require('lodash');
const { registerHelpers } = require('./helpers');
const jsonEscape = require('./utils/json-escape');
const testFileName = 'targeting-rule-update.json';
const flagUpdateContext = require(`./sample-context/flag/${testFileName}`);
// Update the context to have a more recent timestamp. This is important
// because some third-party services reject event payloads which are
// identified as having happened in the more distant past.
const now = new Date().getTime();
flagUpdateContext.timestamp.milliseconds = now;
flagUpdateContext.timestamp.seconds = Math.floor(now / 1000);
const args = process.argv;
const getFormVariableContext = formVariables => {
const endpointContext = {};
if (formVariables) {
formVariables.forEach(formVariable => {
const unsubstitutedKey = '$' + _.toUpper(formVariable.key);
switch (formVariable.type) {
case 'string':
endpointContext[formVariable.key] = unsubstitutedKey;
break;
case 'boolean':
endpointContext[formVariable.key] = true;
break;
case 'uri':
endpointContext[formVariable.key] = unsubstitutedKey;
break;
case 'enum':
endpointContext[formVariable.key] = unsubstitutedKey;
break;
case 'dynamicEnum':
endpointContext[formVariable.key] = unsubstitutedKey;
break;
}
});
}
return endpointContext;
};
const getOAuthContext = requiresOAuth => {
if (requiresOAuth) {
const oauthContext = {
baseURI: '$OAUTH_BASE_URI',
accessToken: '$OAUTH_ACCESS_TOKEN',
};
return oauthContext;
}
return null;
};
registerHelpers();
const curl = _.includes(args, '--curl');
const integrationNameIndex = curl ? 3 : 2;
if (args.length <= integrationNameIndex) {
console.log('Provide an integration directory name:');
console.log(' npm run preview <INTEGRATION_NAME>');
console.log(' npm run curl <INTEGRATION_NAME>\n');
process.exit(1);
}
const integrationName = args[integrationNameIndex];
let manifest;
try {
manifest = require(`./integrations/${integrationName}/manifest.json`);
} catch (e) {
console.log(
`The "${integrationName}" integration does not exist. This value should be your integration directory name.\n`
);
process.exit(1);
}
const formVariables = _.get(manifest, 'formVariables', null);
const endpoint = _.get(
manifest,
'capabilities.auditLogEventsHook.endpoint',
null
);
const requiresOAuth = _.get(manifest, 'requiresOAuth', null);
if (endpoint) {
const endpointContext = getFormVariableContext(formVariables);
endpointContext.oauth = getOAuthContext(requiresOAuth);
endpointContext.context = flagUpdateContext;
const urlTemplate = Handlebars.compile(endpoint.url, {
strict: true,
});
const flagTemplatePath = _.get(
manifest,
'capabilities.auditLogEventsHook.templates.flag',
null
);
const defaultTemplatePath = _.get(
manifest,
'capabilities.auditLogEventsHook.templates.default',
null
);
if (!(flagTemplatePath || defaultTemplatePath)) {
console.log('Could not find a flag/default template in manifest');
process.exit(1);
}
const path = `./integrations/${integrationName}/${
flagTemplatePath || defaultTemplatePath
}`;
const headers = endpoint.headers.map(header => {
const headerTemplate = Handlebars.compile(header.value, {
strict: true,
});
return {
name: header.name,
value: headerTemplate(endpointContext),
};
});
const fullContext = jsonEscape(Object.assign({}, flagUpdateContext));
fullContext.formVariables = getFormVariableContext(formVariables);
const templateString = readFileSync(path, { encoding: 'utf-8' });
const flagTemplate = Handlebars.compile(templateString, { strict: true });
const body = flagTemplate(fullContext);
if (curl) {
let command =
`curl -X ${endpoint.method} \\\n` +
` ${urlTemplate(endpointContext)} \\\n`;
headers.forEach(header => {
command += ` -H '${header.name}: ${header.value}' \\\n`;
});
command += ` -d '${_.trimEnd(body)}'`;
console.log(
'Before running the following curl command, be sure to replace all variables denoted with $.'
);
console.log(
`The following command was generated with the test file ${testFileName}.\n`
);
console.log(command);
} else {
console.log('URL: ', urlTemplate(endpointContext));
console.log('METHOD:', endpoint.method);
headers.forEach(header => {
console.log(`HEADER: ${header.name}: ${header.value}`);
});
console.log(`BODY:\t${testFileName}`);
console.log(body);
}
} else {
console.log(
`The "${integrationName}" integration does not make any outbound requests from LaunchDarkly.\n`
);
process.exit(0);
}