@digitraffic/common 2022.10.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (199) hide show
  1. package/LICENSE +291 -0
  2. package/aws/infra/api/integration.d.ts +21 -0
  3. package/aws/infra/api/integration.js +52 -0
  4. package/aws/infra/api/response.d.ts +22 -0
  5. package/aws/infra/api/response.js +61 -0
  6. package/aws/infra/api/responses.d.ts +39 -0
  7. package/aws/infra/api/responses.js +79 -0
  8. package/aws/infra/api/static-integration.d.ts +15 -0
  9. package/aws/infra/api/static-integration.js +54 -0
  10. package/aws/infra/canaries/canary-alarm.d.ts +6 -0
  11. package/aws/infra/canaries/canary-alarm.js +26 -0
  12. package/aws/infra/canaries/canary-parameters.d.ts +18 -0
  13. package/aws/infra/canaries/canary-parameters.js +3 -0
  14. package/aws/infra/canaries/canary-role.d.ts +6 -0
  15. package/aws/infra/canaries/canary-role.js +46 -0
  16. package/aws/infra/canaries/canary.d.ts +8 -0
  17. package/aws/infra/canaries/canary.js +29 -0
  18. package/aws/infra/canaries/database-canary.d.ts +18 -0
  19. package/aws/infra/canaries/database-canary.js +55 -0
  20. package/aws/infra/canaries/database-checker.d.ts +21 -0
  21. package/aws/infra/canaries/database-checker.js +109 -0
  22. package/aws/infra/canaries/url-canary.d.ts +19 -0
  23. package/aws/infra/canaries/url-canary.js +46 -0
  24. package/aws/infra/canaries/url-checker.d.ts +46 -0
  25. package/aws/infra/canaries/url-checker.js +238 -0
  26. package/aws/infra/documentation.d.ts +56 -0
  27. package/aws/infra/documentation.js +95 -0
  28. package/aws/infra/scheduler.d.ts +12 -0
  29. package/aws/infra/scheduler.js +31 -0
  30. package/aws/infra/security-rule.d.ts +12 -0
  31. package/aws/infra/security-rule.js +39 -0
  32. package/aws/infra/sqs-integration.d.ts +7 -0
  33. package/aws/infra/sqs-integration.js +93 -0
  34. package/aws/infra/sqs-queue.d.ts +16 -0
  35. package/aws/infra/sqs-queue.js +130 -0
  36. package/aws/infra/stack/lambda-configs.d.ts +72 -0
  37. package/aws/infra/stack/lambda-configs.js +93 -0
  38. package/aws/infra/stack/monitoredfunction.d.ts +84 -0
  39. package/aws/infra/stack/monitoredfunction.js +135 -0
  40. package/aws/infra/stack/rest_apis.d.ts +40 -0
  41. package/aws/infra/stack/rest_apis.js +179 -0
  42. package/aws/infra/stack/stack-checking-aspect.d.ts +20 -0
  43. package/aws/infra/stack/stack-checking-aspect.js +163 -0
  44. package/aws/infra/stack/stack.d.ts +41 -0
  45. package/aws/infra/stack/stack.js +58 -0
  46. package/aws/infra/stack/subscription.d.ts +17 -0
  47. package/aws/infra/stack/subscription.js +41 -0
  48. package/aws/infra/usage-plans.d.ts +15 -0
  49. package/aws/infra/usage-plans.js +42 -0
  50. package/aws/runtime/apikey.d.ts +2 -0
  51. package/aws/runtime/apikey.js +13 -0
  52. package/aws/runtime/digitraffic-integration-response.d.ts +8 -0
  53. package/aws/runtime/digitraffic-integration-response.js +26 -0
  54. package/aws/runtime/messaging.d.ts +10 -0
  55. package/aws/runtime/messaging.js +31 -0
  56. package/aws/runtime/s3.d.ts +2 -0
  57. package/aws/runtime/s3.js +30 -0
  58. package/aws/runtime/secrets/dbsecret.d.ts +54 -0
  59. package/aws/runtime/secrets/dbsecret.js +96 -0
  60. package/aws/runtime/secrets/proxy-holder.d.ts +9 -0
  61. package/aws/runtime/secrets/proxy-holder.js +26 -0
  62. package/aws/runtime/secrets/rds-holder.d.ts +9 -0
  63. package/aws/runtime/secrets/rds-holder.js +26 -0
  64. package/aws/runtime/secrets/secret-holder.d.ts +26 -0
  65. package/aws/runtime/secrets/secret-holder.js +73 -0
  66. package/aws/runtime/secrets/secret.d.ts +8 -0
  67. package/aws/runtime/secrets/secret.js +43 -0
  68. package/aws/types/errors.d.ts +4 -0
  69. package/aws/types/errors.js +9 -0
  70. package/aws/types/lambda-response.d.ts +12 -0
  71. package/aws/types/lambda-response.js +28 -0
  72. package/aws/types/mediatypes.d.ts +10 -0
  73. package/aws/types/mediatypes.js +15 -0
  74. package/aws/types/model-with-reference.d.ts +7 -0
  75. package/aws/types/model-with-reference.js +3 -0
  76. package/aws/types/proxytypes.d.ts +26 -0
  77. package/aws/types/proxytypes.js +3 -0
  78. package/aws/types/tags.d.ts +2 -0
  79. package/aws/types/tags.js +7 -0
  80. package/database/cached.d.ts +7 -0
  81. package/database/cached.js +32 -0
  82. package/database/database.d.ts +19 -0
  83. package/database/database.js +62 -0
  84. package/database/last-updated.d.ts +16 -0
  85. package/database/last-updated.js +54 -0
  86. package/index.d.ts +1 -0
  87. package/index.js +18 -0
  88. package/marine/id_utils.d.ts +3 -0
  89. package/marine/id_utils.js +33 -0
  90. package/marine/rtz.d.ts +48 -0
  91. package/marine/rtz.js +3 -0
  92. package/package.json +55 -0
  93. package/src/aws/infra/api/integration.js +52 -0
  94. package/src/aws/infra/api/response.js +61 -0
  95. package/src/aws/infra/api/responses.js +79 -0
  96. package/src/aws/infra/api/static-integration.js +54 -0
  97. package/src/aws/infra/canaries/canary-alarm.js +26 -0
  98. package/src/aws/infra/canaries/canary-parameters.js +3 -0
  99. package/src/aws/infra/canaries/canary-role.js +46 -0
  100. package/src/aws/infra/canaries/canary.js +29 -0
  101. package/src/aws/infra/canaries/database-canary.js +55 -0
  102. package/src/aws/infra/canaries/database-checker.js +109 -0
  103. package/src/aws/infra/canaries/url-canary.js +46 -0
  104. package/src/aws/infra/canaries/url-checker.js +238 -0
  105. package/src/aws/infra/documentation.js +95 -0
  106. package/src/aws/infra/scheduler.js +31 -0
  107. package/src/aws/infra/security-rule.js +39 -0
  108. package/src/aws/infra/sqs-integration.js +93 -0
  109. package/src/aws/infra/sqs-queue.js +130 -0
  110. package/src/aws/infra/stack/lambda-configs.js +93 -0
  111. package/src/aws/infra/stack/monitoredfunction.js +135 -0
  112. package/src/aws/infra/stack/rest_apis.js +179 -0
  113. package/src/aws/infra/stack/stack-checking-aspect.js +163 -0
  114. package/src/aws/infra/stack/stack.js +58 -0
  115. package/src/aws/infra/stack/subscription.js +41 -0
  116. package/src/aws/infra/usage-plans.js +42 -0
  117. package/src/aws/runtime/apikey.js +13 -0
  118. package/src/aws/runtime/digitraffic-integration-response.js +26 -0
  119. package/src/aws/runtime/messaging.js +31 -0
  120. package/src/aws/runtime/s3.js +30 -0
  121. package/src/aws/runtime/secrets/dbsecret.js +96 -0
  122. package/src/aws/runtime/secrets/proxy-holder.js +26 -0
  123. package/src/aws/runtime/secrets/rds-holder.js +26 -0
  124. package/src/aws/runtime/secrets/secret-holder.js +73 -0
  125. package/src/aws/runtime/secrets/secret.js +43 -0
  126. package/src/aws/types/errors.js +9 -0
  127. package/src/aws/types/lambda-response.js +28 -0
  128. package/src/aws/types/mediatypes.js +15 -0
  129. package/src/aws/types/model-with-reference.js +3 -0
  130. package/src/aws/types/proxytypes.js +3 -0
  131. package/src/aws/types/tags.js +7 -0
  132. package/src/database/cached.js +32 -0
  133. package/src/database/database.js +62 -0
  134. package/src/database/last-updated.js +54 -0
  135. package/src/marine/id_utils.js +33 -0
  136. package/src/marine/rtz.js +3 -0
  137. package/src/test/asserter.js +45 -0
  138. package/src/test/db-testutils.js +31 -0
  139. package/src/test/httpserver.js +67 -0
  140. package/src/test/secret.js +25 -0
  141. package/src/test/secrets-manager.js +59 -0
  142. package/src/test/testutils.js +44 -0
  143. package/src/types/input-error.js +7 -0
  144. package/src/types/language.js +10 -0
  145. package/src/types/traffictype.js +13 -0
  146. package/src/types/validator.js +14 -0
  147. package/src/utils/api-model.js +129 -0
  148. package/src/utils/base64.js +21 -0
  149. package/src/utils/date-utils.js +34 -0
  150. package/src/utils/geojson-types.js +18 -0
  151. package/src/utils/geometry.js +140 -0
  152. package/src/utils/retry.js +50 -0
  153. package/src/utils/slack.js +25 -0
  154. package/src/utils/utils.js +40 -0
  155. package/test/asserter.d.ts +11 -0
  156. package/test/asserter.js +45 -0
  157. package/test/db-testutils.d.ts +2 -0
  158. package/test/db-testutils.js +31 -0
  159. package/test/httpserver.d.ts +18 -0
  160. package/test/httpserver.js +67 -0
  161. package/test/marine/id_utils.test.js +69 -0
  162. package/test/promise/promise.test.js +125 -0
  163. package/test/secret.d.ts +3 -0
  164. package/test/secret.js +25 -0
  165. package/test/secrets/dbsecret.test.js +71 -0
  166. package/test/secrets/secret-holder.test.js +124 -0
  167. package/test/secrets/secret.test.js +66 -0
  168. package/test/secrets-manager.d.ts +9 -0
  169. package/test/secrets-manager.js +59 -0
  170. package/test/test/httpserver.test.js +87 -0
  171. package/test/testutils.d.ts +12 -0
  172. package/test/testutils.js +44 -0
  173. package/test/utils/date-utils.test.js +51 -0
  174. package/test/utils/geometry.test.js +49 -0
  175. package/test/utils/utils.test.js +49 -0
  176. package/types/input-error.d.ts +2 -0
  177. package/types/input-error.js +7 -0
  178. package/types/language.d.ts +5 -0
  179. package/types/language.js +10 -0
  180. package/types/traffictype.d.ts +8 -0
  181. package/types/traffictype.js +13 -0
  182. package/types/validator.d.ts +4 -0
  183. package/types/validator.js +14 -0
  184. package/utils/api-model.d.ts +87 -0
  185. package/utils/api-model.js +129 -0
  186. package/utils/base64.d.ts +12 -0
  187. package/utils/base64.js +21 -0
  188. package/utils/date-utils.d.ts +17 -0
  189. package/utils/date-utils.js +34 -0
  190. package/utils/geojson-types.d.ts +14 -0
  191. package/utils/geojson-types.js +18 -0
  192. package/utils/geometry.d.ts +36 -0
  193. package/utils/geometry.js +140 -0
  194. package/utils/retry.d.ts +13 -0
  195. package/utils/retry.js +50 -0
  196. package/utils/slack.d.ts +5 -0
  197. package/utils/slack.js +25 -0
  198. package/utils/utils.d.ts +22 -0
  199. package/utils/utils.js +40 -0
@@ -0,0 +1,238 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.HeaderChecker = exports.GeoJsonChecker = exports.ContentTypeChecker = exports.ContentChecker = exports.ResponseChecker = exports.UrlChecker = exports.API_KEY_HEADER = void 0;
4
+ const http2_1 = require("http2");
5
+ const asserter_1 = require("digitraffic-common/test/asserter");
6
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
7
+ const synthetics = require('Synthetics');
8
+ const zlib = require("zlib");
9
+ const mediatypes_1 = require("../../types/mediatypes");
10
+ const apikey_1 = require("../../runtime/apikey");
11
+ const geometry_1 = require("../../../utils/geometry");
12
+ exports.API_KEY_HEADER = "x-api-key";
13
+ const baseHeaders = {
14
+ "Digitraffic-User": "internal-digitraffic-canary",
15
+ "Accept-Encoding": "gzip",
16
+ "Accept": "*/*",
17
+ };
18
+ class UrlChecker {
19
+ constructor(hostname, apiKey) {
20
+ const headers = { ...baseHeaders };
21
+ if (apiKey) {
22
+ headers[exports.API_KEY_HEADER] = apiKey;
23
+ }
24
+ this.requestOptions = {
25
+ hostname,
26
+ method: 'GET',
27
+ protocol: 'https:',
28
+ headers,
29
+ };
30
+ synthetics.getConfiguration()
31
+ .disableRequestMetrics();
32
+ synthetics.getConfiguration()
33
+ .withIncludeRequestBody(false)
34
+ .withIncludeRequestHeaders(false)
35
+ .withIncludeResponseBody(false)
36
+ .withIncludeResponseHeaders(false)
37
+ .withFailedCanaryMetric(true);
38
+ }
39
+ static create(hostname, apiKeyId) {
40
+ return (0, apikey_1.getApiKeyFromAPIGateway)(apiKeyId).then(apiKey => {
41
+ return new UrlChecker(hostname, apiKey.value);
42
+ });
43
+ }
44
+ static createV2() {
45
+ return this.create(process.env.hostname, process.env.apiKeyId);
46
+ }
47
+ expectStatus(statusCode, url, callback) {
48
+ const requestOptions = { ...this.requestOptions, ...{
49
+ path: url,
50
+ } };
51
+ return synthetics.executeHttpStep(`Verify ${statusCode} for ${url.replace(/auth=.*/, '')}`, requestOptions, callback);
52
+ }
53
+ expect200(url, ...callbacks) {
54
+ const callback = async (json, body, res) => {
55
+ await Promise.allSettled(callbacks.map(c => c(json, body, res)));
56
+ };
57
+ return this.expectStatus(200, url, callback);
58
+ }
59
+ expect404(url) {
60
+ const requestOptions = { ...this.requestOptions, ...{
61
+ path: url,
62
+ } };
63
+ return synthetics.executeHttpStep(`Verify 404 for ${url}`, requestOptions, validateStatusCodeAndContentType(404, mediatypes_1.MediaType.TEXT_PLAIN));
64
+ }
65
+ expect400(url) {
66
+ const requestOptions = { ...this.requestOptions, ...{
67
+ path: url,
68
+ } };
69
+ return synthetics.executeHttpStep(`Verify 400 for ${url}`, requestOptions, validateStatusCodeAndContentType(400, mediatypes_1.MediaType.TEXT_PLAIN));
70
+ }
71
+ expect403WithoutApiKey(url, mediaType) {
72
+ if (!this.requestOptions.headers || !this.requestOptions.headers[exports.API_KEY_HEADER]) {
73
+ console.error("No api key defined");
74
+ }
75
+ const requestOptions = { ...this.requestOptions, ...{
76
+ path: url,
77
+ headers: baseHeaders,
78
+ } };
79
+ return synthetics.executeHttpStep(`Verify 403 for ${url}`, requestOptions, validateStatusCodeAndContentType(403, mediaType || mediatypes_1.MediaType.APPLICATION_JSON));
80
+ }
81
+ done() {
82
+ return "Canary successful";
83
+ }
84
+ }
85
+ exports.UrlChecker = UrlChecker;
86
+ async function getResponseBody(response) {
87
+ const body = await getBodyFromResponse(response);
88
+ if (response.headers[http2_1.constants.HTTP2_HEADER_CONTENT_ENCODING] === 'gzip') {
89
+ try {
90
+ return zlib.gunzipSync(body).toString();
91
+ }
92
+ catch (e) {
93
+ console.info("error " + JSON.stringify(e));
94
+ }
95
+ }
96
+ return body.toString();
97
+ }
98
+ function getBodyFromResponse(response) {
99
+ return new Promise((resolve) => {
100
+ const buffers = [];
101
+ response.on('data', (data) => {
102
+ buffers.push(data);
103
+ });
104
+ response.on('end', () => {
105
+ resolve(Buffer.concat(buffers).toString());
106
+ });
107
+ });
108
+ }
109
+ /**
110
+ * Returns function, that validates that the status code and content-type from response are the given values
111
+ * @param statusCode
112
+ * @param contentType
113
+ */
114
+ function validateStatusCodeAndContentType(statusCode, contentType) {
115
+ return (res) => {
116
+ return new Promise(resolve => {
117
+ if (res.statusCode !== statusCode) {
118
+ throw new Error(`${res.statusCode} ${res.statusMessage}`);
119
+ }
120
+ if (res.headers[http2_1.constants.HTTP2_HEADER_CONTENT_TYPE] !== contentType) {
121
+ throw new Error('Wrong content-type ' + res.headers[http2_1.constants.HTTP2_HEADER_CONTENT_TYPE]);
122
+ }
123
+ resolve();
124
+ });
125
+ };
126
+ }
127
+ // DEPRECATED
128
+ class ResponseChecker {
129
+ constructor(contentType) {
130
+ this.checkCors = true;
131
+ this.contentType = contentType;
132
+ }
133
+ static forJson() {
134
+ return new ResponseChecker(mediatypes_1.MediaType.APPLICATION_JSON);
135
+ }
136
+ static forCSV() {
137
+ return new ResponseChecker(mediatypes_1.MediaType.TEXT_CSV);
138
+ }
139
+ static forGeojson() {
140
+ return new ResponseChecker(mediatypes_1.MediaType.APPLICATION_GEOJSON);
141
+ }
142
+ static forJpeg() {
143
+ return new ResponseChecker(mediatypes_1.MediaType.IMAGE_JPEG);
144
+ }
145
+ check() {
146
+ return this.responseChecker(() => {
147
+ // no need to do anything
148
+ });
149
+ }
150
+ checkJson(fn) {
151
+ return this.responseChecker((body, res) => {
152
+ fn(JSON.parse(body), body, res);
153
+ });
154
+ }
155
+ responseChecker(fn) {
156
+ return async (res) => {
157
+ if (!res.statusCode) {
158
+ throw new Error('statusCode missing');
159
+ }
160
+ if (res.statusCode < 200 || res.statusCode > 299) {
161
+ throw new Error(`${res.statusCode} ${res.statusMessage}`);
162
+ }
163
+ if (this.checkCors && !res.headers[http2_1.constants.HTTP2_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN]) {
164
+ throw new Error('CORS missing');
165
+ }
166
+ if (res.headers[http2_1.constants.HTTP2_HEADER_CONTENT_TYPE] !== this.contentType) {
167
+ throw new Error('Wrong content-type ' + res.headers[http2_1.constants.HTTP2_HEADER_CONTENT_TYPE]);
168
+ }
169
+ const body = await getResponseBody(res);
170
+ fn(body, res);
171
+ };
172
+ }
173
+ }
174
+ exports.ResponseChecker = ResponseChecker;
175
+ class ContentChecker {
176
+ static checkJson(fn) {
177
+ return async (res) => {
178
+ const body = await getResponseBody(res);
179
+ fn(JSON.parse(body), body, res);
180
+ };
181
+ }
182
+ static checkResponse(fn) {
183
+ return async (res) => {
184
+ const body = await getResponseBody(res);
185
+ fn(body, res);
186
+ };
187
+ }
188
+ }
189
+ exports.ContentChecker = ContentChecker;
190
+ class ContentTypeChecker {
191
+ static checkContentType(contentType) {
192
+ return (res) => {
193
+ if (!res.statusCode) {
194
+ throw new Error('statusCode missing');
195
+ }
196
+ if (res.statusCode < 200 || res.statusCode > 299) {
197
+ throw new Error(`${res.statusCode} ${res.statusMessage}`);
198
+ }
199
+ if (!res.headers[http2_1.constants.HTTP2_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN]) {
200
+ throw new Error('CORS missing');
201
+ }
202
+ if (res.headers[http2_1.constants.HTTP2_HEADER_CONTENT_TYPE] !== contentType) {
203
+ throw new Error('Wrong content-type ' + res.headers[http2_1.constants.HTTP2_HEADER_CONTENT_TYPE]);
204
+ }
205
+ };
206
+ }
207
+ }
208
+ exports.ContentTypeChecker = ContentTypeChecker;
209
+ class GeoJsonChecker {
210
+ static validFeatureCollection(fn) {
211
+ return ResponseChecker.forGeojson().checkJson((json) => {
212
+ asserter_1.Asserter.assertEquals(json.type, 'FeatureCollection');
213
+ asserter_1.Asserter.assertTrue((0, geometry_1.isValidGeoJson)(json));
214
+ if (fn) {
215
+ fn(json);
216
+ }
217
+ });
218
+ }
219
+ }
220
+ exports.GeoJsonChecker = GeoJsonChecker;
221
+ class HeaderChecker {
222
+ static checkHeaderExists(headerName) {
223
+ return (res) => {
224
+ if (!res.headers[headerName]) {
225
+ throw new Error('Missing header: ' + headerName);
226
+ }
227
+ };
228
+ }
229
+ static checkHeaderMissing(headerName) {
230
+ return (res) => {
231
+ if (res.headers[headerName]) {
232
+ throw new Error('Header should not exist: ' + headerName);
233
+ }
234
+ };
235
+ }
236
+ }
237
+ exports.HeaderChecker = HeaderChecker;
238
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXJsLWNoZWNrZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9zcmMvYXdzL2luZnJhL2NhbmFyaWVzL3VybC1jaGVja2VyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLGlDQUFnQztBQUVoQywrREFBMEQ7QUFFMUQsOERBQThEO0FBQzlELE1BQU0sVUFBVSxHQUFHLE9BQU8sQ0FBQyxZQUFZLENBQUMsQ0FBQztBQUN6Qyw2QkFBOEI7QUFDOUIsdURBQWlEO0FBQ2pELGlEQUE2RDtBQUU3RCxzREFBdUQ7QUFFMUMsUUFBQSxjQUFjLEdBQUcsV0FBVyxDQUFDO0FBRTFDLE1BQU0sV0FBVyxHQUFHO0lBQ2hCLGtCQUFrQixFQUFHLDZCQUE2QjtJQUNsRCxpQkFBaUIsRUFBRyxNQUFNO0lBQzFCLFFBQVEsRUFBRSxLQUFLO0NBQ1EsQ0FBQztBQUs1QixNQUFhLFVBQVU7SUFHbkIsWUFBWSxRQUFnQixFQUFFLE1BQWU7UUFDekMsTUFBTSxPQUFPLEdBQUcsRUFBQyxHQUFHLFdBQVcsRUFBQyxDQUFDO1FBRWpDLElBQUksTUFBTSxFQUFFO1lBQ1IsT0FBTyxDQUFDLHNCQUFjLENBQUMsR0FBRyxNQUFNLENBQUM7U0FDcEM7UUFFRCxJQUFJLENBQUMsY0FBYyxHQUFHO1lBQ2xCLFFBQVE7WUFDUixNQUFNLEVBQUUsS0FBSztZQUNiLFFBQVEsRUFBRSxRQUFRO1lBQ2xCLE9BQU87U0FDVixDQUFDO1FBRUYsVUFBVSxDQUFDLGdCQUFnQixFQUFFO2FBQ3hCLHFCQUFxQixFQUFFLENBQUM7UUFFN0IsVUFBVSxDQUFDLGdCQUFnQixFQUFFO2FBQ3hCLHNCQUFzQixDQUFDLEtBQUssQ0FBQzthQUM3Qix5QkFBeUIsQ0FBQyxLQUFLLENBQUM7YUFDaEMsdUJBQXVCLENBQUMsS0FBSyxDQUFDO2FBQzlCLDBCQUEwQixDQUFDLEtBQUssQ0FBQzthQUNqQyxzQkFBc0IsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUN0QyxDQUFD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QUFDLFVBQWtCO1FBQ3hDLE9BQU8sQ0FBQyxHQUFvQixFQUFFLEVBQUU7WUFDNUIsSUFBSSxHQUFHLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQyxFQUFFO2dCQUN6QixNQUFNLElBQUksS0FBSyxDQUFDLDJCQUEyQixHQUFHLFVBQVUsQ0FBQyxDQUFDO2FBQzdEO1FBQ0wsQ0FBQyxDQUFDO0lBQ04sQ0FBQztDQUNKO0FBaEJELHNDQWdCQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7Y29uc3RhbnRzfSBmcm9tIFwiaHR0cDJcIjtcbmltcG9ydCB7SW5jb21pbmdNZXNzYWdlLCBSZXF1ZXN0T3B0aW9uc30gZnJvbSBcImh0dHBcIjtcbmltcG9ydCB7QXNzZXJ0ZXJ9IGZyb20gXCJkaWdpdHJhZmZpYy1jb21tb24vdGVzdC9hc3NlcnRlclwiO1xuXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXZhci1yZXF1aXJlc1xuY29uc3Qgc3ludGhldGljcyA9IHJlcXVpcmUoJ1N5bnRoZXRpY3MnKTtcbmltcG9ydCB6bGliID0gcmVxdWlyZSgnemxpYicpO1xuaW1wb3J0IHtNZWRpYVR5cGV9IGZyb20gXCIuLi8uLi90eXBlcy9tZWRpYXR5cGVzXCI7XG5pbXBvcnQge2dldEFwaUtleUZyb21BUElHYXRld2F5fSBmcm9tIFwiLi4vLi4vcnVudGltZS9hcGlrZXlcIjtcbmltcG9ydCB7RmVhdHVyZUNvbGxlY3Rpb259IGZyb20gXCJnZW9qc29uXCI7XG5pbXBvcnQge2lzVmFsaWRHZW9Kc29ufSBmcm9tIFwiLi4vLi4vLi4vdXRpbHMvZ2VvbWV0cnlcIjtcblxuZXhwb3J0IGNvbnN0IEFQSV9LRVlfSEVBREVSID0gXCJ4LWFwaS1rZXlcIjtcblxuY29uc3QgYmFzZUhlYWRlcnMgPSB7XG4gICAgXCJEaWdpdHJhZmZpYy1Vc2VyXCIgOiBcImludGVybmFsLWRpZ2l0cmFmZmljLWNhbmFyeVwiLFxuICAgIFwiQWNjZXB0LUVuY29kaW5nXCIgOiBcImd6aXBcIixcbiAgICBcIkFjY2VwdFwiOiBcIiovKlwiLFxufSBhcyBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+O1xuXG50eXBlIENoZWNrZXJGdW5jdGlvbiA9IChSZXM6IEluY29taW5nTWVzc2FnZSkgPT4gdm9pZDtcbnR5cGUgSnNvbkNoZWNrZXJGdW5jdGlvbjxUPiA9IChqc29uOiBULCBib2R5OiBzdHJpbmcsIG1lc3NhZ2U6IEluY29taW5nTWVzc2FnZSkgPT4gdm9pZDtcblxuZXhwb3J0IGNsYXNzIFVybENoZWNrZXIge1xuICAgIHByaXZhdGUgcmVhZG9ubHkgcmVxdWVzdE9wdGlvbnM6IFJlcXVlc3RPcHRpb25zO1xuXG4gICAgY29uc3RydWN0b3IoaG9zdG5hbWU6IHN0cmluZywgYXBpS2V5Pzogc3RyaW5nKSB7XG4gICAgICAgIGNvbnN0IGhlYWRlcnMgPSB7Li4uYmFzZUhlYWRlcnN9O1xuXG4gICAgICAgIGlmIChhcGlLZXkpIHtcbiAgICAgICAgICAgIGhlYWRlcnNbQVBJX0tFWV9IRUFERVJdID0gYXBpS2V5O1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5yZXF1ZXN0T3B0aW9ucyA9IHtcbiAgICAgICAgICAgIGhvc3RuYW1lLFxuICAgICAgICAgICAgbWV0aG9kOiAnR0VUJyxcbiAgICAgICAgICAgIHByb3RvY29sOiAnaHR0cHM6JyxcbiAgICAgICAgICAgIGhlYWRlcnMsXG4gICAgICAgIH07XG5cbiAgICAgICAgc3ludGhldGljcy5nZXRDb25maWd1cmF0aW9uKClcbiAgICAgICAgICAgIC5kaXNhYmxlUmVxdWVzdE1ldHJpY3MoKTtcblxuICAgICAgICBzeW50aGV0aWNzLmdldENvbmZpZ3VyYXRpb24oKVxuICAgICAgICAgICAgLndpdGhJbmNsdWRlUmVxdWVzdEJvZHkoZmFsc2UpXG4gICAgICAgICAgICAud2l0aEluY2x1ZGVSZXF1ZXN0SGVhZGVycyhmYWxzZSlcbiAgICAgICAgICAgIC53aXRoSW5jbHVkZVJlc3BvbnNlQm9keShmYWxzZSlcbiAgICAgICAgICAgIC53aXRoSW5jbHVkZVJlc3BvbnNlSGVhZGVycyhmYWxzZSlcbiAgICAgICAgICAgIC53aXRoRmFpbGVkQ2FuYXJ5TWV0cmljKHRydWUpO1xuICAgIH1cblxuICAgIHN0YXRpYyBjcmVhdGUoaG9zdG5hbWU6IHN0cmluZywgYXBpS2V5SWQ6IHN0cmluZyk6IFByb21pc2U8VXJsQ2hlY2tlcj4ge1xuICAgICAgICByZXR1cm4gZ2V0QXBpS2V5RnJvbUFQSUdhdGV3YXkoYXBpS2V5SWQpLnRoZW4oYXBpS2V5ID0+IHtcbiAgICAgICAgICAgIHJldHVybiBuZXcgVXJsQ2hlY2tlcihob3N0bmFtZSwgYXBpS2V5LnZhbHVlKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgc3RhdGljIGNyZWF0ZVYyKCk6IFByb21pc2U8VXJsQ2hlY2tlcj4ge1xuICAgICAgICByZXR1cm4gdGhpcy5jcmVhdGUocHJvY2Vzcy5lbnYuaG9zdG5hbWUgYXMgc3RyaW5nLCBwcm9jZXNzLmVudi5hcGlLZXlJZCBhcyBzdHJpbmcpO1xuICAgIH1cblxuICAgIGV4cGVjdFN0YXR1czxUPihzdGF0dXNDb2RlOiBudW1iZXIsIHVybDogc3RyaW5nLCBjYWxsYmFjazogSnNvbkNoZWNrZXJGdW5jdGlvbjxUPik6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICBjb25zdCByZXF1ZXN0T3B0aW9ucyA9IHsuLi50aGlzLnJlcXVlc3RPcHRpb25zLCAuLi57XG4gICAgICAgICAgICBwYXRoOiB1cmwsXG4gICAgICAgIH19O1xuXG4gICAgICAgIHJldHVybiBzeW50aGV0aWNzLmV4ZWN1dGVIdHRwU3RlcChgVmVyaWZ5ICR7c3RhdHVzQ29kZX0gZm9yICR7dXJsLnJlcGxhY2UoL2F1dGg9LiovLCAnJyl9YCxcbiAgICAgICAgICAgIHJlcXVlc3RPcHRpb25zLFxuICAgICAgICAgICAgY2FsbGJhY2spO1xuICAgIH1cblxuICAgIGV4cGVjdDIwMDxUPih1cmw6IHN0cmluZywgLi4uY2FsbGJhY2tzOiBKc29uQ2hlY2tlckZ1bmN0aW9uPFQ+W10pOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgY29uc3QgY2FsbGJhY2sgPSBhc3luYyAoanNvbjogVCwgYm9keTogc3RyaW5nLCByZXM6IEluY29taW5nTWVzc2FnZSkgPT4ge1xuICAgICAgICAgICAgYXdhaXQgUHJvbWlzZS5hbGxTZXR0bGVkKGNhbGxiYWNrcy5tYXAoYyA9PiBjKGpzb24sIGJvZHksIHJlcykpKTtcbiAgICAgICAgfTtcblxuICAgICAgICByZXR1cm4gdGhpcy5leHBlY3RTdGF0dXMoMjAwLCB1cmwsIGNhbGxiYWNrKTtcbiAgICB9XG5cbiAgICBleHBlY3Q0MDQodXJsOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgY29uc3QgcmVxdWVzdE9wdGlvbnMgPSB7Li4udGhpcy5yZXF1ZXN0T3B0aW9ucywgLi4ue1xuICAgICAgICAgICAgcGF0aDogdXJsLFxuICAgICAgICB9fTtcblxuICAgICAgICByZXR1cm4gc3ludGhldGljcy5leGVjdXRlSHR0cFN0ZXAoYFZlcmlmeSA0MDQgZm9yICR7dXJsfWAsIHJlcXVlc3RPcHRpb25zLCB2YWxpZGF0ZVN0YXR1c0NvZGVBbmRDb250ZW50VHlwZSg0MDQsIE1lZGlhVHlwZS5URVhUX1BMQUlOKSk7XG4gICAgfVxuXG4gICAgZXhwZWN0NDAwKHVybDogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIGNvbnN0IHJlcXVlc3RPcHRpb25zID0gey4uLnRoaXMucmVxdWVzdE9wdGlvbnMsIC4uLntcbiAgICAgICAgICAgIHBhdGg6IHVybCxcbiAgICAgICAgfX07XG5cbiAgICAgICAgcmV0dXJuIHN5bnRoZXRpY3MuZXhlY3V0ZUh0dHBTdGVwKGBWZXJpZnkgNDAwIGZvciAke3VybH1gLCByZXF1ZXN0T3B0aW9ucywgdmFsaWRhdGVTdGF0dXNDb2RlQW5kQ29udGVudFR5cGUoNDAwLCBNZWRpYVR5cGUuVEVYVF9QTEFJTikpO1xuICAgIH1cblxuICAgIGV4cGVjdDQwM1dpdGhvdXRBcGlLZXkodXJsOiBzdHJpbmcsIG1lZGlhVHlwZT86IE1lZGlhVHlwZSk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICBpZiAoIXRoaXMucmVxdWVzdE9wdGlvbnMuaGVhZGVycyB8fCAhdGhpcy5yZXF1ZXN0T3B0aW9ucy5oZWFkZXJzW0FQSV9LRVlfSEVBREVSXSkge1xuICAgICAgICAgICAgY29uc29sZS5lcnJvcihcIk5vIGFwaSBrZXkgZGVmaW5lZFwiKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHJlcXVlc3RPcHRpb25zID0gey4uLnRoaXMucmVxdWVzdE9wdGlvbnMsIC4uLntcbiAgICAgICAgICAgIHBhdGg6IHVybCxcbiAgICAgICAgICAgIGhlYWRlcnM6IGJhc2VIZWFkZXJzLFxuICAgICAgICB9fTtcblxuICAgICAgICByZXR1cm4gc3ludGhldGljcy5leGVjdXRlSHR0cFN0ZXAoYFZlcmlmeSA0MDMgZm9yICR7dXJsfWAsXG4gICAgICAgICAgICByZXF1ZXN0T3B0aW9ucyxcbiAgICAgICAgICAgIHZhbGlkYXRlU3RhdHVzQ29kZUFuZENvbnRlbnRUeXBlKDQwMywgbWVkaWFUeXBlIHx8IE1lZGlhVHlwZS5BUFBMSUNBVElPTl9KU09OKSk7XG4gICAgfVxuXG4gICAgZG9uZSgpOiBzdHJpbmcge1xuICAgICAgICByZXR1cm4gXCJDYW5hcnkgc3VjY2Vzc2Z1bFwiO1xuICAgIH1cbn1cblxuYXN5bmMgZnVuY3Rpb24gZ2V0UmVzcG9uc2VCb2R5KHJlc3BvbnNlOiBJbmNvbWluZ01lc3NhZ2UpOiBQcm9taXNlPHN0cmluZz4ge1xuICAgIGNvbnN0IGJvZHkgPSBhd2FpdCBnZXRCb2R5RnJvbVJlc3BvbnNlKHJlc3BvbnNlKTtcblxuICAgIGlmIChyZXNwb25zZS5oZWFkZXJzW2NvbnN0YW50cy5IVFRQMl9IRUFERVJfQ09OVEVOVF9FTkNPRElOR10gPT09ICdnemlwJykge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgcmV0dXJuIHpsaWIuZ3VuemlwU3luYyhib2R5KS50b1N0cmluZygpO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICBjb25zb2xlLmluZm8oXCJlcnJvciBcIiArIEpTT04uc3RyaW5naWZ5KGUpKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBib2R5LnRvU3RyaW5nKCk7XG59XG5cbmZ1bmN0aW9uIGdldEJvZHlGcm9tUmVzcG9uc2UocmVzcG9uc2U6IEluY29taW5nTWVzc2FnZSk6IFByb21pc2U8c3RyaW5nPiB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlOiAoKHZhbHVlOiBzdHJpbmcpID0+IHZvaWQpKSA9PiB7XG4gICAgICAgIGNvbnN0IGJ1ZmZlcnM6IEJ1ZmZlcltdID0gW107XG5cbiAgICAgICAgcmVzcG9uc2Uub24oJ2RhdGEnLCAoZGF0YTogQnVmZmVyKSA9PiB7XG4gICAgICAgICAgICBidWZmZXJzLnB1c2goZGF0YSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHJlc3BvbnNlLm9uKCdlbmQnLCAoKSA9PiB7XG4gICAgICAgICAgICByZXNvbHZlKEJ1ZmZlci5jb25jYXQoYnVmZmVycykudG9TdHJpbmcoKSk7XG4gICAgICAgIH0pO1xuICAgIH0pO1xufVxuXG4vKipcbiAqIFJldHVybnMgZnVuY3Rpb24sIHRoYXQgdmFsaWRhdGVzIHRoYXQgdGhlIHN0YXR1cyBjb2RlIGFuZCBjb250ZW50LXR5cGUgZnJvbSByZXNwb25zZSBhcmUgdGhlIGdpdmVuIHZhbHVlc1xuICogQHBhcmFtIHN0YXR1c0NvZGVcbiAqIEBwYXJhbSBjb250ZW50VHlwZVxuICovXG5mdW5jdGlvbiB2YWxpZGF0ZVN0YXR1c0NvZGVBbmRDb250ZW50VHlwZShzdGF0dXNDb2RlOiBudW1iZXIsIGNvbnRlbnRUeXBlOiBNZWRpYVR5cGUpOiAoUmVzOiBJbmNvbWluZ01lc3NhZ2UpID0+IFByb21pc2U8dm9pZD4ge1xuICAgIHJldHVybiAocmVzOiBJbmNvbWluZ01lc3NhZ2UpID0+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKHJlc29sdmUgPT4ge1xuICAgICAgICAgICAgaWYgKHJlcy5zdGF0dXNDb2RlICE9PSBzdGF0dXNDb2RlKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGAke3Jlcy5zdGF0dXNDb2RlfSAke3Jlcy5zdGF0dXNNZXNzYWdlfWApO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAocmVzLmhlYWRlcnNbY29uc3RhbnRzLkhUVFAyX0hFQURFUl9DT05URU5UX1RZUEVdICE9PSBjb250ZW50VHlwZSkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignV3JvbmcgY29udGVudC10eXBlICcgKyByZXMuaGVhZGVyc1tjb25zdGFudHMuSFRUUDJfSEVBREVSX0NPTlRFTlRfVFlQRV0pO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgIH0pO1xuICAgIH07XG59XG5cbi8vIERFUFJFQ0FURURcbmV4cG9ydCBjbGFzcyBSZXNwb25zZUNoZWNrZXIge1xuICAgIHByaXZhdGUgcmVhZG9ubHkgY29udGVudFR5cGU7XG4gICAgcHJpdmF0ZSBjaGVja0NvcnMgPSB0cnVlO1xuXG4gICAgY29uc3RydWN0b3IoY29udGVudFR5cGU6IHN0cmluZykge1xuICAgICAgICB0aGlzLmNvbnRlbnRUeXBlID0gY29udGVudFR5cGU7XG4gICAgfVxuXG4gICAgc3RhdGljIGZvckpzb24oKTogUmVzcG9uc2VDaGVja2VyIHtcbiAgICAgICAgcmV0dXJuIG5ldyBSZXNwb25zZUNoZWNrZXIoTWVkaWFUeXBlLkFQUExJQ0FUSU9OX0pTT04pO1xuICAgIH1cblxuICAgIHN0YXRpYyBmb3JDU1YoKTogUmVzcG9uc2VDaGVja2VyIHtcbiAgICAgICAgcmV0dXJuIG5ldyBSZXNwb25zZUNoZWNrZXIoTWVkaWFUeXBlLlRFWFRfQ1NWKTtcbiAgICB9XG5cbiAgICBzdGF0aWMgZm9yR2VvanNvbigpOiBSZXNwb25zZUNoZWNrZXIge1xuICAgICAgICByZXR1cm4gbmV3IFJlc3BvbnNlQ2hlY2tlcihNZWRpYVR5cGUuQVBQTElDQVRJT05fR0VPSlNPTik7XG4gICAgfVxuXG4gICAgc3RhdGljIGZvckpwZWcoKTogUmVzcG9uc2VDaGVja2VyIHtcbiAgICAgICAgcmV0dXJuIG5ldyBSZXNwb25zZUNoZWNrZXIoTWVkaWFUeXBlLklNQUdFX0pQRUcpO1xuICAgIH1cblxuICAgIGNoZWNrKCk6IENoZWNrZXJGdW5jdGlvbiB7XG4gICAgICAgIHJldHVybiB0aGlzLnJlc3BvbnNlQ2hlY2tlcigoKSA9PiB7XG4gICAgICAgICAgICAvLyBubyBuZWVkIHRvIGRvIGFueXRoaW5nXG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIGNoZWNrSnNvbjxUPihmbjogKGpzb246IFQsIGJvZHk6IHN0cmluZywgcmVzOiBJbmNvbWluZ01lc3NhZ2UpID0+IHZvaWQpOiBDaGVja2VyRnVuY3Rpb24ge1xuICAgICAgICByZXR1cm4gdGhpcy5yZXNwb25zZUNoZWNrZXIoKGJvZHk6IHN0cmluZywgcmVzOiBJbmNvbWluZ01lc3NhZ2UpID0+IHtcbiAgICAgICAgICAgIGZuKEpTT04ucGFyc2UoYm9keSksIGJvZHksIHJlcyk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHJlc3BvbnNlQ2hlY2tlcihmbjogKGJvZHk6IHN0cmluZywgcmVzOiBJbmNvbWluZ01lc3NhZ2UpID0+IHZvaWQpOiBDaGVja2VyRnVuY3Rpb24ge1xuICAgICAgICByZXR1cm4gYXN5bmMgKHJlczogSW5jb21pbmdNZXNzYWdlKTogUHJvbWlzZTx2b2lkPiA9PiB7XG4gICAgICAgICAgICBpZiAoIXJlcy5zdGF0dXNDb2RlKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdzdGF0dXNDb2RlIG1pc3NpbmcnKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKHJlcy5zdGF0dXNDb2RlIDwgMjAwIHx8IHJlcy5zdGF0dXNDb2RlID4gMjk5KSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGAke3Jlcy5zdGF0dXNDb2RlfSAke3Jlcy5zdGF0dXNNZXNzYWdlfWApO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAodGhpcy5jaGVja0NvcnMgJiYgIXJlcy5oZWFkZXJzW2NvbnN0YW50cy5IVFRQMl9IRUFERVJfQUNDRVNTX0NPTlRST0xfQUxMT1dfT1JJR0lOXSkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignQ09SUyBtaXNzaW5nJyk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChyZXMuaGVhZGVyc1tjb25zdGFudHMuSFRUUDJfSEVBREVSX0NPTlRFTlRfVFlQRV0gIT09IHRoaXMuY29udGVudFR5cGUpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1dyb25nIGNvbnRlbnQtdHlwZSAnICsgcmVzLmhlYWRlcnNbY29uc3RhbnRzLkhUVFAyX0hFQURFUl9DT05URU5UX1RZUEVdKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc3QgYm9keSA9IGF3YWl0IGdldFJlc3BvbnNlQm9keShyZXMpO1xuXG4gICAgICAgICAgICBmbihib2R5LCByZXMpO1xuICAgICAgICB9O1xuICAgIH1cbn1cblxuZXhwb3J0IGNsYXNzIENvbnRlbnRDaGVja2VyIHtcbiAgICBzdGF0aWMgY2hlY2tKc29uPFQ+KGZuOiAoanNvbjogVCwgYm9keTogc3RyaW5nLCByZXM6IEluY29taW5nTWVzc2FnZSkgPT4gdm9pZCk6IENoZWNrZXJGdW5jdGlvbiB7XG4gICAgICAgIHJldHVybiBhc3luYyAocmVzOiBJbmNvbWluZ01lc3NhZ2UpOiBQcm9taXNlPHZvaWQ+ID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGJvZHkgPSBhd2FpdCBnZXRSZXNwb25zZUJvZHkocmVzKTtcblxuICAgICAgICAgICAgZm4oSlNPTi5wYXJzZShib2R5KSwgYm9keSwgcmVzKTtcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBzdGF0aWMgY2hlY2tSZXNwb25zZShmbjogKGJvZHk6IHN0cmluZywgcmVzOiBJbmNvbWluZ01lc3NhZ2UpID0+IHZvaWQpOiBDaGVja2VyRnVuY3Rpb24ge1xuICAgICAgICByZXR1cm4gYXN5bmMgKHJlczogSW5jb21pbmdNZXNzYWdlKTogUHJvbWlzZTx2b2lkPiA9PiB7XG4gICAgICAgICAgICBjb25zdCBib2R5ID0gYXdhaXQgZ2V0UmVzcG9uc2VCb2R5KHJlcyk7XG5cbiAgICAgICAgICAgIGZuKGJvZHksIHJlcyk7XG4gICAgICAgIH07XG4gICAgfVxufVxuXG5leHBvcnQgY2xhc3MgQ29udGVudFR5cGVDaGVja2VyIHtcbiAgICBzdGF0aWMgY2hlY2tDb250ZW50VHlwZShjb250ZW50VHlwZTogTWVkaWFUeXBlKSB7XG4gICAgICAgIHJldHVybiAocmVzOiBJbmNvbWluZ01lc3NhZ2UpID0+IHtcbiAgICAgICAgICAgIGlmICghcmVzLnN0YXR1c0NvZGUpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ3N0YXR1c0NvZGUgbWlzc2luZycpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAocmVzLnN0YXR1c0NvZGUgPCAyMDAgfHwgcmVzLnN0YXR1c0NvZGUgPiAyOTkpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYCR7cmVzLnN0YXR1c0NvZGV9ICR7cmVzLnN0YXR1c01lc3NhZ2V9YCk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmICghcmVzLmhlYWRlcnNbY29uc3RhbnRzLkhUVFAyX0hFQURFUl9BQ0NFU1NfQ09OVFJPTF9BTExPV19PUklHSU5dKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdDT1JTIG1pc3NpbmcnKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKHJlcy5oZWFkZXJzW2NvbnN0YW50cy5IVFRQMl9IRUFERVJfQ09OVEVOVF9UWVBFXSAhPT0gY29udGVudFR5cGUpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1dyb25nIGNvbnRlbnQtdHlwZSAnICsgcmVzLmhlYWRlcnNbY29uc3RhbnRzLkhUVFAyX0hFQURFUl9DT05URU5UX1RZUEVdKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICB9XG59XG5cbmV4cG9ydCBjbGFzcyBHZW9Kc29uQ2hlY2tlciB7XG4gICAgc3RhdGljIHZhbGlkRmVhdHVyZUNvbGxlY3Rpb24oZm4/OiAoanNvbjogRmVhdHVyZUNvbGxlY3Rpb24pID0+IHZvaWQpOiBDaGVja2VyRnVuY3Rpb24ge1xuICAgICAgICByZXR1cm4gUmVzcG9uc2VDaGVja2VyLmZvckdlb2pzb24oKS5jaGVja0pzb24oKGpzb246IEZlYXR1cmVDb2xsZWN0aW9uKSA9PiB7XG4gICAgICAgICAgICBBc3NlcnRlci5hc3NlcnRFcXVhbHMoanNvbi50eXBlLCAnRmVhdHVyZUNvbGxlY3Rpb24nKTtcbiAgICAgICAgICAgIEFzc2VydGVyLmFzc2VydFRydWUoaXNWYWxpZEdlb0pzb24oanNvbikpO1xuXG4gICAgICAgICAgICBpZiAoZm4pIHtcbiAgICAgICAgICAgICAgICBmbihqc29uKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxufVxuXG5leHBvcnQgY2xhc3MgSGVhZGVyQ2hlY2tlciB7XG4gICAgc3RhdGljIGNoZWNrSGVhZGVyRXhpc3RzKGhlYWRlck5hbWU6IHN0cmluZyk6IENoZWNrZXJGdW5jdGlvbiB7XG4gICAgICAgIHJldHVybiAocmVzOiBJbmNvbWluZ01lc3NhZ2UpID0+IHtcbiAgICAgICAgICAgIGlmICghcmVzLmhlYWRlcnNbaGVhZGVyTmFtZV0pIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ01pc3NpbmcgaGVhZGVyOiAnICsgaGVhZGVyTmFtZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgc3RhdGljIGNoZWNrSGVhZGVyTWlzc2luZyhoZWFkZXJOYW1lOiBzdHJpbmcpOiBDaGVja2VyRnVuY3Rpb24ge1xuICAgICAgICByZXR1cm4gKHJlczogSW5jb21pbmdNZXNzYWdlKSA9PiB7XG4gICAgICAgICAgICBpZiAocmVzLmhlYWRlcnNbaGVhZGVyTmFtZV0pIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0hlYWRlciBzaG91bGQgbm90IGV4aXN0OiAnICsgaGVhZGVyTmFtZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgfVxufVxuIl19
@@ -0,0 +1,95 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DocumentationPart = exports.addTagsAndSummary = exports.addTags = exports.addDocumentation = exports.addQueryParameterDescription = void 0;
4
+ const aws_apigateway_1 = require("aws-cdk-lib/aws-apigateway");
5
+ // Documentation parts are objects that describe an API Gateway API or parts of an API
6
+ // https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-documenting-api.html
7
+ /**
8
+ * Add description to a query parameter
9
+ * @param name query parameter name
10
+ * @param description query parameter description
11
+ * @param resource REST API resource
12
+ * @param stack CloudFormation stack
13
+ *
14
+ * @deprecated Use DigitrafficRestApi.documentResource
15
+ */
16
+ function addQueryParameterDescription(name, description, resource, stack) {
17
+ new aws_apigateway_1.CfnDocumentationPart(stack, `${name}Documentation`, {
18
+ restApiId: resource.api.restApiId,
19
+ location: {
20
+ type: 'QUERY_PARAMETER',
21
+ name,
22
+ path: resource.path,
23
+ },
24
+ properties: JSON.stringify({ description }),
25
+ });
26
+ }
27
+ exports.addQueryParameterDescription = addQueryParameterDescription;
28
+ /**
29
+ * Add a documentation part to a method
30
+ * @param methodDescription
31
+ * @param documentationProperties
32
+ * @param resource REST API resource
33
+ * @param stack CloudFormation stack
34
+ */
35
+ function addDocumentation(methodDescription, documentationProperties, resource, stack) {
36
+ new aws_apigateway_1.CfnDocumentationPart(stack, `${methodDescription}Documentation`, {
37
+ restApiId: resource.api.restApiId,
38
+ location: {
39
+ type: 'METHOD',
40
+ path: resource.path,
41
+ },
42
+ properties: JSON.stringify(documentationProperties),
43
+ });
44
+ }
45
+ exports.addDocumentation = addDocumentation;
46
+ /**
47
+ * Adds OpenAPI tags to an API method
48
+ * @param methodDescription Description of API method
49
+ * @param tags OpenAPI tags
50
+ * @param resource REST API resource
51
+ * @param stack CloudFormation stack
52
+ */
53
+ function addTags(methodDescription, tags, resource, stack) {
54
+ addDocumentation(methodDescription, { tags }, resource, stack);
55
+ }
56
+ exports.addTags = addTags;
57
+ /**
58
+ * Adds OpenAPI tags and a method summary to an API method
59
+ *
60
+ * @deprecated Use DigitrafficRestApi.documentResource
61
+ *
62
+ * @param methodDescription Description of API method
63
+ * @param tags OpenAPI tags
64
+ * @param summary OpenAPI summary
65
+ * @param resource REST API resource
66
+ * @param stack CloudFormation stack
67
+ */
68
+ function addTagsAndSummary(methodDescription, tags, summary, resource, stack) {
69
+ addDocumentation(methodDescription, { tags, summary }, resource, stack);
70
+ }
71
+ exports.addTagsAndSummary = addTagsAndSummary;
72
+ class DocumentationPart {
73
+ constructor(parameterName, documentationProperties, type) {
74
+ this.parameterName = parameterName;
75
+ this.documentationProperties = documentationProperties;
76
+ this.type = type;
77
+ }
78
+ deprecated(note) {
79
+ // deprecated is not supported ATM: https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-known-issues.html
80
+ this.documentationProperties.deprecated = true;
81
+ this.documentationProperties.summary += '. ' + note;
82
+ return this;
83
+ }
84
+ static queryParameter(parameterName, description) {
85
+ return new DocumentationPart(parameterName, { description }, "QUERY_PARAMETER");
86
+ }
87
+ static pathParameter(parameterName, description) {
88
+ return new DocumentationPart(parameterName, { description }, "PATH_PARAMETER");
89
+ }
90
+ static method(tags, name, summary) {
91
+ return new DocumentationPart(name, { tags, summary }, "METHOD");
92
+ }
93
+ }
94
+ exports.DocumentationPart = DocumentationPart;
95
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZG9jdW1lbnRhdGlvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9hd3MvaW5mcmEvZG9jdW1lbnRhdGlvbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFDQSwrREFBMEU7QUFFMUUsc0ZBQXNGO0FBQ3RGLGdHQUFnRztBQUVoRzs7Ozs7Ozs7R0FRRztBQUNILFNBQWdCLDRCQUE0QixDQUFDLElBQVksRUFDckQsV0FBbUIsRUFDbkIsUUFBa0IsRUFDbEIsS0FBZ0I7SUFDaEIsSUFBSSxxQ0FBb0IsQ0FBQyxLQUFLLEVBQUUsR0FBRyxJQUFJLGVBQWUsRUFBRTtRQUNwRCxTQUFTLEVBQUUsUUFBUSxDQUFDLEdBQUcsQ0FBQyxTQUFTO1FBQ2pDLFFBQVEsRUFBRTtZQUNOLElBQUksRUFBRSxpQkFBaUI7WUFDdkIsSUFBSTtZQUNKLElBQUksRUFBRSxRQUFRLENBQUMsSUFBSTtTQUN0QjtRQUNELFVBQVUsRUFBRSxJQUFJLENBQUMsU0FBUyxDQUFDLEVBQUMsV0FBVyxFQUFDLENBQUM7S0FDNUMsQ0FBQyxDQUFDO0FBQ1AsQ0FBQztBQWJELG9FQWFDO0FBRUQ7Ozs7OztHQU1HO0FBQ0gsU0FBZ0IsZ0JBQWdCLENBQUMsaUJBQXlCLEVBQ3RELHVCQUErQixFQUMvQixRQUFrQixFQUNsQixLQUFnQjtJQUNoQixJQUFJLHFDQUFvQixDQUFDLEtBQUssRUFBRSxHQUFHLGlCQUFpQixlQUFlLEVBQUU7UUFDakUsU0FBUyxFQUFFLFFBQVEsQ0FBQyxHQUFHLENBQUMsU0FBUztRQUNqQyxRQUFRLEVBQUU7WUFDTixJQUFJLEVBQUUsUUFBUTtZQUNkLElBQUksRUFBRSxRQUFRLENBQUMsSUFBSTtTQUN0QjtRQUNELFVBQVUsRUFBRSxJQUFJLENBQUMsU0FBUyxDQUFDLHVCQUF1QixDQUFDO0tBQ3RELENBQUMsQ0FBQztBQUNQLENBQUM7QUFaRCw0Q0FZQztBQUVEOzs7Ozs7R0FNRztBQUNILFNBQWdCLE9BQU8sQ0FBQyxpQkFBeUIsRUFDN0MsSUFBYyxFQUNkLFFBQWtCLEVBQ2xCLEtBQWdCO0lBQ2hCLGdCQUFnQixDQUFDLGlCQUFpQixFQUFFLEVBQUMsSUFBSSxFQUFDLEVBQUUsUUFBUSxFQUFFLEtBQUssQ0FBQyxDQUFDO0FBQ2pFLENBQUM7QUFMRCwwQkFLQztBQUVEOzs7Ozs7Ozs7O0dBVUc7QUFDSCxTQUFnQixpQkFBaUIsQ0FDN0IsaUJBQXlCLEVBQ3pCLElBQWMsRUFDZCxPQUFlLEVBQ2YsUUFBa0IsRUFDbEIsS0FBZ0I7SUFFaEIsZ0JBQWdCLENBQUMsaUJBQWlCLEVBQUUsRUFBQyxJQUFJLEVBQUUsT0FBTyxFQUFDLEVBQUUsUUFBUSxFQUFFLEtBQUssQ0FBQyxDQUFDO0FBQzFFLENBQUM7QUFSRCw4Q0FRQztBQVNELE1BQWEsaUJBQWlCO0lBSzFCLFlBQW9CLGFBQXFCLEVBQUUsdUJBQWdELEVBQUUsSUFBWTtRQUNyRyxJQUFJLENBQUMsYUFBYSxHQUFHLGFBQWEsQ0FBQztRQUNuQyxJQUFJLENBQUMsdUJBQXVCLEdBQUcsdUJBQXVCLENBQUM7UUFDdkQsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUM7SUFDckIsQ0FBQztJQUVELFVBQVUsQ0FBQyxJQUFZO1FBQ25CLDhIQUE4SDtRQUM5SCxJQUFJLENBQUMsdUJBQXVCLENBQUMsVUFBVSxHQUFHLElBQUksQ0FBQztRQUMvQyxJQUFJLENBQUMsdUJBQXVCLENBQUMsT0FBTyxJQUFHLElBQUksR0FBRyxJQUFJLENBQUM7UUFFbkQsT0FBTyxJQUFJLENBQUM7SUFDaEIsQ0FBQztJQUVELE1BQU0sQ0FBQyxjQUFjLENBQUMsYUFBcUIsRUFBRSxXQUFtQjtRQUM1RCxPQUFPLElBQUksaUJBQWlCLENBQUMsYUFBYSxFQUFFLEVBQUMsV0FBVyxFQUFDLEVBQUUsaUJBQWlCLENBQUMsQ0FBQztJQUNsRixDQUFDO0lBRUQsTUFBTSxDQUFDLGFBQWEsQ0FBQyxhQUFxQixFQUFFLFdBQW1CO1FBQzNELE9BQU8sSUFBSSxpQkFBaUIsQ0FBQyxhQUFhLEVBQUUsRUFBQyxXQUFXLEVBQUMsRUFBRSxnQkFBZ0IsQ0FBQyxDQUFDO0lBQ2pGLENBQUM7SUFFRCxNQUFNLENBQUMsTUFBTSxDQUFDLElBQWMsRUFBRSxJQUFZLEVBQUUsT0FBZTtRQUN2RCxPQUFPLElBQUksaUJBQWlCLENBQUMsSUFBSSxFQUFFLEVBQUMsSUFBSSxFQUFFLE9BQU8sRUFBQyxFQUFFLFFBQVEsQ0FBQyxDQUFDO0lBQ2xFLENBQUM7Q0FDSjtBQTlCRCw4Q0E4QkMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge0NvbnN0cnVjdH0gZnJvbSBcImNvbnN0cnVjdHNcIjtcbmltcG9ydCB7Q2ZuRG9jdW1lbnRhdGlvblBhcnQsIFJlc291cmNlfSBmcm9tIFwiYXdzLWNkay1saWIvYXdzLWFwaWdhdGV3YXlcIjtcblxuLy8gRG9jdW1lbnRhdGlvbiBwYXJ0cyBhcmUgb2JqZWN0cyB0aGF0IGRlc2NyaWJlIGFuIEFQSSBHYXRld2F5IEFQSSBvciBwYXJ0cyBvZiBhbiBBUElcbi8vIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9hcGlnYXRld2F5L2xhdGVzdC9kZXZlbG9wZXJndWlkZS9hcGktZ2F0ZXdheS1kb2N1bWVudGluZy1hcGkuaHRtbFxuXG4vKipcbiAqIEFkZCBkZXNjcmlwdGlvbiB0byBhIHF1ZXJ5IHBhcmFtZXRlclxuICogQHBhcmFtIG5hbWUgcXVlcnkgcGFyYW1ldGVyIG5hbWVcbiAqIEBwYXJhbSBkZXNjcmlwdGlvbiBxdWVyeSBwYXJhbWV0ZXIgZGVzY3JpcHRpb25cbiAqIEBwYXJhbSByZXNvdXJjZSBSRVNUIEFQSSByZXNvdXJjZVxuICogQHBhcmFtIHN0YWNrIENsb3VkRm9ybWF0aW9uIHN0YWNrXG4gKlxuICogQGRlcHJlY2F0ZWQgVXNlIERpZ2l0cmFmZmljUmVzdEFwaS5kb2N1bWVudFJlc291cmNlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhZGRRdWVyeVBhcmFtZXRlckRlc2NyaXB0aW9uKG5hbWU6IHN0cmluZyxcbiAgICBkZXNjcmlwdGlvbjogc3RyaW5nLFxuICAgIHJlc291cmNlOiBSZXNvdXJjZSxcbiAgICBzdGFjazogQ29uc3RydWN0KSB7XG4gICAgbmV3IENmbkRvY3VtZW50YXRpb25QYXJ0KHN0YWNrLCBgJHtuYW1lfURvY3VtZW50YXRpb25gLCB7XG4gICAgICAgIHJlc3RBcGlJZDogcmVzb3VyY2UuYXBpLnJlc3RBcGlJZCxcbiAgICAgICAgbG9jYXRpb246IHtcbiAgICAgICAgICAgIHR5cGU6ICdRVUVSWV9QQVJBTUVURVInLFxuICAgICAgICAgICAgbmFtZSxcbiAgICAgICAgICAgIHBhdGg6IHJlc291cmNlLnBhdGgsXG4gICAgICAgIH0sXG4gICAgICAgIHByb3BlcnRpZXM6IEpTT04uc3RyaW5naWZ5KHtkZXNjcmlwdGlvbn0pLFxuICAgIH0pO1xufVxuXG4vKipcbiAqIEFkZCBhIGRvY3VtZW50YXRpb24gcGFydCB0byBhIG1ldGhvZFxuICogQHBhcmFtIG1ldGhvZERlc2NyaXB0aW9uXG4gKiBAcGFyYW0gZG9jdW1lbnRhdGlvblByb3BlcnRpZXNcbiAqIEBwYXJhbSByZXNvdXJjZSBSRVNUIEFQSSByZXNvdXJjZVxuICogQHBhcmFtIHN0YWNrIENsb3VkRm9ybWF0aW9uIHN0YWNrXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhZGREb2N1bWVudGF0aW9uKG1ldGhvZERlc2NyaXB0aW9uOiBzdHJpbmcsXG4gICAgZG9jdW1lbnRhdGlvblByb3BlcnRpZXM6IG9iamVjdCxcbiAgICByZXNvdXJjZTogUmVzb3VyY2UsXG4gICAgc3RhY2s6IENvbnN0cnVjdCkge1xuICAgIG5ldyBDZm5Eb2N1bWVudGF0aW9uUGFydChzdGFjaywgYCR7bWV0aG9kRGVzY3JpcHRpb259RG9jdW1lbnRhdGlvbmAsIHtcbiAgICAgICAgcmVzdEFwaUlkOiByZXNvdXJjZS5hcGkucmVzdEFwaUlkLFxuICAgICAgICBsb2NhdGlvbjoge1xuICAgICAgICAgICAgdHlwZTogJ01FVEhPRCcsXG4gICAgICAgICAgICBwYXRoOiByZXNvdXJjZS5wYXRoLFxuICAgICAgICB9LFxuICAgICAgICBwcm9wZXJ0aWVzOiBKU09OLnN0cmluZ2lmeShkb2N1bWVudGF0aW9uUHJvcGVydGllcyksXG4gICAgfSk7XG59XG5cbi8qKlxuICogQWRkcyBPcGVuQVBJIHRhZ3MgdG8gYW4gQVBJIG1ldGhvZFxuICogQHBhcmFtIG1ldGhvZERlc2NyaXB0aW9uIERlc2NyaXB0aW9uIG9mIEFQSSBtZXRob2RcbiAqIEBwYXJhbSB0YWdzIE9wZW5BUEkgdGFnc1xuICogQHBhcmFtIHJlc291cmNlIFJFU1QgQVBJIHJlc291cmNlXG4gKiBAcGFyYW0gc3RhY2sgQ2xvdWRGb3JtYXRpb24gc3RhY2tcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFkZFRhZ3MobWV0aG9kRGVzY3JpcHRpb246IHN0cmluZyxcbiAgICB0YWdzOiBzdHJpbmdbXSxcbiAgICByZXNvdXJjZTogUmVzb3VyY2UsXG4gICAgc3RhY2s6IENvbnN0cnVjdCkge1xuICAgIGFkZERvY3VtZW50YXRpb24obWV0aG9kRGVzY3JpcHRpb24sIHt0YWdzfSwgcmVzb3VyY2UsIHN0YWNrKTtcbn1cblxuLyoqXG4gKiBBZGRzIE9wZW5BUEkgdGFncyBhbmQgYSBtZXRob2Qgc3VtbWFyeSB0byBhbiBBUEkgbWV0aG9kXG4gKlxuICogQGRlcHJlY2F0ZWQgVXNlIERpZ2l0cmFmZmljUmVzdEFwaS5kb2N1bWVudFJlc291cmNlXG4gKlxuICogQHBhcmFtIG1ldGhvZERlc2NyaXB0aW9uIERlc2NyaXB0aW9uIG9mIEFQSSBtZXRob2RcbiAqIEBwYXJhbSB0YWdzIE9wZW5BUEkgdGFnc1xuICogQHBhcmFtIHN1bW1hcnkgT3BlbkFQSSBzdW1tYXJ5XG4gKiBAcGFyYW0gcmVzb3VyY2UgUkVTVCBBUEkgcmVzb3VyY2VcbiAqIEBwYXJhbSBzdGFjayBDbG91ZEZvcm1hdGlvbiBzdGFja1xuICovXG5leHBvcnQgZnVuY3Rpb24gYWRkVGFnc0FuZFN1bW1hcnkoXG4gICAgbWV0aG9kRGVzY3JpcHRpb246IHN0cmluZyxcbiAgICB0YWdzOiBzdHJpbmdbXSxcbiAgICBzdW1tYXJ5OiBzdHJpbmcsXG4gICAgcmVzb3VyY2U6IFJlc291cmNlLFxuICAgIHN0YWNrOiBDb25zdHJ1Y3QsXG4pIHtcbiAgICBhZGREb2N1bWVudGF0aW9uKG1ldGhvZERlc2NyaXB0aW9uLCB7dGFncywgc3VtbWFyeX0sIHJlc291cmNlLCBzdGFjayk7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgRG9jdW1lbnRhdGlvblByb3BlcnRpZXMge1xuICAgIGRlc2NyaXB0aW9uPzogc3RyaW5nXG4gICAgdGFncz86IHN0cmluZ1tdXG4gICAgc3VtbWFyeT86IHN0cmluZ1xuICAgIGRlcHJlY2F0ZWQ/OiBib29sZWFuXG59XG5cbmV4cG9ydCBjbGFzcyBEb2N1bWVudGF0aW9uUGFydCB7XG4gICAgcmVhZG9ubHkgcGFyYW1ldGVyTmFtZTogc3RyaW5nO1xuICAgIHJlYWRvbmx5IHR5cGU6IHN0cmluZztcbiAgICByZWFkb25seSBkb2N1bWVudGF0aW9uUHJvcGVydGllczogRG9jdW1lbnRhdGlvblByb3BlcnRpZXM7XG5cbiAgICBwcml2YXRlIGNvbnN0cnVjdG9yKHBhcmFtZXRlck5hbWU6IHN0cmluZywgZG9jdW1lbnRhdGlvblByb3BlcnRpZXM6IERvY3VtZW50YXRpb25Qcm9wZXJ0aWVzLCB0eXBlOiBzdHJpbmcpIHtcbiAgICAgICAgdGhpcy5wYXJhbWV0ZXJOYW1lID0gcGFyYW1ldGVyTmFtZTtcbiAgICAgICAgdGhpcy5kb2N1bWVudGF0aW9uUHJvcGVydGllcyA9IGRvY3VtZW50YXRpb25Qcm9wZXJ0aWVzO1xuICAgICAgICB0aGlzLnR5cGUgPSB0eXBlO1xuICAgIH1cblxuICAgIGRlcHJlY2F0ZWQobm90ZTogc3RyaW5nKTogRG9jdW1lbnRhdGlvblBhcnQge1xuICAgICAgICAvLyBkZXByZWNhdGVkIGlzIG5vdCBzdXBwb3J0ZWQgQVRNOiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vYXBpZ2F0ZXdheS9sYXRlc3QvZGV2ZWxvcGVyZ3VpZGUvYXBpLWdhdGV3YXkta25vd24taXNzdWVzLmh0bWxcbiAgICAgICAgdGhpcy5kb2N1bWVudGF0aW9uUHJvcGVydGllcy5kZXByZWNhdGVkID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5kb2N1bWVudGF0aW9uUHJvcGVydGllcy5zdW1tYXJ5Kz0gJy4gJyArIG5vdGU7XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgc3RhdGljIHF1ZXJ5UGFyYW1ldGVyKHBhcmFtZXRlck5hbWU6IHN0cmluZywgZGVzY3JpcHRpb246IHN0cmluZykge1xuICAgICAgICByZXR1cm4gbmV3IERvY3VtZW50YXRpb25QYXJ0KHBhcmFtZXRlck5hbWUsIHtkZXNjcmlwdGlvbn0sIFwiUVVFUllfUEFSQU1FVEVSXCIpO1xuICAgIH1cblxuICAgIHN0YXRpYyBwYXRoUGFyYW1ldGVyKHBhcmFtZXRlck5hbWU6IHN0cmluZywgZGVzY3JpcHRpb246IHN0cmluZykge1xuICAgICAgICByZXR1cm4gbmV3IERvY3VtZW50YXRpb25QYXJ0KHBhcmFtZXRlck5hbWUsIHtkZXNjcmlwdGlvbn0sIFwiUEFUSF9QQVJBTUVURVJcIik7XG4gICAgfVxuXG4gICAgc3RhdGljIG1ldGhvZCh0YWdzOiBzdHJpbmdbXSwgbmFtZTogc3RyaW5nLCBzdW1tYXJ5OiBzdHJpbmcpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBEb2N1bWVudGF0aW9uUGFydChuYW1lLCB7dGFncywgc3VtbWFyeX0sIFwiTUVUSE9EXCIpO1xuICAgIH1cbn1cbiJdfQ==
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Scheduler = void 0;
4
+ const aws_events_1 = require("aws-cdk-lib/aws-events");
5
+ const aws_cdk_lib_1 = require("aws-cdk-lib");
6
+ const aws_events_targets_1 = require("aws-cdk-lib/aws-events-targets");
7
+ class Scheduler extends aws_events_1.Rule {
8
+ constructor(stack, ruleName, schedule, lambda) {
9
+ super(stack, ruleName, { ruleName, schedule });
10
+ if (lambda) {
11
+ this.addTarget(new aws_events_targets_1.LambdaFunction(lambda));
12
+ }
13
+ }
14
+ static everyMinute(stack, ruleName, lambda) {
15
+ return Scheduler.every(stack, ruleName, aws_cdk_lib_1.Duration.minutes(1), lambda);
16
+ }
17
+ static everyMinutes(stack, ruleName, minutes, lambda) {
18
+ return Scheduler.every(stack, ruleName, aws_cdk_lib_1.Duration.minutes(minutes), lambda);
19
+ }
20
+ static everyHour(stack, ruleName, lambda) {
21
+ return Scheduler.every(stack, ruleName, aws_cdk_lib_1.Duration.hours(1), lambda);
22
+ }
23
+ static everyDay(stack, ruleName, lambda) {
24
+ return Scheduler.every(stack, ruleName, aws_cdk_lib_1.Duration.days(1), lambda);
25
+ }
26
+ static every(stack, ruleName, duration, lambda) {
27
+ return new Scheduler(stack, ruleName, aws_events_1.Schedule.rate(duration), lambda);
28
+ }
29
+ }
30
+ exports.Scheduler = Scheduler;
31
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2NoZWR1bGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2F3cy9pbmZyYS9zY2hlZHVsZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsdURBQXNEO0FBQ3RELDZDQUFxQztBQUNyQyx1RUFBOEQ7QUFJOUQsTUFBYSxTQUFVLFNBQVEsaUJBQUk7SUFDL0IsWUFBWSxLQUFnQixFQUFFLFFBQWdCLEVBQUUsUUFBa0IsRUFBRSxNQUFpQjtRQUNqRixLQUFLLENBQUMsS0FBSyxFQUFFLFFBQVEsRUFBRSxFQUFFLFFBQVEsRUFBRSxRQUFRLEVBQUUsQ0FBQyxDQUFDO1FBRS9DLElBQUksTUFBTSxFQUFFO1lBQ1IsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLG1DQUFjLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQztTQUM5QztJQUNMLENBQUM7SUFFRCxNQUFNLENBQUMsV0FBVyxDQUFDLEtBQWdCLEVBQUUsUUFBZ0IsRUFBRSxNQUFpQjtRQUNwRSxPQUFPLFNBQVMsQ0FBQyxLQUFLLENBQUMsS0FBSyxFQUFFLFFBQVEsRUFBRSxzQkFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsRUFBRSxNQUFNLENBQUMsQ0FBQztJQUN6RSxDQUFDO0lBRUQsTUFBTSxDQUFDLFlBQVksQ0FBQyxLQUFnQixFQUFFLFFBQWdCLEVBQUUsT0FBZSxFQUFFLE1BQWlCO1FBQ3RGLE9BQU8sU0FBUyxDQUFDLEtBQUssQ0FBQyxLQUFLLEVBQUUsUUFBUSxFQUFFLHNCQUFRLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxFQUFFLE1BQU0sQ0FBQyxDQUFDO0lBQy9FLENBQUM7SUFFRCxNQUFNLENBQUMsU0FBUyxDQUFDLEtBQWdCLEVBQUUsUUFBZ0IsRUFBRSxNQUFpQjtRQUNsRSxPQUFPLFNBQVMsQ0FBQyxLQUFLLENBQUMsS0FBSyxFQUFFLFFBQVEsRUFBRSxzQkFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsRUFBRSxNQUFNLENBQUMsQ0FBQztJQUN2RSxDQUFDO0lBRUQsTUFBTSxDQUFDLFFBQVEsQ0FBQyxLQUFnQixFQUFFLFFBQWdCLEVBQUUsTUFBaUI7UUFDakUsT0FBTyxTQUFTLENBQUMsS0FBSyxDQUFDLEtBQUssRUFBRSxRQUFRLEVBQUUsc0JBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsTUFBTSxDQUFDLENBQUM7SUFDdEUsQ0FBQztJQUVELE1BQU0sQ0FBQyxLQUFLLENBQUMsS0FBZ0IsRUFBRSxRQUFnQixFQUFFLFFBQWtCLEVBQUUsTUFBaUI7UUFDbEYsT0FBTyxJQUFJLFNBQVMsQ0FBQyxLQUFLLEVBQUUsUUFBUSxFQUFFLHFCQUFRLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxFQUFFLE1BQU0sQ0FBQyxDQUFDO0lBQzNFLENBQUM7Q0FDSjtBQTVCRCw4QkE0QkMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1J1bGUsIFNjaGVkdWxlfSBmcm9tIFwiYXdzLWNkay1saWIvYXdzLWV2ZW50c1wiO1xuaW1wb3J0IHtEdXJhdGlvbn0gZnJvbSBcImF3cy1jZGstbGliXCI7XG5pbXBvcnQge0xhbWJkYUZ1bmN0aW9ufSBmcm9tIFwiYXdzLWNkay1saWIvYXdzLWV2ZW50cy10YXJnZXRzXCI7XG5pbXBvcnQge0Z1bmN0aW9ufSBmcm9tICdhd3MtY2RrLWxpYi9hd3MtbGFtYmRhJztcbmltcG9ydCB7Q29uc3RydWN0fSBmcm9tIFwiY29uc3RydWN0c1wiO1xuXG5leHBvcnQgY2xhc3MgU2NoZWR1bGVyIGV4dGVuZHMgUnVsZSB7XG4gICAgY29uc3RydWN0b3Ioc3RhY2s6IENvbnN0cnVjdCwgcnVsZU5hbWU6IHN0cmluZywgc2NoZWR1bGU6IFNjaGVkdWxlLCBsYW1iZGE/OiBGdW5jdGlvbikge1xuICAgICAgICBzdXBlcihzdGFjaywgcnVsZU5hbWUsIHsgcnVsZU5hbWUsIHNjaGVkdWxlIH0pO1xuXG4gICAgICAgIGlmIChsYW1iZGEpIHtcbiAgICAgICAgICAgIHRoaXMuYWRkVGFyZ2V0KG5ldyBMYW1iZGFGdW5jdGlvbihsYW1iZGEpKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHN0YXRpYyBldmVyeU1pbnV0ZShzdGFjazogQ29uc3RydWN0LCBydWxlTmFtZTogc3RyaW5nLCBsYW1iZGE/OiBGdW5jdGlvbikge1xuICAgICAgICByZXR1cm4gU2NoZWR1bGVyLmV2ZXJ5KHN0YWNrLCBydWxlTmFtZSwgRHVyYXRpb24ubWludXRlcygxKSwgbGFtYmRhKTtcbiAgICB9XG5cbiAgICBzdGF0aWMgZXZlcnlNaW51dGVzKHN0YWNrOiBDb25zdHJ1Y3QsIHJ1bGVOYW1lOiBzdHJpbmcsIG1pbnV0ZXM6IG51bWJlciwgbGFtYmRhPzogRnVuY3Rpb24pIHtcbiAgICAgICAgcmV0dXJuIFNjaGVkdWxlci5ldmVyeShzdGFjaywgcnVsZU5hbWUsIER1cmF0aW9uLm1pbnV0ZXMobWludXRlcyksIGxhbWJkYSk7XG4gICAgfVxuXG4gICAgc3RhdGljIGV2ZXJ5SG91cihzdGFjazogQ29uc3RydWN0LCBydWxlTmFtZTogc3RyaW5nLCBsYW1iZGE/OiBGdW5jdGlvbikge1xuICAgICAgICByZXR1cm4gU2NoZWR1bGVyLmV2ZXJ5KHN0YWNrLCBydWxlTmFtZSwgRHVyYXRpb24uaG91cnMoMSksIGxhbWJkYSk7XG4gICAgfVxuXG4gICAgc3RhdGljIGV2ZXJ5RGF5KHN0YWNrOiBDb25zdHJ1Y3QsIHJ1bGVOYW1lOiBzdHJpbmcsIGxhbWJkYT86IEZ1bmN0aW9uKSB7XG4gICAgICAgIHJldHVybiBTY2hlZHVsZXIuZXZlcnkoc3RhY2ssIHJ1bGVOYW1lLCBEdXJhdGlvbi5kYXlzKDEpLCBsYW1iZGEpO1xuICAgIH1cblxuICAgIHN0YXRpYyBldmVyeShzdGFjazogQ29uc3RydWN0LCBydWxlTmFtZTogc3RyaW5nLCBkdXJhdGlvbjogRHVyYXRpb24sIGxhbWJkYT86IEZ1bmN0aW9uKSB7XG4gICAgICAgIHJldHVybiBuZXcgU2NoZWR1bGVyKHN0YWNrLCBydWxlTmFtZSwgU2NoZWR1bGUucmF0ZShkdXJhdGlvbiksIGxhbWJkYSk7XG4gICAgfVxufVxuIl19
@@ -0,0 +1,39 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DigitrafficSecurityRule = void 0;
4
+ const aws_events_1 = require("aws-cdk-lib/aws-events");
5
+ const aws_events_targets_1 = require("aws-cdk-lib/aws-events-targets");
6
+ /**
7
+ * Automatic rule for Security Hub. Send notification to given topic if the following conditions apply:
8
+ * * There is a finding with a status of NEW
9
+ * * It has severity of HIGH or CRITICAL
10
+ * * It is in a FAILED state
11
+ */
12
+ class DigitrafficSecurityRule extends aws_events_1.Rule {
13
+ constructor(scope, topic) {
14
+ const ruleName = 'SecurityHubRule';
15
+ super(scope, ruleName, {
16
+ ruleName,
17
+ eventPattern: {
18
+ source: ['aws.securityhub'],
19
+ detailType: ["Security Hub Findings - Imported"],
20
+ detail: {
21
+ findings: {
22
+ "Compliance": {
23
+ "Status": ["FAILED"],
24
+ },
25
+ "Workflow": {
26
+ "Status": ["NEW"],
27
+ },
28
+ "Severity": {
29
+ "Label": ["HIGH", "CRITICAL"],
30
+ },
31
+ },
32
+ },
33
+ },
34
+ });
35
+ this.addTarget(new aws_events_targets_1.SnsTopic(topic));
36
+ }
37
+ }
38
+ exports.DigitrafficSecurityRule = DigitrafficSecurityRule;
39
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VjdXJpdHktcnVsZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9hd3MvaW5mcmEvc2VjdXJpdHktcnVsZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFDQSx1REFBNEM7QUFFNUMsdUVBQXdEO0FBRXhEOzs7OztHQUtHO0FBQ0gsTUFBYSx1QkFBd0IsU0FBUSxpQkFBSTtJQUM3QyxZQUFZLEtBQWdCLEVBQUUsS0FBYTtRQUN2QyxNQUFNLFFBQVEsR0FBRyxpQkFBaUIsQ0FBQztRQUNuQyxLQUFLLENBQUMsS0FBSyxFQUFFLFFBQVEsRUFBRTtZQUNuQixRQUFRO1lBQ1IsWUFBWSxFQUFFO2dCQUNWLE1BQU0sRUFBRSxDQUFDLGlCQUFpQixDQUFDO2dCQUMzQixVQUFVLEVBQUUsQ0FBQyxrQ0FBa0MsQ0FBQztnQkFDaEQsTUFBTSxFQUFFO29CQUNKLFFBQVEsRUFBRTt3QkFDTixZQUFZLEVBQUU7NEJBQ1YsUUFBUSxFQUFFLENBQUMsUUFBUSxDQUFDO3lCQUN2Qjt3QkFDRCxVQUFVLEVBQUU7NEJBQ1IsUUFBUSxFQUFFLENBQUMsS0FBSyxDQUFDO3lCQUNwQjt3QkFDRCxVQUFVLEVBQUU7NEJBQ1IsT0FBTyxFQUFFLENBQUMsTUFBTSxFQUFFLFVBQVUsQ0FBQzt5QkFDaEM7cUJBQ0o7aUJBQ0o7YUFDSjtTQUNKLENBQUMsQ0FBQztRQUVILElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSw2QkFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUM7SUFDeEMsQ0FBQztDQUNKO0FBMUJELDBEQTBCQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7Q29uc3RydWN0fSBmcm9tIFwiY29uc3RydWN0c1wiO1xuaW1wb3J0IHtSdWxlfSBmcm9tIFwiYXdzLWNkay1saWIvYXdzLWV2ZW50c1wiO1xuaW1wb3J0IHtJVG9waWN9IGZyb20gXCJhd3MtY2RrLWxpYi9hd3Mtc25zXCI7XG5pbXBvcnQge1Nuc1RvcGljfSBmcm9tIFwiYXdzLWNkay1saWIvYXdzLWV2ZW50cy10YXJnZXRzXCI7XG5cbi8qKlxuICogQXV0b21hdGljIHJ1bGUgZm9yIFNlY3VyaXR5IEh1Yi4gIFNlbmQgbm90aWZpY2F0aW9uIHRvIGdpdmVuIHRvcGljIGlmIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcHBseTpcbiAqICogVGhlcmUgaXMgYSBmaW5kaW5nIHdpdGggYSBzdGF0dXMgb2YgTkVXXG4gKiAqIEl0IGhhcyBzZXZlcml0eSBvZiBISUdIIG9yIENSSVRJQ0FMXG4gKiAqIEl0IGlzIGluIGEgRkFJTEVEIHN0YXRlXG4gKi9cbmV4cG9ydCBjbGFzcyBEaWdpdHJhZmZpY1NlY3VyaXR5UnVsZSBleHRlbmRzIFJ1bGUge1xuICAgIGNvbnN0cnVjdG9yKHNjb3BlOiBDb25zdHJ1Y3QsIHRvcGljOiBJVG9waWMpIHtcbiAgICAgICAgY29uc3QgcnVsZU5hbWUgPSAnU2VjdXJpdHlIdWJSdWxlJztcbiAgICAgICAgc3VwZXIoc2NvcGUsIHJ1bGVOYW1lLCB7XG4gICAgICAgICAgICBydWxlTmFtZSxcbiAgICAgICAgICAgIGV2ZW50UGF0dGVybjoge1xuICAgICAgICAgICAgICAgIHNvdXJjZTogWydhd3Muc2VjdXJpdHlodWInXSxcbiAgICAgICAgICAgICAgICBkZXRhaWxUeXBlOiBbXCJTZWN1cml0eSBIdWIgRmluZGluZ3MgLSBJbXBvcnRlZFwiXSxcbiAgICAgICAgICAgICAgICBkZXRhaWw6IHtcbiAgICAgICAgICAgICAgICAgICAgZmluZGluZ3M6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIFwiQ29tcGxpYW5jZVwiOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgXCJTdGF0dXNcIjogW1wiRkFJTEVEXCJdLFxuICAgICAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgICAgIFwiV29ya2Zsb3dcIjoge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwiU3RhdHVzXCI6IFtcIk5FV1wiXSxcbiAgICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgICAgICBcIlNldmVyaXR5XCI6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBcIkxhYmVsXCI6IFtcIkhJR0hcIiwgXCJDUklUSUNBTFwiXSxcbiAgICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuXG4gICAgICAgIHRoaXMuYWRkVGFyZ2V0KG5ldyBTbnNUb3BpYyh0b3BpYykpO1xuICAgIH1cbn1cbiJdfQ==
@@ -0,0 +1,93 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.attachQueueToApiGatewayResource = void 0;
4
+ const aws_cdk_lib_1 = require("aws-cdk-lib");
5
+ const aws_apigateway_1 = require("aws-cdk-lib/aws-apigateway");
6
+ const aws_iam_1 = require("aws-cdk-lib/aws-iam");
7
+ function attachQueueToApiGatewayResource(stack, queue, resource, requestValidator, resourceName, apiKeyRequired, requestModels) {
8
+ // role for API Gateway
9
+ const apiGwRole = new aws_iam_1.Role(stack, `${resourceName}APIGatewayToSQSRole`, {
10
+ assumedBy: new aws_iam_1.ServicePrincipal('apigateway.amazonaws.com'),
11
+ });
12
+ // grants API Gateway the right to send SQS messages
13
+ apiGwRole.addToPolicy(new aws_iam_1.PolicyStatement({
14
+ resources: [
15
+ queue.queueArn,
16
+ ],
17
+ actions: [
18
+ 'sqs:SendMessage',
19
+ ],
20
+ }));
21
+ // grants API Gateway the right write CloudWatch Logs
22
+ apiGwRole.addToPolicy(new aws_iam_1.PolicyStatement({
23
+ resources: [
24
+ '*',
25
+ ],
26
+ actions: [
27
+ 'logs:CreateLogGroup',
28
+ 'logs:CreateLogStream',
29
+ 'logs:DescribeLogGroups',
30
+ 'logs:DescribeLogStreams',
31
+ 'logs:PutLogEvents',
32
+ 'logs:GetLogEvents',
33
+ 'logs:FilterLogEvents',
34
+ ],
35
+ }));
36
+ // create an integration between API Gateway and an SQS queue
37
+ const fifoMessageGroupId = queue.fifo ? '&MessageGroupId=AlwaysSameFifoGroup' : '';
38
+ const sqsIntegration = new aws_apigateway_1.AwsIntegration({
39
+ service: 'sqs',
40
+ integrationHttpMethod: 'POST',
41
+ options: {
42
+ passthroughBehavior: aws_apigateway_1.PassthroughBehavior.NEVER,
43
+ credentialsRole: apiGwRole,
44
+ requestParameters: {
45
+ // SQS requires the Content-Type of the HTTP request to be application/x-www-form-urlencoded
46
+ 'integration.request.header.Content-Type': "'application/x-www-form-urlencoded'",
47
+ },
48
+ requestTemplates: {
49
+ // map the JSON request to a form parameter, FIFO needs also MessageGroupId
50
+ // https://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_SendMessage.html
51
+ 'application/json': `Action=SendMessage${fifoMessageGroupId}&MessageBody=$util.urlEncode($input.body)`,
52
+ },
53
+ // these are required by SQS
54
+ integrationResponses: [
55
+ {
56
+ statusCode: '200',
57
+ responseTemplates: {
58
+ 'text/html': 'Success',
59
+ },
60
+ },
61
+ {
62
+ statusCode: '500',
63
+ responseTemplates: {
64
+ 'text/html': 'Error',
65
+ },
66
+ selectionPattern: '500',
67
+ },
68
+ ],
69
+ },
70
+ path: `${aws_cdk_lib_1.Aws.ACCOUNT_ID}/${queue.queueName}`,
71
+ });
72
+ resource.addMethod('POST', sqsIntegration, {
73
+ requestValidator,
74
+ apiKeyRequired,
75
+ requestModels: requestModels ?? {},
76
+ methodResponses: [
77
+ {
78
+ statusCode: '200',
79
+ responseParameters: {
80
+ 'method.response.header.Content-Type': true,
81
+ },
82
+ },
83
+ {
84
+ statusCode: '500',
85
+ responseParameters: {
86
+ 'method.response.header.Content-Type': true,
87
+ },
88
+ },
89
+ ],
90
+ });
91
+ }
92
+ exports.attachQueueToApiGatewayResource = attachQueueToApiGatewayResource;
93
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3FzLWludGVncmF0aW9uLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2F3cy9pbmZyYS9zcXMtaW50ZWdyYXRpb24udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsNkNBQWdDO0FBQ2hDLCtEQUEyRztBQUUzRyxpREFBNEU7QUFJNUUsU0FBZ0IsK0JBQStCLENBQzNDLEtBQWdCLEVBQ2hCLEtBQVksRUFDWixRQUFrQixFQUNsQixnQkFBa0MsRUFDbEMsWUFBb0IsRUFDcEIsY0FBdUIsRUFDdkIsYUFBeUM7SUFFekMsdUJBQXVCO0lBQ3ZCLE1BQU0sU0FBUyxHQUFHLElBQUksY0FBSSxDQUFDLEtBQUssRUFBRSxHQUFHLFlBQVkscUJBQXFCLEVBQUU7UUFDcEUsU0FBUyxFQUFFLElBQUksMEJBQWdCLENBQUMsMEJBQTBCLENBQUM7S0FDOUQsQ0FBQyxDQUFDO0lBQ0gsb0RBQW9EO0lBQ3BELFNBQVMsQ0FBQyxXQUFXLENBQUMsSUFBSSx5QkFBZSxDQUFDO1FBQ3RDLFNBQVMsRUFBRTtZQUNQLEtBQUssQ0FBQyxRQUFRO1NBQ2pCO1FBQ0QsT0FBTyxFQUFFO1lBQ0wsaUJBQWlCO1NBQ3BCO0tBQ0osQ0FBQyxDQUFDLENBQUM7SUFDSixxREFBcUQ7SUFDckQsU0FBUyxDQUFDLFdBQVcsQ0FBQyxJQUFJLHlCQUFlLENBQUM7UUFDdEMsU0FBUyxFQUFFO1lBQ1AsR0FBRztTQUNOO1FBQ0QsT0FBTyxFQUFFO1lBQ0wscUJBQXFCO1lBQ3JCLHNCQUFzQjtZQUN0Qix3QkFBd0I7WUFDeEIseUJBQXlCO1lBQ3pCLG1CQUFtQjtZQUNuQixtQkFBbUI7WUFDbkIsc0JBQXNCO1NBQ3pCO0tBQ0osQ0FBQyxDQUFDLENBQUM7SUFDSiw2REFBNkQ7SUFDN0QsTUFBTSxrQkFBa0IsR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxxQ0FBcUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO0lBQ25GLE1BQU0sY0FBYyxHQUFHLElBQUksK0JBQWMsQ0FBQztRQUN0QyxPQUFPLEVBQUUsS0FBSztRQUNkLHFCQUFxQixFQUFFLE1BQU07UUFDN0IsT0FBTyxFQUFFO1lBQ0wsbUJBQW1CLEVBQUUsb0NBQW1CLENBQUMsS0FBSztZQUM5QyxlQUFlLEVBQUUsU0FBUztZQUMxQixpQkFBaUIsRUFBRTtnQkFDZiw0RkFBNEY7Z0JBQzVGLHlDQUF5QyxFQUFFLHFDQUFxQzthQUNuRjtZQUNELGdCQUFnQixFQUFFO2dCQUNkLDJFQUEyRTtnQkFDM0UsNkZBQTZGO2dCQUM3RixrQkFBa0IsRUFBRSxxQkFBcUIsa0JBQWtCLDJDQUEyQzthQUN6RztZQUNELDRCQUE0QjtZQUM1QixvQkFBb0IsRUFBRTtnQkFDbEI7b0JBQ0ksVUFBVSxFQUFFLEtBQUs7b0JBQ2pCLGlCQUFpQixFQUFFO3dCQUNmLFdBQVcsRUFBRSxTQUFTO3FCQUN6QjtpQkFDSjtnQkFDRDtvQkFDSSxVQUFVLEVBQUUsS0FBSztvQkFDakIsaUJBQWlCLEVBQUU7d0JBQ2YsV0FBVyxFQUFFLE9BQU87cUJBQ3ZCO29CQUNELGdCQUFnQixFQUFFLEtBQUs7aUJBQzFCO2FBRUo7U0FFSjtRQUNELElBQUksRUFBRSxHQUFHLGlCQUFHLENBQUMsVUFBVSxJQUFJLEtBQUssQ0FBQyxTQUFTLEVBQUU7S0FDL0MsQ0FBQyxDQUFDO0lBQ0gsUUFBUSxDQUFDLFNBQVMsQ0FBQyxNQUFNLEVBQUUsY0FBYyxFQUFFO1FBQ3ZDLGdCQUFnQjtRQUNoQixjQUFjO1FBQ2QsYUFBYSxFQUFFLGFBQWEsSUFBSSxFQUFFO1FBQ2xDLGVBQWUsRUFBRTtZQUNiO2dCQUNJLFVBQVUsRUFBRSxLQUFLO2dCQUNqQixrQkFBa0IsRUFBRTtvQkFDaEIscUNBQXFDLEVBQUUsSUFBSTtpQkFDOUM7YUFDSjtZQUNEO2dCQUNJLFVBQVUsRUFBRSxLQUFLO2dCQUNqQixrQkFBa0IsRUFBRTtvQkFDaEIscUNBQXFDLEVBQUUsSUFBSTtpQkFDOUM7YUFDSjtTQUNKO0tBQ0osQ0FBQyxDQUFDO0FBQ1AsQ0FBQztBQTlGRCwwRUE4RkMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge0F3c30gZnJvbSBcImF3cy1jZGstbGliXCI7XG5pbXBvcnQge0F3c0ludGVncmF0aW9uLCBQYXNzdGhyb3VnaEJlaGF2aW9yLCBSZXF1ZXN0VmFsaWRhdG9yLCBSZXNvdXJjZX0gZnJvbSBcImF3cy1jZGstbGliL2F3cy1hcGlnYXRld2F5XCI7XG5pbXBvcnQge1F1ZXVlfSBmcm9tIFwiYXdzLWNkay1saWIvYXdzLXNxc1wiO1xuaW1wb3J0IHtQb2xpY3lTdGF0ZW1lbnQsIFJvbGUsIFNlcnZpY2VQcmluY2lwYWx9IGZyb20gXCJhd3MtY2RrLWxpYi9hd3MtaWFtXCI7XG5pbXBvcnQge0lNb2RlbH0gZnJvbSBcImF3cy1jZGstbGliL2F3cy1hcGlnYXRld2F5L2xpYi9tb2RlbFwiO1xuaW1wb3J0IHtDb25zdHJ1Y3R9IGZyb20gXCJjb25zdHJ1Y3RzXCI7XG5cbmV4cG9ydCBmdW5jdGlvbiBhdHRhY2hRdWV1ZVRvQXBpR2F0ZXdheVJlc291cmNlKFxuICAgIHN0YWNrOiBDb25zdHJ1Y3QsXG4gICAgcXVldWU6IFF1ZXVlLFxuICAgIHJlc291cmNlOiBSZXNvdXJjZSxcbiAgICByZXF1ZXN0VmFsaWRhdG9yOiBSZXF1ZXN0VmFsaWRhdG9yLFxuICAgIHJlc291cmNlTmFtZTogc3RyaW5nLFxuICAgIGFwaUtleVJlcXVpcmVkOiBib29sZWFuLFxuICAgIHJlcXVlc3RNb2RlbHM/OiB7W3BhcmFtOiBzdHJpbmddOiBJTW9kZWx9LFxuKSB7XG4gICAgLy8gcm9sZSBmb3IgQVBJIEdhdGV3YXlcbiAgICBjb25zdCBhcGlHd1JvbGUgPSBuZXcgUm9sZShzdGFjaywgYCR7cmVzb3VyY2VOYW1lfUFQSUdhdGV3YXlUb1NRU1JvbGVgLCB7XG4gICAgICAgIGFzc3VtZWRCeTogbmV3IFNlcnZpY2VQcmluY2lwYWwoJ2FwaWdhdGV3YXkuYW1hem9uYXdzLmNvbScpLFxuICAgIH0pO1xuICAgIC8vIGdyYW50cyBBUEkgR2F0ZXdheSB0aGUgcmlnaHQgdG8gc2VuZCBTUVMgbWVzc2FnZXNcbiAgICBhcGlHd1JvbGUuYWRkVG9Qb2xpY3kobmV3IFBvbGljeVN0YXRlbWVudCh7XG4gICAgICAgIHJlc291cmNlczogW1xuICAgICAgICAgICAgcXVldWUucXVldWVBcm4sXG4gICAgICAgIF0sXG4gICAgICAgIGFjdGlvbnM6IFtcbiAgICAgICAgICAgICdzcXM6U2VuZE1lc3NhZ2UnLFxuICAgICAgICBdLFxuICAgIH0pKTtcbiAgICAvLyBncmFudHMgQVBJIEdhdGV3YXkgdGhlIHJpZ2h0IHdyaXRlIENsb3VkV2F0Y2ggTG9nc1xuICAgIGFwaUd3Um9sZS5hZGRUb1BvbGljeShuZXcgUG9saWN5U3RhdGVtZW50KHtcbiAgICAgICAgcmVzb3VyY2VzOiBbXG4gICAgICAgICAgICAnKicsXG4gICAgICAgIF0sXG4gICAgICAgIGFjdGlvbnM6IFtcbiAgICAgICAgICAgICdsb2dzOkNyZWF0ZUxvZ0dyb3VwJyxcbiAgICAgICAgICAgICdsb2dzOkNyZWF0ZUxvZ1N0cmVhbScsXG4gICAgICAgICAgICAnbG9nczpEZXNjcmliZUxvZ0dyb3VwcycsXG4gICAgICAgICAgICAnbG9nczpEZXNjcmliZUxvZ1N0cmVhbXMnLFxuICAgICAgICAgICAgJ2xvZ3M6UHV0TG9nRXZlbnRzJyxcbiAgICAgICAgICAgICdsb2dzOkdldExvZ0V2ZW50cycsXG4gICAgICAgICAgICAnbG9nczpGaWx0ZXJMb2dFdmVudHMnLFxuICAgICAgICBdLFxuICAgIH0pKTtcbiAgICAvLyBjcmVhdGUgYW4gaW50ZWdyYXRpb24gYmV0d2VlbiBBUEkgR2F0ZXdheSBhbmQgYW4gU1FTIHF1ZXVlXG4gICAgY29uc3QgZmlmb01lc3NhZ2VHcm91cElkID0gcXVldWUuZmlmbyA/ICcmTWVzc2FnZUdyb3VwSWQ9QWx3YXlzU2FtZUZpZm9Hcm91cCcgOiAnJztcbiAgICBjb25zdCBzcXNJbnRlZ3JhdGlvbiA9IG5ldyBBd3NJbnRlZ3JhdGlvbih7XG4gICAgICAgIHNlcnZpY2U6ICdzcXMnLFxuICAgICAgICBpbnRlZ3JhdGlvbkh0dHBNZXRob2Q6ICdQT1NUJyxcbiAgICAgICAgb3B0aW9uczoge1xuICAgICAgICAgICAgcGFzc3Rocm91Z2hCZWhhdmlvcjogUGFzc3Rocm91Z2hCZWhhdmlvci5ORVZFUixcbiAgICAgICAgICAgIGNyZWRlbnRpYWxzUm9sZTogYXBpR3dSb2xlLFxuICAgICAgICAgICAgcmVxdWVzdFBhcmFtZXRlcnM6IHtcbiAgICAgICAgICAgICAgICAvLyBTUVMgcmVxdWlyZXMgdGhlIENvbnRlbnQtVHlwZSBvZiB0aGUgSFRUUCByZXF1ZXN0IHRvIGJlIGFwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZFxuICAgICAgICAgICAgICAgICdpbnRlZ3JhdGlvbi5yZXF1ZXN0LmhlYWRlci5Db250ZW50LVR5cGUnOiBcIidhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQnXCIsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgcmVxdWVzdFRlbXBsYXRlczoge1xuICAgICAgICAgICAgICAgIC8vIG1hcCB0aGUgSlNPTiByZXF1ZXN0IHRvIGEgZm9ybSBwYXJhbWV0ZXIsIEZJRk8gbmVlZHMgYWxzbyBNZXNzYWdlR3JvdXBJZFxuICAgICAgICAgICAgICAgIC8vIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NTaW1wbGVRdWV1ZVNlcnZpY2UvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfU2VuZE1lc3NhZ2UuaHRtbFxuICAgICAgICAgICAgICAgICdhcHBsaWNhdGlvbi9qc29uJzogYEFjdGlvbj1TZW5kTWVzc2FnZSR7Zmlmb01lc3NhZ2VHcm91cElkfSZNZXNzYWdlQm9keT0kdXRpbC51cmxFbmNvZGUoJGlucHV0LmJvZHkpYCxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAvLyB0aGVzZSBhcmUgcmVxdWlyZWQgYnkgU1FTXG4gICAgICAgICAgICBpbnRlZ3JhdGlvblJlc3BvbnNlczogW1xuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgc3RhdHVzQ29kZTogJzIwMCcsXG4gICAgICAgICAgICAgICAgICAgIHJlc3BvbnNlVGVtcGxhdGVzOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAndGV4dC9odG1sJzogJ1N1Y2Nlc3MnLFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBzdGF0dXNDb2RlOiAnNTAwJyxcbiAgICAgICAgICAgICAgICAgICAgcmVzcG9uc2VUZW1wbGF0ZXM6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICd0ZXh0L2h0bWwnOiAnRXJyb3InLFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICBzZWxlY3Rpb25QYXR0ZXJuOiAnNTAwJyxcbiAgICAgICAgICAgICAgICB9LFxuXG4gICAgICAgICAgICBdLFxuXG4gICAgICAgIH0sXG4gICAgICAgIHBhdGg6IGAke0F3cy5BQ0NPVU5UX0lEfS8ke3F1ZXVlLnF1ZXVlTmFtZX1gLFxuICAgIH0pO1xuICAgIHJlc291cmNlLmFkZE1ldGhvZCgnUE9TVCcsIHNxc0ludGVncmF0aW9uLCB7XG4gICAgICAgIHJlcXVlc3RWYWxpZGF0b3IsXG4gICAgICAgIGFwaUtleVJlcXVpcmVkLFxuICAgICAgICByZXF1ZXN0TW9kZWxzOiByZXF1ZXN0TW9kZWxzID8/IHt9LFxuICAgICAgICBtZXRob2RSZXNwb25zZXM6IFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBzdGF0dXNDb2RlOiAnMjAwJyxcbiAgICAgICAgICAgICAgICByZXNwb25zZVBhcmFtZXRlcnM6IHtcbiAgICAgICAgICAgICAgICAgICAgJ21ldGhvZC5yZXNwb25zZS5oZWFkZXIuQ29udGVudC1UeXBlJzogdHJ1ZSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBzdGF0dXNDb2RlOiAnNTAwJyxcbiAgICAgICAgICAgICAgICByZXNwb25zZVBhcmFtZXRlcnM6IHtcbiAgICAgICAgICAgICAgICAgICAgJ21ldGhvZC5yZXNwb25zZS5oZWFkZXIuQ29udGVudC1UeXBlJzogdHJ1ZSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICB9KTtcbn1cbiJdfQ==