serverless-spy 0.0.36 → 0.0.37

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 (105) hide show
  1. package/.jsii +3 -3
  2. package/cli/cli.ts +145 -75
  3. package/cli/icons/Arch_AWS-Lambda_16.svg +18 -0
  4. package/cli/icons/Arch_Amazon-DynamoDB_16.svg +18 -0
  5. package/cli/icons/Arch_Amazon-EventBridge_16.svg +18 -0
  6. package/cli/icons/Arch_Amazon-Simple-Notification-Service_16.svg +18 -0
  7. package/cli/icons/Arch_Amazon-Simple-Queue-Service_16.svg +18 -0
  8. package/cli/icons/Arch_Amazon-Simple-Storage-Service_16.svg +18 -0
  9. package/cli/index.html +84 -25
  10. package/cli/node_modules/commander/LICENSE +22 -0
  11. package/cli/node_modules/commander/Readme.md +1114 -0
  12. package/cli/node_modules/commander/esm.mjs +16 -0
  13. package/cli/node_modules/commander/index.js +27 -0
  14. package/cli/node_modules/commander/lib/argument.js +147 -0
  15. package/cli/node_modules/commander/lib/command.js +2161 -0
  16. package/cli/node_modules/commander/lib/error.js +45 -0
  17. package/cli/node_modules/commander/lib/help.js +406 -0
  18. package/cli/node_modules/commander/lib/option.js +324 -0
  19. package/cli/node_modules/commander/lib/suggestSimilar.js +100 -0
  20. package/cli/node_modules/commander/package-support.json +16 -0
  21. package/cli/node_modules/commander/package.json +80 -0
  22. package/cli/node_modules/commander/typings/index.d.ts +879 -0
  23. package/cli/package.json +23 -0
  24. package/cli/sampleData.ts +518 -0
  25. package/cli/style.css +66 -42
  26. package/cli/webServerlessSpy.ts +461 -0
  27. package/common/SpyEventSender.ts +291 -0
  28. package/common/getWebSocketUrl.ts +21 -4
  29. package/common/spyEvents/EventBridgeBaseSpyEvent.ts +13 -0
  30. package/common/spyEvents/EventBridgeRuleSpyEvent.ts +2 -7
  31. package/common/spyEvents/EventBridgeSpyEvent.ts +2 -7
  32. package/common/spyEvents/FunctionBaseSpyEvent.ts +7 -0
  33. package/common/spyEvents/FunctionConsole.ts +5 -0
  34. package/common/spyEvents/FunctionConsoleSpyEvent.ts +5 -8
  35. package/common/spyEvents/FunctionResponseSpyEvent.ts +2 -5
  36. package/common/spyEvents/SnsSpyEventBase.ts +11 -0
  37. package/common/spyEvents/SnsSubscriptionSpyEvent.ts +3 -9
  38. package/common/spyEvents/SnsTopicSpyEvent.ts +3 -9
  39. package/dist/releasetag.txt +1 -1
  40. package/extension/interceptor.ts +91 -14
  41. package/functions/sendMessage.ts +4 -2
  42. package/lib/cli/cli.js +124 -65
  43. package/lib/cli/cli.mjs +125 -66
  44. package/lib/cli/sampleData.d.ts +892 -0
  45. package/lib/cli/sampleData.js +481 -0
  46. package/lib/cli/sampleData.mjs +478 -0
  47. package/lib/cli/webServerlessSpy.js +5516 -0
  48. package/lib/cli/webServerlessSpy.js.map +7 -0
  49. package/lib/common/SpyEventSender.d.ts +17 -0
  50. package/lib/common/SpyEventSender.js +227 -0
  51. package/lib/common/SpyEventSender.mjs +223 -0
  52. package/lib/common/getWebSocketUrl.d.ts +1 -1
  53. package/lib/common/getWebSocketUrl.js +19 -7
  54. package/lib/common/getWebSocketUrl.mjs +17 -5
  55. package/lib/common/spyEvents/EventBridgeBaseSpyEvent.d.ts +9 -0
  56. package/lib/common/spyEvents/EventBridgeBaseSpyEvent.js +3 -0
  57. package/lib/common/spyEvents/EventBridgeBaseSpyEvent.mjs +2 -0
  58. package/lib/common/spyEvents/EventBridgeRuleSpyEvent.d.ts +2 -7
  59. package/lib/common/spyEvents/EventBridgeRuleSpyEvent.js +1 -1
  60. package/lib/common/spyEvents/EventBridgeRuleSpyEvent.mjs +1 -1
  61. package/lib/common/spyEvents/EventBridgeSpyEvent.d.ts +2 -7
  62. package/lib/common/spyEvents/EventBridgeSpyEvent.js +1 -1
  63. package/lib/common/spyEvents/EventBridgeSpyEvent.mjs +1 -1
  64. package/lib/common/spyEvents/FunctionBaseSpyEvent.d.ts +6 -0
  65. package/lib/common/spyEvents/FunctionBaseSpyEvent.js +3 -0
  66. package/lib/common/spyEvents/FunctionBaseSpyEvent.mjs +2 -0
  67. package/lib/common/spyEvents/FunctionConsole.d.ts +5 -0
  68. package/lib/common/spyEvents/FunctionConsole.js +3 -0
  69. package/lib/common/spyEvents/FunctionConsole.mjs +2 -0
  70. package/lib/common/spyEvents/FunctionConsoleSpyEvent.d.ts +4 -8
  71. package/lib/common/spyEvents/FunctionConsoleSpyEvent.js +1 -1
  72. package/lib/common/spyEvents/FunctionConsoleSpyEvent.mjs +1 -1
  73. package/lib/common/spyEvents/FunctionResponseSpyEvent.d.ts +2 -5
  74. package/lib/common/spyEvents/FunctionResponseSpyEvent.js +1 -1
  75. package/lib/common/spyEvents/FunctionResponseSpyEvent.mjs +1 -1
  76. package/lib/common/spyEvents/SnsSpyEventBase.d.ts +10 -0
  77. package/lib/common/spyEvents/SnsSpyEventBase.js +3 -0
  78. package/lib/common/spyEvents/SnsSpyEventBase.mjs +2 -0
  79. package/lib/common/spyEvents/SnsSubscriptionSpyEvent.d.ts +2 -9
  80. package/lib/common/spyEvents/SnsSubscriptionSpyEvent.js +1 -1
  81. package/lib/common/spyEvents/SnsSubscriptionSpyEvent.mjs +1 -1
  82. package/lib/common/spyEvents/SnsTopicSpyEvent.d.ts +2 -9
  83. package/lib/common/spyEvents/SnsTopicSpyEvent.js +1 -1
  84. package/lib/common/spyEvents/SnsTopicSpyEvent.mjs +1 -1
  85. package/lib/extension/dist/layer/nodejs/node_modules/interceptor.js +251 -181
  86. package/lib/extension/dist/layer/nodejs/node_modules/interceptor.js.map +3 -3
  87. package/lib/listener/SpyHandlers.ts.d.ts +30 -2
  88. package/lib/listener/SpyHandlers.ts.js +1 -1
  89. package/lib/listener/SpyHandlers.ts.mjs +1 -1
  90. package/lib/listener/WsListener.js +11 -11
  91. package/lib/listener/WsListener.mjs +12 -12
  92. package/lib/src/ServerlessSpy.js +2 -3
  93. package/lib/src/ServerlessSpy.mjs +1 -2
  94. package/listener/SpyHandlers.ts.ts +70 -9
  95. package/listener/WsListener.ts +21 -18
  96. package/package.json +5 -3
  97. package/cli/serverlessSpy.js +0 -73
  98. package/cli/ws.ts +0 -79
  99. package/common/publishSpyEvent.ts +0 -269
  100. package/lib/cli/ws.d.ts +0 -1
  101. package/lib/cli/ws.js +0 -68
  102. package/lib/cli/ws.mjs +0 -66
  103. package/lib/common/publishSpyEvent.d.ts +0 -4
  104. package/lib/common/publishSpyEvent.js +0 -211
  105. package/lib/common/publishSpyEvent.mjs +0 -205
@@ -0,0 +1,17 @@
1
+ import { ApiGatewayManagementApi } from '@aws-sdk/client-apigatewaymanagementapi';
2
+ import { AttributeValue, DynamoDBClient } from '@aws-sdk/client-dynamodb';
3
+ export declare class SpyEventSender {
4
+ ddb: DynamoDBClient;
5
+ debugMode: boolean;
6
+ apigwManagementApi: ApiGatewayManagementApi;
7
+ connections: Record<string, AttributeValue>[] | undefined;
8
+ constructor(params?: {
9
+ log: (message: string, ...optionalParams: any[]) => void;
10
+ logError: (message: string, ...optionalParams: any[]) => void;
11
+ });
12
+ publishSpyEvent(event: any): Promise<void>;
13
+ private postData;
14
+ private getSpyEventType;
15
+ private log;
16
+ private logError;
17
+ }
@@ -0,0 +1,227 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SpyEventSender = void 0;
4
+ const client_apigatewaymanagementapi_1 = require("@aws-sdk/client-apigatewaymanagementapi");
5
+ const client_dynamodb_1 = require("@aws-sdk/client-dynamodb");
6
+ const util_dynamodb_1 = require("@aws-sdk/util-dynamodb");
7
+ const envVariableNames_1 = require("../src/common/envVariableNames");
8
+ class SpyEventSender {
9
+ constructor(params) {
10
+ this.ddb = new client_dynamodb_1.DynamoDBClient({
11
+ region: process.env.AWS_REGION,
12
+ });
13
+ this.debugMode = process.env[envVariableNames_1.envVariableNames.SSPY_DEBUG] === 'true';
14
+ this.apigwManagementApi = new client_apigatewaymanagementapi_1.ApiGatewayManagementApi({
15
+ apiVersion: '2018-11-29',
16
+ endpoint: process.env[envVariableNames_1.envVariableNames.SSPY_WS_ENDPOINT],
17
+ });
18
+ if (params?.log) {
19
+ this.log = params.log;
20
+ }
21
+ if (params?.logError) {
22
+ this.logError = params.logError;
23
+ }
24
+ }
25
+ async publishSpyEvent(event) {
26
+ this.log('Event', JSON.stringify(event));
27
+ const mapping = JSON.parse(process.env[envVariableNames_1.envVariableNames.SSPY_INFRA_MAPPING]);
28
+ this.log('ARN to names mapping', JSON.stringify(mapping));
29
+ let connectionData;
30
+ const scanParams = new client_dynamodb_1.ScanCommand({
31
+ TableName: process.env[envVariableNames_1.envVariableNames.SSPY_WS_TABLE_NAME],
32
+ ProjectionExpression: 'connectionId',
33
+ });
34
+ connectionData = await this.ddb.send(scanParams);
35
+ this.connections = connectionData.Items;
36
+ const postDataPromises = [];
37
+ if (event?.Records && event.Records[0]?.Sns) {
38
+ //console.log('*** SNS ***');
39
+ const eventSns = event;
40
+ for (const record of eventSns.Records) {
41
+ const subscriptionArn = record.EventSubscriptionArn;
42
+ let serviceKey;
43
+ if (mapping[subscriptionArn]) {
44
+ // subscription event that could contain filter based on existing subscription
45
+ serviceKey = mapping[subscriptionArn];
46
+ }
47
+ else {
48
+ // catch all subscription
49
+ const topicArn = record.Sns.TopicArn;
50
+ serviceKey = mapping[topicArn];
51
+ }
52
+ let message;
53
+ try {
54
+ message = JSON.parse(record.Sns.Message);
55
+ }
56
+ catch {
57
+ message = record.Sns.Message;
58
+ }
59
+ const spyEventType = this.getSpyEventType(serviceKey);
60
+ const data = {
61
+ spyEventType,
62
+ message,
63
+ subject: record.Sns.Subject,
64
+ timestamp: record.Sns.Timestamp,
65
+ topicArn: record.Sns.TopicArn,
66
+ messageId: record.Sns.MessageId,
67
+ messageAttributes: record.Sns.MessageAttributes,
68
+ };
69
+ const fluentEvent = {
70
+ data,
71
+ serviceKey,
72
+ };
73
+ postDataPromises.push(this.postData(fluentEvent));
74
+ }
75
+ }
76
+ else if (event?.Records && event.Records[0]?.eventSource === 'aws:sqs') {
77
+ //console.log('*** SQS ***');
78
+ const eventSqs = event;
79
+ for (const record of eventSqs.Records) {
80
+ const subscriptionArn = record.eventSourceARN;
81
+ const serviceKey = mapping[subscriptionArn];
82
+ let body;
83
+ try {
84
+ body = JSON.parse(record.body);
85
+ }
86
+ catch {
87
+ body = record.body;
88
+ }
89
+ const data = {
90
+ spyEventType: 'Sqs',
91
+ body,
92
+ messageAttributes: record.messageAttributes,
93
+ };
94
+ const fluentEvent = {
95
+ data,
96
+ serviceKey,
97
+ };
98
+ postDataPromises.push(this.postData(fluentEvent));
99
+ }
100
+ }
101
+ else if (event?.Records && event.Records[0]?.s3) {
102
+ //console.log('*** S3 ***');
103
+ const eventS3 = event;
104
+ for (const record of eventS3.Records) {
105
+ const bucketArn = record.s3.bucket.arn;
106
+ const data = {
107
+ spyEventType: 'S3',
108
+ eventName: record.eventName,
109
+ eventTime: record.eventTime,
110
+ bucket: record.s3.bucket.name,
111
+ key: record.s3.object.key,
112
+ };
113
+ const fluentEvent = {
114
+ data,
115
+ serviceKey: mapping[bucketArn],
116
+ };
117
+ postDataPromises.push(this.postData(fluentEvent));
118
+ }
119
+ }
120
+ else if (event.Records && event.Records[0]?.dynamodb) {
121
+ //console.log('*** DYNAMODB ***');
122
+ const eventDynamoDB = event;
123
+ for (const record of eventDynamoDB.Records) {
124
+ let arn = record.eventSourceARN;
125
+ arn = arn.substring(0, arn.indexOf('/stream/'));
126
+ const data = {
127
+ spyEventType: 'DynamoDB',
128
+ eventName: record.eventName,
129
+ newImage: (0, util_dynamodb_1.unmarshall)(record.dynamodb?.NewImage),
130
+ keys: (0, util_dynamodb_1.unmarshall)(record.dynamodb?.Keys),
131
+ oldImage: record.dynamodb?.OldImage
132
+ ? (0, util_dynamodb_1.unmarshall)(record.dynamodb?.OldImage)
133
+ : undefined,
134
+ };
135
+ const fluentEvent = {
136
+ data,
137
+ serviceKey: mapping[arn],
138
+ };
139
+ postDataPromises.push(this.postData(fluentEvent));
140
+ }
141
+ }
142
+ else if (event.detail &&
143
+ event['detail-type'] &&
144
+ event.version &&
145
+ event.source) {
146
+ //console.log('*** EventBridge ***');
147
+ const eventEb = event;
148
+ const serviceKey = mapping.eventBridge; // the is new lambda for each subscription
149
+ const spyEventType = this.getSpyEventType(serviceKey);
150
+ const message = eventEb.detail;
151
+ const data = {
152
+ spyEventType,
153
+ detail: message,
154
+ detailType: eventEb['detail-type'],
155
+ eventBridgeId: eventEb['id'],
156
+ source: eventEb.source,
157
+ time: eventEb.time,
158
+ account: eventEb.account,
159
+ };
160
+ const fluentEvent = {
161
+ data,
162
+ serviceKey,
163
+ };
164
+ postDataPromises.push(this.postData(fluentEvent));
165
+ }
166
+ else {
167
+ //console.log('*** OTHER ***');
168
+ const fluentEvent = event;
169
+ postDataPromises.push(this.postData(fluentEvent));
170
+ }
171
+ await Promise.all(postDataPromises);
172
+ }
173
+ async postData(spyMessage) {
174
+ this.log('Post spy message', JSON.stringify(spyMessage));
175
+ if (!this.connections) {
176
+ return;
177
+ }
178
+ const postCalls = this.connections.map(async ({ connectionId }) => {
179
+ this.log(`Sending message to client: ${connectionId.S}`);
180
+ try {
181
+ const postToConnectionCommand = new client_apigatewaymanagementapi_1.PostToConnectionCommand({
182
+ ConnectionId: connectionId.S,
183
+ Data: JSON.stringify({
184
+ timestamp: new Date().toISOString(),
185
+ serviceKey: spyMessage.serviceKey,
186
+ data: spyMessage.data,
187
+ }),
188
+ });
189
+ await this.apigwManagementApi.send(postToConnectionCommand);
190
+ }
191
+ catch (e) {
192
+ this.logError(`Faild sending spy message to: ${connectionId.S}`, e);
193
+ if (e.$metadata.httpStatusCode === 410) {
194
+ this.log(`Found stale connection, deleting ${connectionId}`);
195
+ const deleteParams = new client_dynamodb_1.DeleteItemCommand({
196
+ TableName: process.env[envVariableNames_1.envVariableNames.SSPY_WS_TABLE_NAME],
197
+ Key: { connectionId },
198
+ });
199
+ await this.ddb.send(deleteParams);
200
+ }
201
+ else {
202
+ throw e;
203
+ }
204
+ }
205
+ });
206
+ await Promise.all(postCalls);
207
+ this.log('Send spy message finish');
208
+ }
209
+ getSpyEventType(serviceKey) {
210
+ if (!serviceKey) {
211
+ throw new Error('Missing serviceKey');
212
+ }
213
+ return serviceKey.substring(0, serviceKey.indexOf('#'));
214
+ }
215
+ log(message, ...optionalParams) {
216
+ if (this.debugMode) {
217
+ console.debug('SSPY EXTENSION', message, ...optionalParams);
218
+ }
219
+ }
220
+ logError(message, ...optionalParams) {
221
+ if (this.debugMode) {
222
+ console.error('SSPY EXTENSION', message, ...optionalParams);
223
+ }
224
+ }
225
+ }
226
+ exports.SpyEventSender = SpyEventSender;
227
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiU3B5RXZlbnRTZW5kZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9jb21tb24vU3B5RXZlbnRTZW5kZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsNEZBR2lEO0FBQ2pELDhEQUtrQztBQUVsQywwREFBb0Q7QUFRcEQscUVBQWtFO0FBVWxFLE1BQWEsY0FBYztJQVd6QixZQUFZLE1BR1g7UUFiRCxRQUFHLEdBQUcsSUFBSSxnQ0FBYyxDQUFDO1lBQ3ZCLE1BQU0sRUFBRSxPQUFPLENBQUMsR0FBRyxDQUFDLFVBQVU7U0FDL0IsQ0FBQyxDQUFDO1FBQ0gsY0FBUyxHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMsbUNBQWdCLENBQUMsVUFBVSxDQUFDLEtBQUssTUFBTSxDQUFDO1FBQ2hFLHVCQUFrQixHQUFHLElBQUksd0RBQXVCLENBQUM7WUFDL0MsVUFBVSxFQUFFLFlBQVk7WUFDeEIsUUFBUSxFQUFFLE9BQU8sQ0FBQyxHQUFHLENBQUMsbUNBQWdCLENBQUMsZ0JBQWdCLENBQUU7U0FDMUQsQ0FBQyxDQUFDO1FBT0QsSUFBSSxNQUFNLEVBQUUsR0FBRyxFQUFFO1lBQ2YsSUFBSSxDQUFDLEdBQUcsR0FBRyxNQUFNLENBQUMsR0FBRyxDQUFDO1NBQ3ZCO1FBRUQsSUFBSSxNQUFNLEVBQUUsUUFBUSxFQUFFO1lBQ3BCLElBQUksQ0FBQyxRQUFRLEdBQUcsTUFBTSxDQUFDLFFBQVEsQ0FBQztTQUNqQztJQUNILENBQUM7SUFFTSxLQUFLLENBQUMsZUFBZSxDQUFDLEtBQVU7UUFDckMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxPQUFPLEVBQUUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO1FBRXpDLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQ3hCLE9BQU8sQ0FBQyxHQUFHLENBQUMsbUNBQWdCLENBQUMsa0JBQWtCLENBQUUsQ0FDbEQsQ0FBQztRQUNGLElBQUksQ0FBQyxHQUFHLENB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QU07b0JBQ0wsTUFBTSxDQUFDLENBQUM7aUJBQ1Q7YUFDRjtRQUNILENBQUMsQ0FBQyxDQUFDO1FBRUgsTUFBTSxPQUFPLENBQUMsR0FBRyxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBQzdCLElBQUksQ0FBQyxHQUFHLENBQUMseUJBQXlCLENBQUMsQ0FBQztJQUN0QyxDQUFDO0lBRU8sZUFBZSxDQUFDLFVBQWtCO1FBQ3hDLElBQUksQ0FBQyxVQUFVLEVBQUU7WUFDZixNQUFNLElBQUksS0FBSyxDQUFDLG9CQUFvQixDQUFDLENBQUM7U0FDdkM7UUFFRCxPQUFPLFVBQVUsQ0FBQyxTQUFTLENBQUMsQ0FBQyxFQUFFLFVBQVUsQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztJQUMxRCxDQUFDO0lBRU8sR0FBRyxDQUFDLE9BQWUsRUFBRSxHQUFHLGNBQXFCO1FBQ25ELElBQUksSUFBSSxDQUFDLFNBQVMsRUFBRTtZQUNsQixPQUFPLENBQUMsS0FBSyxDQUFDLGdCQUFnQixFQUFFLE9BQU8sRUFBRSxHQUFHLGNBQWMsQ0FBQyxDQUFDO1NBQzdEO0lBQ0gsQ0FBQztJQUVPLFFBQVEsQ0FBQyxPQUFlLEVBQUUsR0FBRyxjQUFxQjtRQUN4RCxJQUFJLElBQUksQ0FBQyxTQUFTLEVBQUU7WUFDbEIsT0FBTyxDQUFDLEtBQUssQ0FBQyxnQkFBZ0IsRUFBRSxPQUFPLEVBQUUsR0FBRyxjQUFjLENBQUMsQ0FBQztTQUM3RDtJQUNILENBQUM7Q0FDRjtBQXJRRCx3Q0FxUUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBBcGlHYXRld2F5TWFuYWdlbWVudEFwaSxcbiAgUG9zdFRvQ29ubmVjdGlvbkNvbW1hbmQsXG59IGZyb20gJ0Bhd3Mtc2RrL2NsaWVudC1hcGlnYXRld2F5bWFuYWdlbWVudGFwaSc7XG5pbXBvcnQge1xuICBBdHRyaWJ1dGVWYWx1ZSxcbiAgRGVsZXRlSXRlbUNvbW1hbmQsXG4gIER5bmFtb0RCQ2xpZW50LFxuICBTY2FuQ29tbWFuZCxcbn0gZnJvbSAnQGF3cy1zZGsvY2xpZW50LWR5bmFtb2RiJztcblxuaW1wb3J0IHsgdW5tYXJzaGFsbCB9IGZyb20gJ0Bhd3Mtc2RrL3V0aWwtZHluYW1vZGInO1xuaW1wb3J0IHtcbiAgRHluYW1vREJTdHJlYW1FdmVudCxcbiAgUzNFdmVudCxcbiAgU05TRXZlbnQsXG4gIEV2ZW50QnJpZGdlRXZlbnQsXG4gIFNRU0V2ZW50LFxufSBmcm9tICdhd3MtbGFtYmRhJztcbmltcG9ydCB7IGVudlZhcmlhYmxlTmFtZXMgfSBmcm9tICcuLi9zcmMvY29tbW9uL2VudlZhcmlhYmxlTmFtZXMnO1xuaW1wb3J0IHsgRHluYW1vREJTcHlFdmVudCB9IGZyb20gJy4vc3B5RXZlbnRzL0R5bmFtb0RCU3B5RXZlbnQnO1xuaW1wb3J0IHsgRXZlbnRCcmlkZ2VSdWxlU3B5RXZlbnQgfSBmcm9tICcuL3NweUV2ZW50cy9FdmVudEJyaWRnZVJ1bGVTcHlFdmVudCc7XG5pbXBvcnQgeyBFdmVudEJyaWRnZVNweUV2ZW50IH0gZnJvbSAnLi9zcHlFdmVudHMvRXZlbnRCcmlkZ2VTcHlFdmVudCc7XG5pbXBvcnQgeyBTM1NweUV2ZW50IH0gZnJvbSAnLi9zcHlFdmVudHMvUzNTcHlFdmVudCc7XG5pbXBvcnQgeyBTbnNTdWJzY3JpcHRpb25TcHlFdmVudCB9IGZyb20gJy4vc3B5RXZlbnRzL1Nuc1N1YnNjcmlwdGlvblNweUV2ZW50JztcbmltcG9ydCB7IFNuc1RvcGljU3B5RXZlbnQgfSBmcm9tICcuL3NweUV2ZW50cy9TbnNUb3BpY1NweUV2ZW50JztcbmltcG9ydCB7IFNweU1lc3NhZ2UgfSBmcm9tICcuL3NweUV2ZW50cy9TcHlNZXNzYWdlJztcbmltcG9ydCB7IFNxc1NweUV2ZW50IH0gZnJvbSAnLi9zcHlFdmVudHMvU3FzU3B5RXZlbnQnO1xuXG5leHBvcnQgY2xhc3MgU3B5RXZlbnRTZW5kZXIge1xuICBkZGIgPSBuZXcgRHluYW1vREJDbGllbnQoe1xuICAgIHJlZ2lvbjogcHJvY2Vzcy5lbnYuQVdTX1JFR0lPTixcbiAgfSk7XG4gIGRlYnVnTW9kZSA9IHByb2Nlc3MuZW52W2VudlZhcmlhYmxlTmFtZXMuU1NQWV9ERUJVR10gPT09ICd0cnVlJztcbiAgYXBpZ3dNYW5hZ2VtZW50QXBpID0gbmV3IEFwaUdhdGV3YXlNYW5hZ2VtZW50QXBpKHtcbiAgICBhcGlWZXJzaW9uOiAnMjAxOC0xMS0yOScsXG4gICAgZW5kcG9pbnQ6IHByb2Nlc3MuZW52W2VudlZhcmlhYmxlTmFtZXMuU1NQWV9XU19FTkRQT0lOVF0hLFxuICB9KTtcbiAgY29ubmVjdGlvbnM6IFJlY29yZDxzdHJpbmcsIEF0dHJpYnV0ZVZhbHVlPltdIHwgdW5kZWZpbmVkO1xuXG4gIGNvbnN0cnVjdG9yKHBhcmFtcz86IHtcbiAgICBsb2c6IChtZXNzYWdlOiBzdHJpbmcsIC4uLm9wdGlvbmFsUGFyYW1zOiBhbnlbXSkgPT4gdm9pZDtcbiAgICBsb2dFcnJvcjogKG1lc3NhZ2U6IHN0cmluZywgLi4ub3B0aW9uYWxQYXJhbXM6IGFueVtdKSA9PiB2b2lkO1xuICB9KSB7XG4gICAgaWYgKHBhcmFtcz8ubG9nKSB7XG4gICAgICB0aGlzLmxvZyA9IHBhcmFtcy5sb2c7XG4gICAgfVxuXG4gICAgaWYgKHBhcmFtcz8ubG9nRXJyb3IpIHtcbiAgICAgIHRoaXMubG9nRXJyb3IgPSBwYXJhbXMubG9nRXJyb3I7XG4gICAgfVxuICB9XG5cbiAgcHVibGljIGFzeW5jIHB1Ymxpc2hTcHlFdmVudChldmVudDogYW55KSB7XG4gICAgdGhpcy5sb2coJ0V2ZW50JywgSlNPTi5zdHJpbmdpZnkoZXZlbnQpKTtcblxuICAgIGNvbnN0IG1hcHBpbmcgPSBKU09OLnBhcnNlKFxuICAgICAgcHJvY2Vzcy5lbnZbZW52VmFyaWFibGVOYW1lcy5TU1BZX0lORlJBX01BUFBJTkddIVxuICAgICk7XG4gICAgdGhpcy5sb2coJ0FSTiB0byBuYW1lcyBtYXBwaW5nJywgSlNPTi5zdHJpbmdpZnkobWFwcGluZykpO1xuXG4gICAgbGV0IGNvbm5lY3Rpb25EYXRhO1xuXG4gICAgY29uc3Qgc2NhblBhcmFtcyA9IG5ldyBTY2FuQ29tbWFuZCh7XG4gICAgICBUYWJsZU5hbWU6IHByb2Nlc3MuZW52W2VudlZhcmlhYmxlTmFtZXMuU1NQWV9XU19UQUJMRV9OQU1FXSBhcyBzdHJpbmcsXG4gICAgICBQcm9qZWN0aW9uRXhwcmVzc2lvbjogJ2Nvbm5lY3Rpb25JZCcsXG4gICAgfSk7XG5cbiAgICBjb25uZWN0aW9uRGF0YSA9IGF3YWl0IHRoaXMuZGRiLnNlbmQoc2NhblBhcmFtcyk7XG5cbiAgICB0aGlzLmNvbm5lY3Rpb25zID0gY29ubmVjdGlvbkRhdGEuSXRlbXM7XG5cbiAgICBjb25zdCBwb3N0RGF0YVByb21pc2VzOiBQcm9taXNlPGFueT5bXSA9IFtdO1xuXG4gICAgaWYgKGV2ZW50Py5SZWNvcmRzICYmIGV2ZW50LlJlY29yZHNbMF0/LlNucykge1xuICAgICAgLy9jb25zb2xlLmxvZygnKioqIFNOUyAqKionKTtcbiAgICAgIGNvbnN0IGV2ZW50U25zID0gZXZlbnQgYXMgU05TRXZlbnQ7XG4gICAgICBmb3IgKGNvbnN0IHJlY29yZCBvZiBldmVudFNucy5SZWNvcmRzKSB7XG4gICAgICAgIGNvbnN0IHN1YnNjcmlwdGlvbkFybiA9IHJlY29yZC5FdmVudFN1YnNjcmlwdGlvbkFybjtcblxuICAgICAgICBsZXQgc2VydmljZUtleTogc3RyaW5nO1xuICAgICAgICBpZiAobWFwcGluZ1tzdWJzY3JpcHRpb25Bcm5dKSB7XG4gICAgICAgICAgLy8gc3Vic2NyaXB0aW9uIGV2ZW50IHRoYXQgY291bGQgY29udGFpbiBmaWx0ZXIgYmFzZWQgb24gZXhpc3Rpbmcgc3Vic2NyaXB0aW9uXG4gICAgICAgICAgc2VydmljZUtleSA9IG1hcHBpbmdbc3Vic2NyaXB0aW9uQXJuXTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAvLyBjYXRjaCBhbGwgc3Vic2NyaXB0aW9uXG4gICAgICAgICAgY29uc3QgdG9waWNBcm4gPSByZWNvcmQuU25zLlRvcGljQXJuO1xuICAgICAgICAgIHNlcnZpY2VLZXkgPSBtYXBwaW5nW3RvcGljQXJuXTtcbiAgICAgICAgfVxuXG4gICAgICAgIGxldCBtZXNzYWdlOiBzdHJpbmc7XG5cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBtZXNzYWdlID0gSlNPTi5wYXJzZShyZWNvcmQuU25zLk1lc3NhZ2UpO1xuICAgICAgICB9IGNhdGNoIHtcbiAgICAgICAgICBtZXNzYWdlID0gcmVjb3JkLlNucy5NZXNzYWdlO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3Qgc3B5RXZlbnRUeXBlID0gdGhpcy5nZXRTcHlFdmVudFR5cGUoc2VydmljZUtleSkgYXNcbiAgICAgICAgICB8ICdGdW5jdGlvblNuc1RvcGljJ1xuICAgICAgICAgIHwgJ0Z1bmN0aW9uU25zU3Vic2NyaXB0aW9uJztcblxuICAgICAgICBjb25zdCBkYXRhOiBTbnNUb3BpY1NweUV2ZW50IHwgU25zU3Vic2NyaXB0aW9uU3B5RXZlbnQgPSB7XG4gICAgICAgICAgc3B5RXZlbnRUeXBlLFxuICAgICAgICAgIG1lc3NhZ2UsXG4gICAgICAgICAgc3ViamVjdDogcmVjb3JkLlNucy5TdWJqZWN0LFxuICAgICAgICAgIHRpbWVzdGFtcDogcmVjb3JkLlNucy5UaW1lc3RhbXAsXG4gICAgICAgICAgdG9waWNBcm46IHJlY29yZC5TbnMuVG9waWNBcm4sXG4gICAgICAgICAgbWVzc2FnZUlkOiByZWNvcmQuU25zLk1lc3NhZ2VJZCxcbiAgICAgICAgICBtZXNzYWdlQXR0cmlidXRlczogcmVjb3JkLlNucy5NZXNzYWdlQXR0cmlidXRlcyxcbiAgICAgICAgfTtcblxuICAgICAgICBjb25zdCBmbHVlbnRFdmVudDogT21pdDxTcHlNZXNzYWdlLCAndGltZXN0YW1wJz4gPSB7XG4gICAgICAgICAgZGF0YSxcbiAgICAgICAgICBzZXJ2aWNlS2V5LFxuICAgICAgICB9O1xuICAgICAgICBwb3N0RGF0YVByb21pc2VzLnB1c2godGhpcy5wb3N0RGF0YShmbHVlbnRFdmVudCkpO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoZXZlbnQ/LlJlY29yZHMgJiYgZXZlbnQuUmVjb3Jkc1swXT8uZXZlbnRTb3VyY2UgPT09ICdhd3M6c3FzJykge1xuICAgICAgLy9jb25zb2xlLmxvZygnKioqIFNRUyAqKionKTtcbiAgICAgIGNvbnN0IGV2ZW50U3FzID0gZXZlbnQgYXMgU1FTRXZlbnQ7XG4gICAgICBmb3IgKGNvbnN0IHJlY29yZCBvZiBldmVudFNxcy5SZWNvcmRzKSB7XG4gICAgICAgIGNvbnN0IHN1YnNjcmlwdGlvbkFybiA9IHJlY29yZC5ldmVudFNvdXJjZUFSTjtcblxuICAgICAgICBjb25zdCBzZXJ2aWNlS2V5ID0gbWFwcGluZ1tzdWJzY3JpcHRpb25Bcm5dO1xuICAgICAgICBsZXQgYm9keTogc3RyaW5nO1xuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgYm9keSA9IEpTT04ucGFyc2UocmVjb3JkLmJvZHkpO1xuICAgICAgICB9IGNhdGNoIHtcbiAgICAgICAgICBib2R5ID0gcmVjb3JkLmJvZHk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBkYXRhOiBTcXNTcHlFdmVudCA9IHtcbiAgICAgICAgICBzcHlFdmVudFR5cGU6ICdTcXMnLFxuICAgICAgICAgIGJvZHksXG4gICAgICAgICAgbWVzc2FnZUF0dHJpYnV0ZXM6IHJlY29yZC5tZXNzYWdlQXR0cmlidXRlcyxcbiAgICAgICAgfTtcblxuICAgICAgICBjb25zdCBmbHVlbnRFdmVudDogT21pdDxTcHlNZXNzYWdlLCAndGltZXN0YW1wJz4gPSB7XG4gICAgICAgICAgZGF0YSxcbiAgICAgICAgICBzZXJ2aWNlS2V5LFxuICAgICAgICB9O1xuICAgICAgICBwb3N0RGF0YVByb21pc2VzLnB1c2godGhpcy5wb3N0RGF0YShmbHVlbnRFdmVudCkpO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoZXZlbnQ/LlJlY29yZHMgJiYgZXZlbnQuUmVjb3Jkc1swXT8uczMpIHtcbiAgICAgIC8vY29uc29sZS5sb2coJyoqKiBTMyAqKionKTtcbiAgICAgIGNvbnN0IGV2ZW50UzMgPSBldmVudCBhcyBTM0V2ZW50O1xuICAgICAgZm9yIChjb25zdCByZWNvcmQgb2YgZXZlbnRTMy5SZWNvcmRzKSB7XG4gICAgICAgIGNvbnN0IGJ1Y2tldEFybiA9IHJlY29yZC5zMy5idWNrZXQuYXJuO1xuXG4gICAgICAgIGNvbnN0IGRhdGE6IFMzU3B5RXZlbnQgPSB7XG4gICAgICAgICAgc3B5RXZlbnRUeXBlOiAnUzMnLFxuICAgICAgICAgIGV2ZW50TmFtZTogcmVjb3JkLmV2ZW50TmFtZSxcbiAgICAgICAgICBldmVudFRpbWU6IHJlY29yZC5ldmVudFRpbWUsXG4gICAgICAgICAgYnVja2V0OiByZWNvcmQuczMuYnVja2V0Lm5hbWUsXG4gICAgICAgICAga2V5OiByZWNvcmQuczMub2JqZWN0LmtleSxcbiAgICAgICAgfTtcblxuICAgICAgICBjb25zdCBmbHVlbnRFdmVudDogT21pdDxTcHlNZXNzYWdlLCAndGltZXN0YW1wJz4gPSB7XG4gICAgICAgICAgZGF0YSxcbiAgICAgICAgICBzZXJ2aWNlS2V5OiBtYXBwaW5nW2J1Y2tldEFybl0sXG4gICAgICAgIH07XG4gICAgICAgIHBvc3REYXRhUHJvbWlzZXMucHVzaCh0aGlzLnBvc3REYXRhKGZsdWVudEV2ZW50KSk7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChldmVudC5SZWNvcmRzICYmIGV2ZW50LlJlY29yZHNbMF0/LmR5bmFtb2RiKSB7XG4gICAgICAvL2NvbnNvbGUubG9nKCcqKiogRFlOQU1PREIgKioqJyk7XG4gICAgICBjb25zdCBldmVudER5bmFtb0RCID0gZXZlbnQgYXMgRHluYW1vREJTdHJlYW1FdmVudDtcbiAgICAgIGZvciAoY29uc3QgcmVjb3JkIG9mIGV2ZW50RHluYW1vREIuUmVjb3Jkcykge1xuICAgICAgICBsZXQgYXJuID0gcmVjb3JkLmV2ZW50U291cmNlQVJOITtcbiAgICAgICAgYXJuID0gYXJuLnN1YnN0cmluZygwLCBhcm4uaW5kZXhPZignL3N0cmVhbS8nKSk7XG5cbiAgICAgICAgY29uc3QgZGF0YTogRHluYW1vREJTcHlFdmVudCA9IHtcbiAgICAgICAgICBzcHlFdmVudFR5cGU6ICdEeW5hbW9EQicsXG4gICAgICAgICAgZXZlbnROYW1lOiByZWNvcmQuZXZlbnROYW1lLFxuICAgICAgICAgIG5ld0ltYWdlOiB1bm1hcnNoYWxsKHJlY29yZC5keW5hbW9kYj8uTmV3SW1hZ2UgYXMgYW55KSxcbiAgICAgICAgICBrZXlzOiB1bm1hcnNoYWxsKHJlY29yZC5keW5hbW9kYj8uS2V5cyBhcyBhbnkpLFxuICAgICAgICAgIG9sZEltYWdlOiByZWNvcmQuZHluYW1vZGI/Lk9sZEltYWdlXG4gICAgICAgICAgICA/IHVubWFyc2hhbGwocmVjb3JkLmR5bmFtb2RiPy5PbGRJbWFnZSBhcyBhbnkpXG4gICAgICAgICAgICA6IHVuZGVmaW5lZCxcbiAgICAgICAgfTtcblxuICAgICAgICBjb25zdCBmbHVlbnRFdmVudDogT21pdDxTcHlNZXNzYWdlLCAndGltZXN0YW1wJz4gPSB7XG4gICAgICAgICAgZGF0YSxcbiAgICAgICAgICBzZXJ2aWNlS2V5OiBtYXBwaW5nW2Fybl0sXG4gICAgICAgIH07XG4gICAgICAgIHBvc3REYXRhUHJvbWlzZXMucHVzaCh0aGlzLnBvc3REYXRhKGZsdWVudEV2ZW50KSk7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChcbiAgICAgIGV2ZW50LmRldGFpbCAmJlxuICAgICAgZXZlbnRbJ2RldGFpbC10eXBlJ10gJiZcbiAgICAgIGV2ZW50LnZlcnNpb24gJiZcbiAgICAgIGV2ZW50LnNvdXJjZVxuICAgICkge1xuICAgICAgLy9jb25zb2xlLmxvZygnKioqIEV2ZW50QnJpZGdlICoqKicpO1xuICAgICAgY29uc3QgZXZlbnRFYiA9IGV2ZW50IGFzIEV2ZW50QnJpZGdlRXZlbnQ8YW55LCBhbnk+O1xuXG4gICAgICBjb25zdCBzZXJ2aWNlS2V5ID0gbWFwcGluZy5ldmVudEJyaWRnZTsgLy8gdGhlIGlzIG5ldyBsYW1iZGEgZm9yIGVhY2ggc3Vic2NyaXB0aW9uXG5cbiAgICAgIGNvbnN0IHNweUV2ZW50VHlwZSA9IHRoaXMuZ2V0U3B5RXZlbnRUeXBlKHNlcnZpY2VLZXkpIGFzXG4gICAgICAgIHwgJ0V2ZW50QnJpZGdlJ1xuICAgICAgICB8ICdFdmVudEJyaWRnZVJ1bGUnO1xuXG4gICAgICBjb25zdCBtZXNzYWdlID0gZXZlbnRFYi5kZXRhaWw7XG5cbiAgICAgIGNvbnN0IGRhdGE6IEV2ZW50QnJpZGdlU3B5RXZlbnQgfCBFdmVudEJyaWRnZVJ1bGVTcHlFdmVudCA9IHtcbiAgICAgICAgc3B5RXZlbnRUeXBlLFxuICAgICAgICBkZXRhaWw6IG1lc3NhZ2UsXG4gICAgICAgIGRldGFpbFR5cGU6IGV2ZW50RWJbJ2RldGFpbC10eXBlJ10sXG4gICAgICAgIGV2ZW50QnJpZGdlSWQ6IGV2ZW50RWJbJ2lkJ10sXG4gICAgICAgIHNvdXJjZTogZXZlbnRFYi5zb3VyY2UsXG4gICAgICAgIHRpbWU6IGV2ZW50RWIudGltZSxcbiAgICAgICAgYWNjb3VudDogZXZlbnRFYi5hY2NvdW50LFxuICAgICAgfTtcblxuICAgICAgY29uc3QgZmx1ZW50RXZlbnQ6IE9taXQ8U3B5TWVzc2FnZSwgJ3RpbWVzdGFtcCc+ID0ge1xuICAgICAgICBkYXRhLFxuICAgICAgICBzZXJ2aWNlS2V5LFxuICAgICAgfTtcbiAgICAgIHBvc3REYXRhUHJvbWlzZXMucHVzaCh0aGlzLnBvc3REYXRhKGZsdWVudEV2ZW50KSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vY29uc29sZS5sb2coJyoqKiBPVEhFUiAqKionKTtcbiAgICAgIGNvbnN0IGZsdWVudEV2ZW50OiBPbWl0PFNweU1lc3NhZ2UsICd0aW1lc3RhbXAnPiA9IGV2ZW50O1xuICAgICAgcG9zdERhdGFQcm9taXNlcy5wdXNoKHRoaXMucG9zdERhdGEoZmx1ZW50RXZlbnQpKTtcbiAgICB9XG5cbiAgICBhd2FpdCBQcm9taXNlLmFsbChwb3N0RGF0YVByb21pc2VzKTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgcG9zdERhdGEoc3B5TWVzc2FnZTogT21pdDxTcHlNZXNzYWdlLCAndGltZXN0YW1wJz4pIHtcbiAgICB0aGlzLmxvZygnUG9zdCBzcHkgbWVzc2FnZScsIEpTT04uc3RyaW5naWZ5KHNweU1lc3NhZ2UpKTtcblxuICAgIGlmICghdGhpcy5jb25uZWN0aW9ucykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IHBvc3RDYWxscyA9IHRoaXMuY29ubmVjdGlvbnMubWFwKGFzeW5jICh7IGNvbm5lY3Rpb25JZCB9KSA9PiB7XG4gICAgICB0aGlzLmxvZyhgU2VuZGluZyBtZXNzYWdlIHRvIGNsaWVudDogJHtjb25uZWN0aW9uSWQuU31gKTtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgcG9zdFRvQ29ubmVjdGlvbkNvbW1hbmQgPSBuZXcgUG9zdFRvQ29ubmVjdGlvbkNvbW1hbmQoe1xuICAgICAgICAgIENvbm5lY3Rpb25JZDogY29ubmVjdGlvbklkLlMsXG4gICAgICAgICAgRGF0YTogSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgICAgICAgdGltZXN0YW1wOiBuZXcgRGF0ZSgpLnRvSVNPU3RyaW5nKCksXG4gICAgICAgICAgICBzZXJ2aWNlS2V5OiBzcHlNZXNzYWdlLnNlcnZpY2VLZXksXG4gICAgICAgICAgICBkYXRhOiBzcHlNZXNzYWdlLmRhdGEsXG4gICAgICAgICAgfSkgYXMgYW55LFxuICAgICAgICB9KTtcblxuICAgICAgICBhd2FpdCB0aGlzLmFwaWd3TWFuYWdlbWVudEFwaS5zZW5kKHBvc3RUb0Nvbm5lY3Rpb25Db21tYW5kKTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgdGhpcy5sb2dFcnJvcihgRmFpbGQgc2VuZGluZyBzcHkgbWVzc2FnZSB0bzogJHtjb25uZWN0aW9uSWQuU31gLCBlKTtcbiAgICAgICAgaWYgKChlIGFzIGFueSkuJG1ldGFkYXRhLmh0dHBTdGF0dXNDb2RlID09PSA0MTApIHtcbiAgICAgICAgICB0aGlzLmxvZyhgRm91bmQgc3RhbGUgY29ubmVjdGlvbiwgZGVsZXRpbmcgJHtjb25uZWN0aW9uSWR9YCk7XG5cbiAgICAgICAgICBjb25zdCBkZWxldGVQYXJhbXMgPSBuZXcgRGVsZXRlSXRlbUNvbW1hbmQoe1xuICAgICAgICAgICAgVGFibGVOYW1lOiBwcm9jZXNzLmVudltlbnZWYXJpYWJsZU5hbWVzLlNTUFlfV1NfVEFCTEVfTkFNRV0sXG4gICAgICAgICAgICBLZXk6IHsgY29ubmVjdGlvbklkIH0sXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICBhd2FpdCB0aGlzLmRkYi5zZW5kKGRlbGV0ZVBhcmFtcyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhyb3cgZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pO1xuXG4gICAgYXdhaXQgUHJvbWlzZS5hbGwocG9zdENhbGxzKTtcbiAgICB0aGlzLmxvZygnU2VuZCBzcHkgbWVzc2FnZSBmaW5pc2gnKTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0U3B5RXZlbnRUeXBlKHNlcnZpY2VLZXk6IHN0cmluZykge1xuICAgIGlmICghc2VydmljZUtleSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdNaXNzaW5nIHNlcnZpY2VLZXknKTtcbiAgICB9XG5cbiAgICByZXR1cm4gc2VydmljZUtleS5zdWJzdHJpbmcoMCwgc2VydmljZUtleS5pbmRleE9mKCcjJykpO1xuICB9XG5cbiAgcHJpdmF0ZSBsb2cobWVzc2FnZTogc3RyaW5nLCAuLi5vcHRpb25hbFBhcmFtczogYW55W10pIHtcbiAgICBpZiAodGhpcy5kZWJ1Z01vZGUpIHtcbiAgICAgIGNvbnNvbGUuZGVidWcoJ1NTUFkgRVhURU5TSU9OJywgbWVzc2FnZSwgLi4ub3B0aW9uYWxQYXJhbXMpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgbG9nRXJyb3IobWVzc2FnZTogc3RyaW5nLCAuLi5vcHRpb25hbFBhcmFtczogYW55W10pIHtcbiAgICBpZiAodGhpcy5kZWJ1Z01vZGUpIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoJ1NTUFkgRVhURU5TSU9OJywgbWVzc2FnZSwgLi4ub3B0aW9uYWxQYXJhbXMpO1xuICAgIH1cbiAgfVxufVxuIl19
@@ -0,0 +1,223 @@
1
+ import { ApiGatewayManagementApi, PostToConnectionCommand, } from '@aws-sdk/client-apigatewaymanagementapi';
2
+ import { DeleteItemCommand, DynamoDBClient, ScanCommand, } from '@aws-sdk/client-dynamodb';
3
+ import { unmarshall } from '@aws-sdk/util-dynamodb';
4
+ import { envVariableNames } from '../src/common/envVariableNames';
5
+ export class SpyEventSender {
6
+ constructor(params) {
7
+ this.ddb = new DynamoDBClient({
8
+ region: process.env.AWS_REGION,
9
+ });
10
+ this.debugMode = process.env[envVariableNames.SSPY_DEBUG] === 'true';
11
+ this.apigwManagementApi = new ApiGatewayManagementApi({
12
+ apiVersion: '2018-11-29',
13
+ endpoint: process.env[envVariableNames.SSPY_WS_ENDPOINT],
14
+ });
15
+ if (params?.log) {
16
+ this.log = params.log;
17
+ }
18
+ if (params?.logError) {
19
+ this.logError = params.logError;
20
+ }
21
+ }
22
+ async publishSpyEvent(event) {
23
+ this.log('Event', JSON.stringify(event));
24
+ const mapping = JSON.parse(process.env[envVariableNames.SSPY_INFRA_MAPPING]);
25
+ this.log('ARN to names mapping', JSON.stringify(mapping));
26
+ let connectionData;
27
+ const scanParams = new ScanCommand({
28
+ TableName: process.env[envVariableNames.SSPY_WS_TABLE_NAME],
29
+ ProjectionExpression: 'connectionId',
30
+ });
31
+ connectionData = await this.ddb.send(scanParams);
32
+ this.connections = connectionData.Items;
33
+ const postDataPromises = [];
34
+ if (event?.Records && event.Records[0]?.Sns) {
35
+ //console.log('*** SNS ***');
36
+ const eventSns = event;
37
+ for (const record of eventSns.Records) {
38
+ const subscriptionArn = record.EventSubscriptionArn;
39
+ let serviceKey;
40
+ if (mapping[subscriptionArn]) {
41
+ // subscription event that could contain filter based on existing subscription
42
+ serviceKey = mapping[subscriptionArn];
43
+ }
44
+ else {
45
+ // catch all subscription
46
+ const topicArn = record.Sns.TopicArn;
47
+ serviceKey = mapping[topicArn];
48
+ }
49
+ let message;
50
+ try {
51
+ message = JSON.parse(record.Sns.Message);
52
+ }
53
+ catch {
54
+ message = record.Sns.Message;
55
+ }
56
+ const spyEventType = this.getSpyEventType(serviceKey);
57
+ const data = {
58
+ spyEventType,
59
+ message,
60
+ subject: record.Sns.Subject,
61
+ timestamp: record.Sns.Timestamp,
62
+ topicArn: record.Sns.TopicArn,
63
+ messageId: record.Sns.MessageId,
64
+ messageAttributes: record.Sns.MessageAttributes,
65
+ };
66
+ const fluentEvent = {
67
+ data,
68
+ serviceKey,
69
+ };
70
+ postDataPromises.push(this.postData(fluentEvent));
71
+ }
72
+ }
73
+ else if (event?.Records && event.Records[0]?.eventSource === 'aws:sqs') {
74
+ //console.log('*** SQS ***');
75
+ const eventSqs = event;
76
+ for (const record of eventSqs.Records) {
77
+ const subscriptionArn = record.eventSourceARN;
78
+ const serviceKey = mapping[subscriptionArn];
79
+ let body;
80
+ try {
81
+ body = JSON.parse(record.body);
82
+ }
83
+ catch {
84
+ body = record.body;
85
+ }
86
+ const data = {
87
+ spyEventType: 'Sqs',
88
+ body,
89
+ messageAttributes: record.messageAttributes,
90
+ };
91
+ const fluentEvent = {
92
+ data,
93
+ serviceKey,
94
+ };
95
+ postDataPromises.push(this.postData(fluentEvent));
96
+ }
97
+ }
98
+ else if (event?.Records && event.Records[0]?.s3) {
99
+ //console.log('*** S3 ***');
100
+ const eventS3 = event;
101
+ for (const record of eventS3.Records) {
102
+ const bucketArn = record.s3.bucket.arn;
103
+ const data = {
104
+ spyEventType: 'S3',
105
+ eventName: record.eventName,
106
+ eventTime: record.eventTime,
107
+ bucket: record.s3.bucket.name,
108
+ key: record.s3.object.key,
109
+ };
110
+ const fluentEvent = {
111
+ data,
112
+ serviceKey: mapping[bucketArn],
113
+ };
114
+ postDataPromises.push(this.postData(fluentEvent));
115
+ }
116
+ }
117
+ else if (event.Records && event.Records[0]?.dynamodb) {
118
+ //console.log('*** DYNAMODB ***');
119
+ const eventDynamoDB = event;
120
+ for (const record of eventDynamoDB.Records) {
121
+ let arn = record.eventSourceARN;
122
+ arn = arn.substring(0, arn.indexOf('/stream/'));
123
+ const data = {
124
+ spyEventType: 'DynamoDB',
125
+ eventName: record.eventName,
126
+ newImage: unmarshall(record.dynamodb?.NewImage),
127
+ keys: unmarshall(record.dynamodb?.Keys),
128
+ oldImage: record.dynamodb?.OldImage
129
+ ? unmarshall(record.dynamodb?.OldImage)
130
+ : undefined,
131
+ };
132
+ const fluentEvent = {
133
+ data,
134
+ serviceKey: mapping[arn],
135
+ };
136
+ postDataPromises.push(this.postData(fluentEvent));
137
+ }
138
+ }
139
+ else if (event.detail &&
140
+ event['detail-type'] &&
141
+ event.version &&
142
+ event.source) {
143
+ //console.log('*** EventBridge ***');
144
+ const eventEb = event;
145
+ const serviceKey = mapping.eventBridge; // the is new lambda for each subscription
146
+ const spyEventType = this.getSpyEventType(serviceKey);
147
+ const message = eventEb.detail;
148
+ const data = {
149
+ spyEventType,
150
+ detail: message,
151
+ detailType: eventEb['detail-type'],
152
+ eventBridgeId: eventEb['id'],
153
+ source: eventEb.source,
154
+ time: eventEb.time,
155
+ account: eventEb.account,
156
+ };
157
+ const fluentEvent = {
158
+ data,
159
+ serviceKey,
160
+ };
161
+ postDataPromises.push(this.postData(fluentEvent));
162
+ }
163
+ else {
164
+ //console.log('*** OTHER ***');
165
+ const fluentEvent = event;
166
+ postDataPromises.push(this.postData(fluentEvent));
167
+ }
168
+ await Promise.all(postDataPromises);
169
+ }
170
+ async postData(spyMessage) {
171
+ this.log('Post spy message', JSON.stringify(spyMessage));
172
+ if (!this.connections) {
173
+ return;
174
+ }
175
+ const postCalls = this.connections.map(async ({ connectionId }) => {
176
+ this.log(`Sending message to client: ${connectionId.S}`);
177
+ try {
178
+ const postToConnectionCommand = new PostToConnectionCommand({
179
+ ConnectionId: connectionId.S,
180
+ Data: JSON.stringify({
181
+ timestamp: new Date().toISOString(),
182
+ serviceKey: spyMessage.serviceKey,
183
+ data: spyMessage.data,
184
+ }),
185
+ });
186
+ await this.apigwManagementApi.send(postToConnectionCommand);
187
+ }
188
+ catch (e) {
189
+ this.logError(`Faild sending spy message to: ${connectionId.S}`, e);
190
+ if (e.$metadata.httpStatusCode === 410) {
191
+ this.log(`Found stale connection, deleting ${connectionId}`);
192
+ const deleteParams = new DeleteItemCommand({
193
+ TableName: process.env[envVariableNames.SSPY_WS_TABLE_NAME],
194
+ Key: { connectionId },
195
+ });
196
+ await this.ddb.send(deleteParams);
197
+ }
198
+ else {
199
+ throw e;
200
+ }
201
+ }
202
+ });
203
+ await Promise.all(postCalls);
204
+ this.log('Send spy message finish');
205
+ }
206
+ getSpyEventType(serviceKey) {
207
+ if (!serviceKey) {
208
+ throw new Error('Missing serviceKey');
209
+ }
210
+ return serviceKey.substring(0, serviceKey.indexOf('#'));
211
+ }
212
+ log(message, ...optionalParams) {
213
+ if (this.debugMode) {
214
+ console.debug('SSPY EXTENSION', message, ...optionalParams);
215
+ }
216
+ }
217
+ logError(message, ...optionalParams) {
218
+ if (this.debugMode) {
219
+ console.error('SSPY EXTENSION', message, ...optionalParams);
220
+ }
221
+ }
222
+ }
223
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiU3B5RXZlbnRTZW5kZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9jb21tb24vU3B5RXZlbnRTZW5kZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUNMLHVCQUF1QixFQUN2Qix1QkFBdUIsR0FDeEIsTUFBTSx5Q0FBeUMsQ0FBQztBQUNqRCxPQUFPLEVBRUwsaUJBQWlCLEVBQ2pCLGNBQWMsRUFDZCxXQUFXLEdBQ1osTUFBTSwwQkFBMEIsQ0FBQztBQUVsQyxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFRcEQsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sZ0NBQWdDLENBQUM7QUFVbEUsTUFBTSxPQUFPLGNBQWM7SUFXekIsWUFBWSxNQUdYO1FBYkQsUUFBRyxHQUFHLElBQUksY0FBYyxDQUFDO1lBQ3ZCLE1BQU0sRUFBRSxPQUFPLENBQUMsR0FBRyxDQUFDLFVBQVU7U0FDL0IsQ0FBQyxDQUFDO1FBQ0gsY0FBUyxHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMsZ0JBQWdCLENBQUMsVUFBVSxDQUFDLEtBQUssTUFBTSxDQUFDO1FBQ2hFLHVCQUFrQixHQUFHLElBQUksdUJBQXVCLENBQUM7WUFDL0MsVUFBVSxFQUFFLFlBQVk7WUFDeEIsUUFBUSxFQUFFLE9BQU8sQ0FBQyxHQUFHLENBQUMsZ0JBQWdCLENBQUMsZ0JBQWdCLENBQUU7U0FDMUQsQ0FBQyxDQUFDO1FBT0QsSUFBSSxNQUFNLEVBQUUsR0FBRyxFQUFFO1lBQ2YsSUFBSSxDQUFDLEdBQUcsR0FBRyxNQUFNLENBQUMsR0FBRyxDQUFDO1NBQ3ZCO1FBRUQsSUFBSSxNQUFNLEVBQUUsUUFBUSxFQUFFO1lBQ3BCLElBQUksQ0FBQyxRQUFRLEdBQUcsTUFBTSxDQUFDLFFBQVEsQ0FBQztTQUNqQztJQUNILENBQUM7SUFFTSxLQUFLLENBQUMsZUFBZSxDQUFDLEtBQVU7UUFDckMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxPQUFPLEVB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QUFDLGdCQUFnQixDQUFDLGtCQUFrQixDQUFDO3dCQUMzRCxHQUFHLEVBQUUsRUFBRSxZQUFZLEVBQUU7cUJBQ3RCLENBQUMsQ0FBQztvQkFFSCxNQUFNLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDO2lCQUNuQztxQkFBTTtvQkFDTCxNQUFNLENBQUMsQ0FBQztpQkFDVDthQUNGO1FBQ0gsQ0FBQyxDQUFDLENBQUM7UUFFSCxNQUFNLE9BQU8sQ0FBQyxHQUFHLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDN0IsSUFBSSxDQUFDLEdBQUcsQ0FBQyx5QkFBeUIsQ0FBQyxDQUFDO0lBQ3RDLENBQUM7SUFFTyxlQUFlLENBQUMsVUFBa0I7UUFDeEMsSUFBSSxDQUFDLFVBQVUsRUFBRTtZQUNmLE1BQU0sSUFBSSxLQUFLLENBQUMsb0JBQW9CLENBQUMsQ0FBQztTQUN2QztRQUVELE9BQU8sVUFBVSxDQUFDLFNBQVMsQ0FBQyxDQUFDLEVBQUUsVUFBVSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO0lBQzFELENBQUM7SUFFTyxHQUFHLENBQUMsT0FBZSxFQUFFLEdBQUcsY0FBcUI7UUFDbkQsSUFBSSxJQUFJLENBQUMsU0FBUyxFQUFFO1lBQ2xCLE9BQU8sQ0FBQyxLQUFLLENBQUMsZ0JBQWdCLEVBQUUsT0FBTyxFQUFFLEdBQUcsY0FBYyxDQUFDLENBQUM7U0FDN0Q7SUFDSCxDQUFDO0lBRU8sUUFBUSxDQUFDLE9BQWUsRUFBRSxHQUFHLGNBQXFCO1FBQ3hELElBQUksSUFBSSxDQUFDLFNBQVMsRUFBRTtZQUNsQixPQUFPLENBQUMsS0FBSyxDQUFDLGdCQUFnQixFQUFFLE9BQU8sRUFBRSxHQUFHLGNBQWMsQ0FBQyxDQUFDO1NBQzdEO0lBQ0gsQ0FBQztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQXBpR2F0ZXdheU1hbmFnZW1lbnRBcGksXG4gIFBvc3RUb0Nvbm5lY3Rpb25Db21tYW5kLFxufSBmcm9tICdAYXdzLXNkay9jbGllbnQtYXBpZ2F0ZXdheW1hbmFnZW1lbnRhcGknO1xuaW1wb3J0IHtcbiAgQXR0cmlidXRlVmFsdWUsXG4gIERlbGV0ZUl0ZW1Db21tYW5kLFxuICBEeW5hbW9EQkNsaWVudCxcbiAgU2NhbkNvbW1hbmQsXG59IGZyb20gJ0Bhd3Mtc2RrL2NsaWVudC1keW5hbW9kYic7XG5cbmltcG9ydCB7IHVubWFyc2hhbGwgfSBmcm9tICdAYXdzLXNkay91dGlsLWR5bmFtb2RiJztcbmltcG9ydCB7XG4gIER5bmFtb0RCU3RyZWFtRXZlbnQsXG4gIFMzRXZlbnQsXG4gIFNOU0V2ZW50LFxuICBFdmVudEJyaWRnZUV2ZW50LFxuICBTUVNFdmVudCxcbn0gZnJvbSAnYXdzLWxhbWJkYSc7XG5pbXBvcnQgeyBlbnZWYXJpYWJsZU5hbWVzIH0gZnJvbSAnLi4vc3JjL2NvbW1vbi9lbnZWYXJpYWJsZU5hbWVzJztcbmltcG9ydCB7IER5bmFtb0RCU3B5RXZlbnQgfSBmcm9tICcuL3NweUV2ZW50cy9EeW5hbW9EQlNweUV2ZW50JztcbmltcG9ydCB7IEV2ZW50QnJpZGdlUnVsZVNweUV2ZW50IH0gZnJvbSAnLi9zcHlFdmVudHMvRXZlbnRCcmlkZ2VSdWxlU3B5RXZlbnQnO1xuaW1wb3J0IHsgRXZlbnRCcmlkZ2VTcHlFdmVudCB9IGZyb20gJy4vc3B5RXZlbnRzL0V2ZW50QnJpZGdlU3B5RXZlbnQnO1xuaW1wb3J0IHsgUzNTcHlFdmVudCB9IGZyb20gJy4vc3B5RXZlbnRzL1MzU3B5RXZlbnQnO1xuaW1wb3J0IHsgU25zU3Vic2NyaXB0aW9uU3B5RXZlbnQgfSBmcm9tICcuL3NweUV2ZW50cy9TbnNTdWJzY3JpcHRpb25TcHlFdmVudCc7XG5pbXBvcnQgeyBTbnNUb3BpY1NweUV2ZW50IH0gZnJvbSAnLi9zcHlFdmVudHMvU25zVG9waWNTcHlFdmVudCc7XG5pbXBvcnQgeyBTcHlNZXNzYWdlIH0gZnJvbSAnLi9zcHlFdmVudHMvU3B5TWVzc2FnZSc7XG5pbXBvcnQgeyBTcXNTcHlFdmVudCB9IGZyb20gJy4vc3B5RXZlbnRzL1Nxc1NweUV2ZW50JztcblxuZXhwb3J0IGNsYXNzIFNweUV2ZW50U2VuZGVyIHtcbiAgZGRiID0gbmV3IER5bmFtb0RCQ2xpZW50KHtcbiAgICByZWdpb246IHByb2Nlc3MuZW52LkFXU19SRUdJT04sXG4gIH0pO1xuICBkZWJ1Z01vZGUgPSBwcm9jZXNzLmVudltlbnZWYXJpYWJsZU5hbWVzLlNTUFlfREVCVUddID09PSAndHJ1ZSc7XG4gIGFwaWd3TWFuYWdlbWVudEFwaSA9IG5ldyBBcGlHYXRld2F5TWFuYWdlbWVudEFwaSh7XG4gICAgYXBpVmVyc2lvbjogJzIwMTgtMTEtMjknLFxuICAgIGVuZHBvaW50OiBwcm9jZXNzLmVudltlbnZWYXJpYWJsZU5hbWVzLlNTUFlfV1NfRU5EUE9JTlRdISxcbiAgfSk7XG4gIGNvbm5lY3Rpb25zOiBSZWNvcmQ8c3RyaW5nLCBBdHRyaWJ1dGVWYWx1ZT5bXSB8IHVuZGVmaW5lZDtcblxuICBjb25zdHJ1Y3RvcihwYXJhbXM/OiB7XG4gICAgbG9nOiAobWVzc2FnZTogc3RyaW5nLCAuLi5vcHRpb25hbFBhcmFtczogYW55W10pID0+IHZvaWQ7XG4gICAgbG9nRXJyb3I6IChtZXNzYWdlOiBzdHJpbmcsIC4uLm9wdGlvbmFsUGFyYW1zOiBhbnlbXSkgPT4gdm9pZDtcbiAgfSkge1xuICAgIGlmIChwYXJhbXM/LmxvZykge1xuICAgICAgdGhpcy5sb2cgPSBwYXJhbXMubG9nO1xuICAgIH1cblxuICAgIGlmIChwYXJhbXM/LmxvZ0Vycm9yKSB7XG4gICAgICB0aGlzLmxvZ0Vycm9yID0gcGFyYW1zLmxvZ0Vycm9yO1xuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBwdWJsaXNoU3B5RXZlbnQoZXZlbnQ6IGFueSkge1xuICAgIHRoaXMubG9nKCdFdmVudCcsIEpTT04uc3RyaW5naWZ5KGV2ZW50KSk7XG5cbiAgICBjb25zdCBtYXBwaW5nID0gSlNPTi5wYXJzZShcbiAgICAgIHByb2Nlc3MuZW52W2VudlZhcmlhYmxlTmFtZXMuU1NQWV9JTkZSQV9NQVBQSU5HXSFcbiAgICApO1xuICAgIHRoaXMubG9nKCdBUk4gdG8gbmFtZXMgbWFwcGluZycsIEpTT04uc3RyaW5naWZ5KG1hcHBpbmcpKTtcblxuICAgIGxldCBjb25uZWN0aW9uRGF0YTtcblxuICAgIGNvbnN0IHNjYW5QYXJhbXMgPSBuZXcgU2NhbkNvbW1hbmQoe1xuICAgICAgVGFibGVOYW1lOiBwcm9jZXNzLmVudltlbnZWYXJpYWJsZU5hbWVzLlNTUFlfV1NfVEFCTEVfTkFNRV0gYXMgc3RyaW5nLFxuICAgICAgUHJvamVjdGlvbkV4cHJlc3Npb246ICdjb25uZWN0aW9uSWQnLFxuICAgIH0pO1xuXG4gICAgY29ubmVjdGlvbkRhdGEgPSBhd2FpdCB0aGlzLmRkYi5zZW5kKHNjYW5QYXJhbXMpO1xuXG4gICAgdGhpcy5jb25uZWN0aW9ucyA9IGNvbm5lY3Rpb25EYXRhLkl0ZW1zO1xuXG4gICAgY29uc3QgcG9zdERhdGFQcm9taXNlczogUHJvbWlzZTxhbnk+W10gPSBbXTtcblxuICAgIGlmIChldmVudD8uUmVjb3JkcyAmJiBldmVudC5SZWNvcmRzWzBdPy5TbnMpIHtcbiAgICAgIC8vY29uc29sZS5sb2coJyoqKiBTTlMgKioqJyk7XG4gICAgICBjb25zdCBldmVudFNucyA9IGV2ZW50IGFzIFNOU0V2ZW50O1xuICAgICAgZm9yIChjb25zdCByZWNvcmQgb2YgZXZlbnRTbnMuUmVjb3Jkcykge1xuICAgICAgICBjb25zdCBzdWJzY3JpcHRpb25Bcm4gPSByZWNvcmQuRXZlbnRTdWJzY3JpcHRpb25Bcm47XG5cbiAgICAgICAgbGV0IHNlcnZpY2VLZXk6IHN0cmluZztcbiAgICAgICAgaWYgKG1hcHBpbmdbc3Vic2NyaXB0aW9uQXJuXSkge1xuICAgICAgICAgIC8vIHN1YnNjcmlwdGlvbiBldmVudCB0aGF0IGNvdWxkIGNvbnRhaW4gZmlsdGVyIGJhc2VkIG9uIGV4aXN0aW5nIHN1YnNjcmlwdGlvblxuICAgICAgICAgIHNlcnZpY2VLZXkgPSBtYXBwaW5nW3N1YnNjcmlwdGlvbkFybl07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gY2F0Y2ggYWxsIHN1YnNjcmlwdGlvblxuICAgICAgICAgIGNvbnN0IHRvcGljQXJuID0gcmVjb3JkLlNucy5Ub3BpY0FybjtcbiAgICAgICAgICBzZXJ2aWNlS2V5ID0gbWFwcGluZ1t0b3BpY0Fybl07XG4gICAgICAgIH1cblxuICAgICAgICBsZXQgbWVzc2FnZTogc3RyaW5nO1xuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgbWVzc2FnZSA9IEpTT04ucGFyc2UocmVjb3JkLlNucy5NZXNzYWdlKTtcbiAgICAgICAgfSBjYXRjaCB7XG4gICAgICAgICAgbWVzc2FnZSA9IHJlY29yZC5TbnMuTWVzc2FnZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHNweUV2ZW50VHlwZSA9IHRoaXMuZ2V0U3B5RXZlbnRUeXBlKHNlcnZpY2VLZXkpIGFzXG4gICAgICAgICAgfCAnRnVuY3Rpb25TbnNUb3BpYydcbiAgICAgICAgICB8ICdGdW5jdGlvblNuc1N1YnNjcmlwdGlvbic7XG5cbiAgICAgICAgY29uc3QgZGF0YTogU25zVG9waWNTcHlFdmVudCB8IFNuc1N1YnNjcmlwdGlvblNweUV2ZW50ID0ge1xuICAgICAgICAgIHNweUV2ZW50VHlwZSxcbiAgICAgICAgICBtZXNzYWdlLFxuICAgICAgICAgIHN1YmplY3Q6IHJlY29yZC5TbnMuU3ViamVjdCxcbiAgICAgICAgICB0aW1lc3RhbXA6IHJlY29yZC5TbnMuVGltZXN0YW1wLFxuICAgICAgICAgIHRvcGljQXJuOiByZWNvcmQuU25zLlRvcGljQXJuLFxuICAgICAgICAgIG1lc3NhZ2VJZDogcmVjb3JkLlNucy5NZXNzYWdlSWQsXG4gICAgICAgICAgbWVzc2FnZUF0dHJpYnV0ZXM6IHJlY29yZC5TbnMuTWVzc2FnZUF0dHJpYnV0ZXMsXG4gICAgICAgIH07XG5cbiAgICAgICAgY29uc3QgZmx1ZW50RXZlbnQ6IE9taXQ8U3B5TWVzc2FnZSwgJ3RpbWVzdGFtcCc+ID0ge1xuICAgICAgICAgIGRhdGEsXG4gICAgICAgICAgc2VydmljZUtleSxcbiAgICAgICAgfTtcbiAgICAgICAgcG9zdERhdGFQcm9taXNlcy5wdXNoKHRoaXMucG9zdERhdGEoZmx1ZW50RXZlbnQpKTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGV2ZW50Py5SZWNvcmRzICYmIGV2ZW50LlJlY29yZHNbMF0/LmV2ZW50U291cmNlID09PSAnYXdzOnNxcycpIHtcbiAgICAgIC8vY29uc29sZS5sb2coJyoqKiBTUVMgKioqJyk7XG4gICAgICBjb25zdCBldmVudFNxcyA9IGV2ZW50IGFzIFNRU0V2ZW50O1xuICAgICAgZm9yIChjb25zdCByZWNvcmQgb2YgZXZlbnRTcXMuUmVjb3Jkcykge1xuICAgICAgICBjb25zdCBzdWJzY3JpcHRpb25Bcm4gPSByZWNvcmQuZXZlbnRTb3VyY2VBUk47XG5cbiAgICAgICAgY29uc3Qgc2VydmljZUtleSA9IG1hcHBpbmdbc3Vic2NyaXB0aW9uQXJuXTtcbiAgICAgICAgbGV0IGJvZHk6IHN0cmluZztcblxuICAgICAgICB0cnkge1xuICAgICAgICAgIGJvZHkgPSBKU09OLnBhcnNlKHJlY29yZC5ib2R5KTtcbiAgICAgICAgfSBjYXRjaCB7XG4gICAgICAgICAgYm9keSA9IHJlY29yZC5ib2R5O1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgZGF0YTogU3FzU3B5RXZlbnQgPSB7XG4gICAgICAgICAgc3B5RXZlbnRUeXBlOiAnU3FzJyxcbiAgICAgICAgICBib2R5LFxuICAgICAgICAgIG1lc3NhZ2VBdHRyaWJ1dGVzOiByZWNvcmQubWVzc2FnZUF0dHJpYnV0ZXMsXG4gICAgICAgIH07XG5cbiAgICAgICAgY29uc3QgZmx1ZW50RXZlbnQ6IE9taXQ8U3B5TWVzc2FnZSwgJ3RpbWVzdGFtcCc+ID0ge1xuICAgICAgICAgIGRhdGEsXG4gICAgICAgICAgc2VydmljZUtleSxcbiAgICAgICAgfTtcbiAgICAgICAgcG9zdERhdGFQcm9taXNlcy5wdXNoKHRoaXMucG9zdERhdGEoZmx1ZW50RXZlbnQpKTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGV2ZW50Py5SZWNvcmRzICYmIGV2ZW50LlJlY29yZHNbMF0/LnMzKSB7XG4gICAgICAvL2NvbnNvbGUubG9nKCcqKiogUzMgKioqJyk7XG4gICAgICBjb25zdCBldmVudFMzID0gZXZlbnQgYXMgUzNFdmVudDtcbiAgICAgIGZvciAoY29uc3QgcmVjb3JkIG9mIGV2ZW50UzMuUmVjb3Jkcykge1xuICAgICAgICBjb25zdCBidWNrZXRBcm4gPSByZWNvcmQuczMuYnVja2V0LmFybjtcblxuICAgICAgICBjb25zdCBkYXRhOiBTM1NweUV2ZW50ID0ge1xuICAgICAgICAgIHNweUV2ZW50VHlwZTogJ1MzJyxcbiAgICAgICAgICBldmVudE5hbWU6IHJlY29yZC5ldmVudE5hbWUsXG4gICAgICAgICAgZXZlbnRUaW1lOiByZWNvcmQuZXZlbnRUaW1lLFxuICAgICAgICAgIGJ1Y2tldDogcmVjb3JkLnMzLmJ1Y2tldC5uYW1lLFxuICAgICAgICAgIGtleTogcmVjb3JkLnMzLm9iamVjdC5rZXksXG4gICAgICAgIH07XG5cbiAgICAgICAgY29uc3QgZmx1ZW50RXZlbnQ6IE9taXQ8U3B5TWVzc2FnZSwgJ3RpbWVzdGFtcCc+ID0ge1xuICAgICAgICAgIGRhdGEsXG4gICAgICAgICAgc2VydmljZUtleTogbWFwcGluZ1tidWNrZXRBcm5dLFxuICAgICAgICB9O1xuICAgICAgICBwb3N0RGF0YVByb21pc2VzLnB1c2godGhpcy5wb3N0RGF0YShmbHVlbnRFdmVudCkpO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoZXZlbnQuUmVjb3JkcyAmJiBldmVudC5SZWNvcmRzWzBdPy5keW5hbW9kYikge1xuICAgICAgLy9jb25zb2xlLmxvZygnKioqIERZTkFNT0RCICoqKicpO1xuICAgICAgY29uc3QgZXZlbnREeW5hbW9EQiA9IGV2ZW50IGFzIER5bmFtb0RCU3RyZWFtRXZlbnQ7XG4gICAgICBmb3IgKGNvbnN0IHJlY29yZCBvZiBldmVudER5bmFtb0RCLlJlY29yZHMpIHtcbiAgICAgICAgbGV0IGFybiA9IHJlY29yZC5ldmVudFNvdXJjZUFSTiE7XG4gICAgICAgIGFybiA9IGFybi5zdWJzdHJpbmcoMCwgYXJuLmluZGV4T2YoJy9zdHJlYW0vJykpO1xuXG4gICAgICAgIGNvbnN0IGRhdGE6IER5bmFtb0RCU3B5RXZlbnQgPSB7XG4gICAgICAgICAgc3B5RXZlbnRUeXBlOiAnRHluYW1vREInLFxuICAgICAgICAgIGV2ZW50TmFtZTogcmVjb3JkLmV2ZW50TmFtZSxcbiAgICAgICAgICBuZXdJbWFnZTogdW5tYXJzaGFsbChyZWNvcmQuZHluYW1vZGI/Lk5ld0ltYWdlIGFzIGFueSksXG4gICAgICAgICAga2V5czogdW5tYXJzaGFsbChyZWNvcmQuZHluYW1vZGI/LktleXMgYXMgYW55KSxcbiAgICAgICAgICBvbGRJbWFnZTogcmVjb3JkLmR5bmFtb2RiPy5PbGRJbWFnZVxuICAgICAgICAgICAgPyB1bm1hcnNoYWxsKHJlY29yZC5keW5hbW9kYj8uT2xkSW1hZ2UgYXMgYW55KVxuICAgICAgICAgICAgOiB1bmRlZmluZWQsXG4gICAgICAgIH07XG5cbiAgICAgICAgY29uc3QgZmx1ZW50RXZlbnQ6IE9taXQ8U3B5TWVzc2FnZSwgJ3RpbWVzdGFtcCc+ID0ge1xuICAgICAgICAgIGRhdGEsXG4gICAgICAgICAgc2VydmljZUtleTogbWFwcGluZ1thcm5dLFxuICAgICAgICB9O1xuICAgICAgICBwb3N0RGF0YVByb21pc2VzLnB1c2godGhpcy5wb3N0RGF0YShmbHVlbnRFdmVudCkpO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoXG4gICAgICBldmVudC5kZXRhaWwgJiZcbiAgICAgIGV2ZW50WydkZXRhaWwtdHlwZSddICYmXG4gICAgICBldmVudC52ZXJzaW9uICYmXG4gICAgICBldmVudC5zb3VyY2VcbiAgICApIHtcbiAgICAgIC8vY29uc29sZS5sb2coJyoqKiBFdmVudEJyaWRnZSAqKionKTtcbiAgICAgIGNvbnN0IGV2ZW50RWIgPSBldmVudCBhcyBFdmVudEJyaWRnZUV2ZW50PGFueSwgYW55PjtcblxuICAgICAgY29uc3Qgc2VydmljZUtleSA9IG1hcHBpbmcuZXZlbnRCcmlkZ2U7IC8vIHRoZSBpcyBuZXcgbGFtYmRhIGZvciBlYWNoIHN1YnNjcmlwdGlvblxuXG4gICAgICBjb25zdCBzcHlFdmVudFR5cGUgPSB0aGlzLmdldFNweUV2ZW50VHlwZShzZXJ2aWNlS2V5KSBhc1xuICAgICAgICB8ICdFdmVudEJyaWRnZSdcbiAgICAgICAgfCAnRXZlbnRCcmlkZ2VSdWxlJztcblxuICAgICAgY29uc3QgbWVzc2FnZSA9IGV2ZW50RWIuZGV0YWlsO1xuXG4gICAgICBjb25zdCBkYXRhOiBFdmVudEJyaWRnZVNweUV2ZW50IHwgRXZlbnRCcmlkZ2VSdWxlU3B5RXZlbnQgPSB7XG4gICAgICAgIHNweUV2ZW50VHlwZSxcbiAgICAgICAgZGV0YWlsOiBtZXNzYWdlLFxuICAgICAgICBkZXRhaWxUeXBlOiBldmVudEViWydkZXRhaWwtdHlwZSddLFxuICAgICAgICBldmVudEJyaWRnZUlkOiBldmVudEViWydpZCddLFxuICAgICAgICBzb3VyY2U6IGV2ZW50RWIuc291cmNlLFxuICAgICAgICB0aW1lOiBldmVudEViLnRpbWUsXG4gICAgICAgIGFjY291bnQ6IGV2ZW50RWIuYWNjb3VudCxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IGZsdWVudEV2ZW50OiBPbWl0PFNweU1lc3NhZ2UsICd0aW1lc3RhbXAnPiA9IHtcbiAgICAgICAgZGF0YSxcbiAgICAgICAgc2VydmljZUtleSxcbiAgICAgIH07XG4gICAgICBwb3N0RGF0YVByb21pc2VzLnB1c2godGhpcy5wb3N0RGF0YShmbHVlbnRFdmVudCkpO1xuICAgIH0gZWxzZSB7XG4gICAgICAvL2NvbnNvbGUubG9nKCcqKiogT1RIRVIgKioqJyk7XG4gICAgICBjb25zdCBmbHVlbnRFdmVudDogT21pdDxTcHlNZXNzYWdlLCAndGltZXN0YW1wJz4gPSBldmVudDtcbiAgICAgIHBvc3REYXRhUHJvbWlzZXMucHVzaCh0aGlzLnBvc3REYXRhKGZsdWVudEV2ZW50KSk7XG4gICAgfVxuXG4gICAgYXdhaXQgUHJvbWlzZS5hbGwocG9zdERhdGFQcm9taXNlcyk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHBvc3REYXRhKHNweU1lc3NhZ2U6IE9taXQ8U3B5TWVzc2FnZSwgJ3RpbWVzdGFtcCc+KSB7XG4gICAgdGhpcy5sb2coJ1Bvc3Qgc3B5IG1lc3NhZ2UnLCBKU09OLnN0cmluZ2lmeShzcHlNZXNzYWdlKSk7XG5cbiAgICBpZiAoIXRoaXMuY29ubmVjdGlvbnMpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBwb3N0Q2FsbHMgPSB0aGlzLmNvbm5lY3Rpb25zLm1hcChhc3luYyAoeyBjb25uZWN0aW9uSWQgfSkgPT4ge1xuICAgICAgdGhpcy5sb2coYFNlbmRpbmcgbWVzc2FnZSB0byBjbGllbnQ6ICR7Y29ubmVjdGlvbklkLlN9YCk7XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHBvc3RUb0Nvbm5lY3Rpb25Db21tYW5kID0gbmV3IFBvc3RUb0Nvbm5lY3Rpb25Db21tYW5kKHtcbiAgICAgICAgICBDb25uZWN0aW9uSWQ6IGNvbm5lY3Rpb25JZC5TLFxuICAgICAgICAgIERhdGE6IEpTT04uc3RyaW5naWZ5KHtcbiAgICAgICAgICAgIHRpbWVzdGFtcDogbmV3IERhdGUoKS50b0lTT1N0cmluZygpLFxuICAgICAgICAgICAgc2VydmljZUtleTogc3B5TWVzc2FnZS5zZXJ2aWNlS2V5LFxuICAgICAgICAgICAgZGF0YTogc3B5TWVzc2FnZS5kYXRhLFxuICAgICAgICAgIH0pIGFzIGFueSxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgYXdhaXQgdGhpcy5hcGlnd01hbmFnZW1lbnRBcGkuc2VuZChwb3N0VG9Db25uZWN0aW9uQ29tbWFuZCk7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIHRoaXMubG9nRXJyb3IoYEZhaWxkIHNlbmRpbmcgc3B5IG1lc3NhZ2UgdG86ICR7Y29ubmVjdGlvbklkLlN9YCwgZSk7XG4gICAgICAgIGlmICgoZSBhcyBhbnkpLiRtZXRhZGF0YS5odHRwU3RhdHVzQ29kZSA9PT0gNDEwKSB7XG4gICAgICAgICAgdGhpcy5sb2coYEZvdW5kIHN0YWxlIGNvbm5lY3Rpb24sIGRlbGV0aW5nICR7Y29ubmVjdGlvbklkfWApO1xuXG4gICAgICAgICAgY29uc3QgZGVsZXRlUGFyYW1zID0gbmV3IERlbGV0ZUl0ZW1Db21tYW5kKHtcbiAgICAgICAgICAgIFRhYmxlTmFtZTogcHJvY2Vzcy5lbnZbZW52VmFyaWFibGVOYW1lcy5TU1BZX1dTX1RBQkxFX05BTUVdLFxuICAgICAgICAgICAgS2V5OiB7IGNvbm5lY3Rpb25JZCB9LFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgYXdhaXQgdGhpcy5kZGIuc2VuZChkZWxldGVQYXJhbXMpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRocm93IGU7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KTtcblxuICAgIGF3YWl0IFByb21pc2UuYWxsKHBvc3RDYWxscyk7XG4gICAgdGhpcy5sb2coJ1NlbmQgc3B5IG1lc3NhZ2UgZmluaXNoJyk7XG4gIH1cblxuICBwcml2YXRlIGdldFNweUV2ZW50VHlwZShzZXJ2aWNlS2V5OiBzdHJpbmcpIHtcbiAgICBpZiAoIXNlcnZpY2VLZXkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignTWlzc2luZyBzZXJ2aWNlS2V5Jyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHNlcnZpY2VLZXkuc3Vic3RyaW5nKDAsIHNlcnZpY2VLZXkuaW5kZXhPZignIycpKTtcbiAgfVxuXG4gIHByaXZhdGUgbG9nKG1lc3NhZ2U6IHN0cmluZywgLi4ub3B0aW9uYWxQYXJhbXM6IGFueVtdKSB7XG4gICAgaWYgKHRoaXMuZGVidWdNb2RlKSB7XG4gICAgICBjb25zb2xlLmRlYnVnKCdTU1BZIEVYVEVOU0lPTicsIG1lc3NhZ2UsIC4uLm9wdGlvbmFsUGFyYW1zKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGxvZ0Vycm9yKG1lc3NhZ2U6IHN0cmluZywgLi4ub3B0aW9uYWxQYXJhbXM6IGFueVtdKSB7XG4gICAgaWYgKHRoaXMuZGVidWdNb2RlKSB7XG4gICAgICBjb25zb2xlLmVycm9yKCdTU1BZIEVYVEVOU0lPTicsIG1lc3NhZ2UsIC4uLm9wdGlvbmFsUGFyYW1zKTtcbiAgICB9XG4gIH1cbn1cbiJdfQ==
@@ -1,2 +1,2 @@
1
1
  import { Credentials } from '@aws-sdk/types';
2
- export declare function getWebSocketUrl(url: string, credentials?: Credentials): Promise<string>;
2
+ export declare function getSignedWebSocketUrl(url: string, credentials?: Credentials): Promise<string>;
@@ -1,19 +1,31 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getWebSocketUrl = void 0;
3
+ exports.getSignedWebSocketUrl = void 0;
4
4
  const credential_providers_1 = require("@aws-sdk/credential-providers");
5
5
  const aws4 = require("aws4");
6
6
  // ""wss://m6g3w6ttdh.execute-api.eu-west-1.amazonaws.com/prod";"
7
- async function getWebSocketUrl(url, credentials) {
8
- const urlParsed = parseUrl(url);
9
- const hostParts = urlParsed.host.split('.');
7
+ async function getSignedWebSocketUrl(url, credentials) {
8
+ let hostParts;
9
+ let pathname;
10
+ if (!url) {
11
+ throw new Error(`Missing websocket URL`);
12
+ }
13
+ try {
14
+ new URL(url); //validate URL
15
+ const urlParsed = parseUrl(url);
16
+ pathname = urlParsed.pathname;
17
+ hostParts = urlParsed.host.split('.');
18
+ }
19
+ catch {
20
+ throw new Error(`Invalid websocket URL ${url}`);
21
+ }
10
22
  if (!credentials) {
11
23
  const credentialsProvider = (0, credential_providers_1.fromNodeProviderChain)();
12
24
  credentials = await credentialsProvider();
13
25
  }
14
26
  const AWS_REGION = hostParts[2]; // The region of your API-gateway
15
27
  const SOCKET_HOST = hostParts[0]; // Your API-gateway ID
16
- const ENV = urlParsed.pathname.replace(/^\//, ''); // The stage of your target deployment
28
+ const ENV = pathname.replace(/^\//, ''); // The stage of your target deployment
17
29
  const WEBSOCKET_URL = `${SOCKET_HOST}.execute-api.${AWS_REGION}.amazonaws.com`; // Don't prepend with wss!
18
30
  // const AWS_REGION = "eu-west-1"; // The region of your API-gateway
19
31
  // const SOCKET_HOST = "m6g3w6ttdh"; // Your API-gateway ID
@@ -38,7 +50,7 @@ async function getWebSocketUrl(url, credentials) {
38
50
  const url2 = `wss://${WEBSOCKET_URL}${path}`;
39
51
  return url2;
40
52
  }
41
- exports.getWebSocketUrl = getWebSocketUrl;
53
+ exports.getSignedWebSocketUrl = getSignedWebSocketUrl;
42
54
  function parseUrl(href) {
43
55
  const match = href.match(/^(wss?:)\/\/(([^:/?#]*)(?::([0-9]+))?)([/]{0,1}[^?#]*)(\?[^#]*|)(#.*|)$/);
44
56
  return (match && {
@@ -52,4 +64,4 @@ function parseUrl(href) {
52
64
  hash: match[7],
53
65
  });
54
66
  }
55
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2V0V2ViU29ja2V0VXJsLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vY29tbW9uL2dldFdlYlNvY2tldFVybC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSx3RUFBc0U7QUFFdEUsNkJBQTZCO0FBRTdCLGlFQUFpRTtBQUUxRCxLQUFLLFVBQVUsZUFBZSxDQUFDLEdBQVcsRUFBRSxXQUF5QjtJQUMxRSxNQUFNLFNBQVMsR0FBRyxRQUFRLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDaEMsTUFBTSxTQUFTLEdBQUcsU0FBVSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7SUFFN0MsSUFBSSxDQUFDLFdBQVcsRUFBRTtRQUNoQixNQUFNLG1CQUFtQixHQUFHLElBQUEsNENBQXFCLEdBQUUsQ0FBQztRQUNwRCxXQUFXLEdBQUcsTUFBTSxtQkFBbUIsRUFBRSxDQUFDO0tBQzNDO0lBRUQsTUFBTSxVQUFVLEdBQUcsU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsaUNBQWlDO0lBQ2xFLE1BQU0sV0FBVyxHQUFHLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLHNCQUFzQjtJQUN4RCxNQUFNLEdBQUcsR0FBRyxTQUFVLENBQUMsUUFBUyxDQUFDLE9BQU8sQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxzQ0FBc0M7SUFDM0YsTUFBTSxhQUFhLEdBQUcsR0FBRyxXQUFXLGdCQUFnQixVQUFVLGdCQUFnQixDQUFDLENBQUMsMEJBQTBCO0lBQzFHLG9FQUFvRTtJQUNwRSwyREFBMkQ7SUFDM0QsNkRBQTZEO0lBQzdELDZHQUE2RztJQUU3RyxvQkFBb0I7SUFDcEIsTUFBTSxFQUFFLElBQUksRUFBRSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQ3hCO1FBQ0UsTUFBTSxFQUFFLEtBQUs7UUFDYixJQUFJLEVBQUUsYUFBYTtRQUNuQiw0REFBNEQ7UUFDNUQsK0JBQStCO1FBQy9CLE9BQU87UUFDUCxJQUFJLEVBQUUsSUFBSSxHQUFHLEVBQUU7UUFDZixPQUFPLEVBQUUsYUFBYTtRQUN0QixNQUFNLEVBQUUsVUFBVTtRQUNsQixTQUFTLEVBQUUsSUFBSTtLQUNoQixFQUNEO1FBQ0UsV0FBVyxFQUFFLFdBQVcsQ0FBQyxXQUFXO1FBQ3BDLGVBQWUsRUFBRSxXQUFXLENBQUMsZUFBZTtRQUM1QyxZQUFZLEVBQUUsV0FBVyxDQUFDLFlBQVk7S0FDdkMsQ0FDRixDQUFDO0lBRUYsTUFBTSxJQUFJLEdBQUcsU0FBUyxhQUFhLEdBQUcsSUFBSSxFQUFFLENBQUM7SUFDN0MsT0FBTyxJQUFJLENBQUM7QUFDZCxDQUFDO0FBeENELDBDQXdDQztBQUVELFNBQVMsUUFBUSxDQUFDLElBQVk7SUFDNUIsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FDdEIseUVBQXlFLENBQzFFLENBQUM7SUFDRixPQUFPLENBQ0wsS0FBSyxJQUFJO1FBQ1AsSUFBSTtRQUNKLFFBQVEsRUFBRSxLQUFLLENBQUMsQ0FBQyxDQUFDO1FBQ2xCLElBQUksRUFBRSxLQUFLLENBQUMsQ0FBQyxDQUFDO1FBQ2QsUUFBUSxFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUM7UUFDbEIsSUFBSSxFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUM7UUFDZCxRQUFRLEVBQUUsS0FBSyxDQUFDLENBQUMsQ0FBQztRQUNsQixNQUFNLEVBQUUsS0FBSyxDQUFDLENBQUMsQ0FBQztRQUNoQixJQUFJLEVBQUUsS0FBSyxDQUFDLENBQUMsQ0FBQztLQUNmLENBQ0YsQ0FBQztBQUNKLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBmcm9tTm9kZVByb3ZpZGVyQ2hhaW4gfSBmcm9tICdAYXdzLXNkay9jcmVkZW50aWFsLXByb3ZpZGVycyc7XG5pbXBvcnQgeyBDcmVkZW50aWFscyB9IGZyb20gJ0Bhd3Mtc2RrL3R5cGVzJztcbmltcG9ydCAqIGFzIGF3czQgZnJvbSAnYXdzNCc7XG5cbi8vIFwiXCJ3c3M6Ly9tNmczdzZ0dGRoLmV4ZWN1dGUtYXBpLmV1LXdlc3QtMS5hbWF6b25hd3MuY29tL3Byb2RcIjtcIlxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZ2V0V2ViU29ja2V0VXJsKHVybDogc3RyaW5nLCBjcmVkZW50aWFscz86IENyZWRlbnRpYWxzKSB7XG4gIGNvbnN0IHVybFBhcnNlZCA9IHBhcnNlVXJsKHVybCk7XG4gIGNvbnN0IGhvc3RQYXJ0cyA9IHVybFBhcnNlZCEuaG9zdC5zcGxpdCgnLicpO1xuXG4gIGlmICghY3JlZGVudGlhbHMpIHtcbiAgICBjb25zdCBjcmVkZW50aWFsc1Byb3ZpZGVyID0gZnJvbU5vZGVQcm92aWRlckNoYWluKCk7XG4gICAgY3JlZGVudGlhbHMgPSBhd2FpdCBjcmVkZW50aWFsc1Byb3ZpZGVyKCk7XG4gIH1cblxuICBjb25zdCBBV1NfUkVHSU9OID0gaG9zdFBhcnRzWzJdOyAvLyBUaGUgcmVnaW9uIG9mIHlvdXIgQVBJLWdhdGV3YXlcbiAgY29uc3QgU09DS0VUX0hPU1QgPSBob3N0UGFydHNbMF07IC8vIFlvdXIgQVBJLWdhdGV3YXkgSURcbiAgY29uc3QgRU5WID0gdXJsUGFyc2VkIS5wYXRobmFtZSEucmVwbGFjZSgvXlxcLy8sICcnKTsgLy8gVGhlIHN0YWdlIG9mIHlvdXIgdGFyZ2V0IGRlcGxveW1lbnRcbiAgY29uc3QgV0VCU09DS0VUX1VSTCA9IGAke1NPQ0tFVF9IT1NUfS5leGVjdXRlLWFwaS4ke0FXU19SRUdJT059LmFtYXpvbmF3cy5jb21gOyAvLyBEb24ndCBwcmVwZW5kIHdpdGggd3NzIVxuICAvLyBjb25zdCBBV1NfUkVHSU9OID0gXCJldS13ZXN0LTFcIjsgLy8gVGhlIHJlZ2lvbiBvZiB5b3VyIEFQSS1nYXRld2F5XG4gIC8vIGNvbnN0IFNPQ0tFVF9IT1NUID0gXCJtNmczdzZ0dGRoXCI7IC8vIFlvdXIgQVBJLWdhdGV3YXkgSURcbiAgLy8gY29uc3QgRU5WID0gXCJwcm9kXCI7IC8vIFRoZSBzdGFnZSBvZiB5b3VyIHRhcmdldCBkZXBsb3ltZW50XG4gIC8vIGNvbnN0IFdFQlNPQ0tFVF9VUkwgPSBgJHtTT0NLRVRfSE9TVH0uZXhlY3V0ZS1hcGkuJHtBV1NfUkVHSU9OfS5hbWF6b25hd3MuY29tYDsgLy8gRG9uJ3QgcHJlcGVuZCB3aXRoIHdzcyFcblxuICAvLyBHZXQgYSBzaWduZWQgcGF0aFxuICBjb25zdCB7IHBhdGggfSA9IGF3czQuc2lnbihcbiAgICB7XG4gICAgICBtZXRob2Q6ICdHRVQnLFxuICAgICAgaG9zdDogV0VCU09DS0VUX1VSTCxcbiAgICAgIC8vIHBhdGg6IGAvJHtFTlZ9P1gtQW16LVNlY3VyaXR5LVRva2VuPSR7ZW5jb2RlVVJJQ29tcG9uZW50KFxuICAgICAgLy8gICBjcmVkZW50aWFscyEuU2Vzc2lvblRva2VuIVxuICAgICAgLy8gKX1gLFxuICAgICAgcGF0aDogYC8ke0VOVn1gLFxuICAgICAgc2VydmljZTogJ2V4ZWN1dGUtYXBpJyxcbiAgICAgIHJlZ2lvbjogQVdTX1JFR0lPTixcbiAgICAgIHNpZ25RdWVyeTogdHJ1ZSxcbiAgICB9LFxuICAgIHtcbiAgICAgIGFjY2Vzc0tleUlkOiBjcmVkZW50aWFscy5hY2Nlc3NLZXlJZCxcbiAgICAgIHNlY3JldEFjY2Vzc0tleTogY3JlZGVudGlhbHMuc2VjcmV0QWNjZXNzS2V5LFxuICAgICAgc2Vzc2lvblRva2VuOiBjcmVkZW50aWFscy5zZXNzaW9uVG9rZW4sXG4gICAgfVxuICApO1xuXG4gIGNvbnN0IHVybDIgPSBgd3NzOi8vJHtXRUJTT0NLRVRfVVJMfSR7cGF0aH1gO1xuICByZXR1cm4gdXJsMjtcbn1cblxuZnVuY3Rpb24gcGFyc2VVcmwoaHJlZjogc3RyaW5nKSB7XG4gIGNvbnN0IG1hdGNoID0gaHJlZi5tYXRjaChcbiAgICAvXih3c3M/OilcXC9cXC8oKFteOi8/I10qKSg/OjooWzAtOV0rKSk/KShbL117MCwxfVtePyNdKikoXFw/W14jXSp8KSgjLip8KSQvXG4gICk7XG4gIHJldHVybiAoXG4gICAgbWF0Y2ggJiYge1xuICAgICAgaHJlZixcbiAgICAgIHByb3RvY29sOiBtYXRjaFsxXSxcbiAgICAgIGhvc3Q6IG1hdGNoWzJdLFxuICAgICAgaG9zdG5hbWU6IG1hdGNoWzNdLFxuICAgICAgcG9ydDogbWF0Y2hbNF0sXG4gICAgICBwYXRobmFtZTogbWF0Y2hbNV0sXG4gICAgICBzZWFyY2g6IG1hdGNoWzZdLFxuICAgICAgaGFzaDogbWF0Y2hbN10sXG4gICAgfVxuICApO1xufVxuIl19
67
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2V0V2ViU29ja2V0VXJsLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vY29tbW9uL2dldFdlYlNvY2tldFVybC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSx3RUFBc0U7QUFFdEUsNkJBQTZCO0FBRTdCLGlFQUFpRTtBQUUxRCxLQUFLLFVBQVUscUJBQXFCLENBQ3pDLEdBQVcsRUFDWCxXQUF5QjtJQUV6QixJQUFJLFNBQW1CLENBQUM7SUFDeEIsSUFBSSxRQUFnQixDQUFDO0lBRXJCLElBQUksQ0FBQyxHQUFHLEVBQUU7UUFDUixNQUFNLElBQUksS0FBSyxDQUFDLHVCQUF1QixDQUFDLENBQUM7S0FDMUM7SUFFRCxJQUFJO1FBQ0YsSUFBSSxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxjQUFjO1FBRTVCLE1BQU0sU0FBUyxHQUFHLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUNoQyxRQUFRLEdBQUcsU0FBVSxDQUFDLFFBQVMsQ0FBQztRQUNoQyxTQUFTLEdBQUcsU0FBVSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7S0FDeEM7SUFBQyxNQUFNO1FBQ04sTUFBTSxJQUFJLEtBQUssQ0FBQyx5QkFBeUIsR0FBRyxFQUFFLENBQUMsQ0FBQztLQUNqRDtJQUVELElBQUksQ0FBQyxXQUFXLEVBQUU7UUFDaEIsTUFBTSxtQkFBbUIsR0FBRyxJQUFBLDRDQUFxQixHQUFFLENBQUM7UUFDcEQsV0FBVyxHQUFHLE1BQU0sbUJBQW1CLEVBQUUsQ0FBQztLQUMzQztJQUVELE1BQU0sVUFBVSxHQUFHLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLGlDQUFpQztJQUNsRSxNQUFNLFdBQVcsR0FBRyxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxzQkFBc0I7SUFDeEQsTUFBTSxHQUFHLEdBQUcsUUFBUSxDQUFDLE9BQU8sQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxzQ0FBc0M7SUFDL0UsTUFBTSxhQUFhLEdBQUcsR0FBRyxXQUFXLGdCQUFnQixVQUFVLGdCQUFnQixDQUFDLENBQUMsMEJBQTBCO0lBQzFHLG9FQUFvRTtJQUNwRSwyREFBMkQ7SUFDM0QsNkRBQTZEO0lBQzdELDZHQUE2RztJQUU3RyxvQkFBb0I7SUFDcEIsTUFBTSxFQUFFLElBQUksRUFBRSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQ3hCO1FBQ0UsTUFBTSxFQUFFLEtBQUs7UUFDYixJQUFJLEVBQUUsYUFBYTtRQUNuQiw0REFBNEQ7UUFDNUQsK0JBQStCO1FBQy9CLE9BQU87UUFDUCxJQUFJLEVBQUUsSUFBSSxHQUFHLEVBQUU7UUFDZixPQUFPLEVBQUUsYUFBYTtRQUN0QixNQUFNLEVBQUUsVUFBVTtRQUNsQixTQUFTLEVBQUUsSUFBSTtLQUNoQixFQUNEO1FBQ0UsV0FBVyxFQUFFLFdBQVcsQ0FBQyxXQUFXO1FBQ3BDLGVBQWUsRUFBRSxXQUFXLENBQUMsZUFBZTtRQUM1QyxZQUFZLEVBQUUsV0FBVyxDQUFDLFlBQVk7S0FDdkMsQ0FDRixDQUFDO0lBRUYsTUFBTSxJQUFJLEdBQUcsU0FBUyxhQUFhLEdBQUcsSUFBSSxFQUFFLENBQUM7SUFDN0MsT0FBTyxJQUFJLENBQUM7QUFDZCxDQUFDO0FBekRELHNEQXlEQztBQUVELFNBQVMsUUFBUSxDQUFDLElBQVk7SUFDNUIsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FDdEIseUVBQXlFLENBQzFFLENBQUM7SUFDRixPQUFPLENBQ0wsS0FBSyxJQUFJO1FBQ1AsSUFBSTtRQUNKLFFBQVEsRUFBRSxLQUFLLENBQUMsQ0FBQyxDQUFDO1FBQ2xCLElBQUksRUFBRSxLQUFLLENBQUMsQ0FBQyxDQUFDO1FBQ2QsUUFBUSxFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUM7UUFDbEIsSUFBSSxFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUM7UUFDZCxRQUFRLEVBQUUsS0FBSyxDQUFDLENBQUMsQ0FBQztRQUNsQixNQUFNLEVBQUUsS0FBSyxDQUFDLENBQUMsQ0FBQztRQUNoQixJQUFJLEVBQUUsS0FBSyxDQUFDLENBQUMsQ0FBQztLQUNmLENBQ0YsQ0FBQztBQUNKLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBmcm9tTm9kZVByb3ZpZGVyQ2hhaW4gfSBmcm9tICdAYXdzLXNkay9jcmVkZW50aWFsLXByb3ZpZGVycyc7XG5pbXBvcnQgeyBDcmVkZW50aWFscyB9IGZyb20gJ0Bhd3Mtc2RrL3R5cGVzJztcbmltcG9ydCAqIGFzIGF3czQgZnJvbSAnYXdzNCc7XG5cbi8vIFwiXCJ3c3M6Ly9tNmczdzZ0dGRoLmV4ZWN1dGUtYXBpLmV1LXdlc3QtMS5hbWF6b25hd3MuY29tL3Byb2RcIjtcIlxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZ2V0U2lnbmVkV2ViU29ja2V0VXJsKFxuICB1cmw6IHN0cmluZyxcbiAgY3JlZGVudGlhbHM/OiBDcmVkZW50aWFsc1xuKSB7XG4gIGxldCBob3N0UGFydHM6IHN0cmluZ1tdO1xuICBsZXQgcGF0aG5hbWU6IHN0cmluZztcblxuICBpZiAoIXVybCkge1xuICAgIHRocm93IG5ldyBFcnJvcihgTWlzc2luZyB3ZWJzb2NrZXQgVVJMYCk7XG4gIH1cblxuICB0cnkge1xuICAgIG5ldyBVUkwodXJsKTsgLy92YWxpZGF0ZSBVUkxcblxuICAgIGNvbnN0IHVybFBhcnNlZCA9IHBhcnNlVXJsKHVybCk7XG4gICAgcGF0aG5hbWUgPSB1cmxQYXJzZWQhLnBhdGhuYW1lITtcbiAgICBob3N0UGFydHMgPSB1cmxQYXJzZWQhLmhvc3Quc3BsaXQoJy4nKTtcbiAgfSBjYXRjaCB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBJbnZhbGlkIHdlYnNvY2tldCBVUkwgJHt1cmx9YCk7XG4gIH1cblxuICBpZiAoIWNyZWRlbnRpYWxzKSB7XG4gICAgY29uc3QgY3JlZGVudGlhbHNQcm92aWRlciA9IGZyb21Ob2RlUHJvdmlkZXJDaGFpbigpO1xuICAgIGNyZWRlbnRpYWxzID0gYXdhaXQgY3JlZGVudGlhbHNQcm92aWRlcigpO1xuICB9XG5cbiAgY29uc3QgQVdTX1JFR0lPTiA9IGhvc3RQYXJ0c1syXTsgLy8gVGhlIHJlZ2lvbiBvZiB5b3VyIEFQSS1nYXRld2F5XG4gIGNvbnN0IFNPQ0tFVF9IT1NUID0gaG9zdFBhcnRzWzBdOyAvLyBZb3VyIEFQSS1nYXRld2F5IElEXG4gIGNvbnN0IEVOViA9IHBhdGhuYW1lLnJlcGxhY2UoL15cXC8vLCAnJyk7IC8vIFRoZSBzdGFnZSBvZiB5b3VyIHRhcmdldCBkZXBsb3ltZW50XG4gIGNvbnN0IFdFQlNPQ0tFVF9VUkwgPSBgJHtTT0NLRVRfSE9TVH0uZXhlY3V0ZS1hcGkuJHtBV1NfUkVHSU9OfS5hbWF6b25hd3MuY29tYDsgLy8gRG9uJ3QgcHJlcGVuZCB3aXRoIHdzcyFcbiAgLy8gY29uc3QgQVdTX1JFR0lPTiA9IFwiZXUtd2VzdC0xXCI7IC8vIFRoZSByZWdpb24gb2YgeW91ciBBUEktZ2F0ZXdheVxuICAvLyBjb25zdCBTT0NLRVRfSE9TVCA9IFwibTZnM3c2dHRkaFwiOyAvLyBZb3VyIEFQSS1nYXRld2F5IElEXG4gIC8vIGNvbnN0IEVOViA9IFwicHJvZFwiOyAvLyBUaGUgc3RhZ2Ugb2YgeW91ciB0YXJnZXQgZGVwbG95bWVudFxuICAvLyBjb25zdCBXRUJTT0NLRVRfVVJMID0gYCR7U09DS0VUX0hPU1R9LmV4ZWN1dGUtYXBpLiR7QVdTX1JFR0lPTn0uYW1hem9uYXdzLmNvbWA7IC8vIERvbid0IHByZXBlbmQgd2l0aCB3c3MhXG5cbiAgLy8gR2V0IGEgc2lnbmVkIHBhdGhcbiAgY29uc3QgeyBwYXRoIH0gPSBhd3M0LnNpZ24oXG4gICAge1xuICAgICAgbWV0aG9kOiAnR0VUJyxcbiAgICAgIGhvc3Q6IFdFQlNPQ0tFVF9VUkwsXG4gICAgICAvLyBwYXRoOiBgLyR7RU5WfT9YLUFtei1TZWN1cml0eS1Ub2tlbj0ke2VuY29kZVVSSUNvbXBvbmVudChcbiAgICAgIC8vICAgY3JlZGVudGlhbHMhLlNlc3Npb25Ub2tlbiFcbiAgICAgIC8vICl9YCxcbiAgICAgIHBhdGg6IGAvJHtFTlZ9YCxcbiAgICAgIHNlcnZpY2U6ICdleGVjdXRlLWFwaScsXG4gICAgICByZWdpb246IEFXU19SRUdJT04sXG4gICAgICBzaWduUXVlcnk6IHRydWUsXG4gICAgfSxcbiAgICB7XG4gICAgICBhY2Nlc3NLZXlJZDogY3JlZGVudGlhbHMuYWNjZXNzS2V5SWQsXG4gICAgICBzZWNyZXRBY2Nlc3NLZXk6IGNyZWRlbnRpYWxzLnNlY3JldEFjY2Vzc0tleSxcbiAgICAgIHNlc3Npb25Ub2tlbjogY3JlZGVudGlhbHMuc2Vzc2lvblRva2VuLFxuICAgIH1cbiAgKTtcblxuICBjb25zdCB1cmwyID0gYHdzczovLyR7V0VCU09DS0VUX1VSTH0ke3BhdGh9YDtcbiAgcmV0dXJuIHVybDI7XG59XG5cbmZ1bmN0aW9uIHBhcnNlVXJsKGhyZWY6IHN0cmluZykge1xuICBjb25zdCBtYXRjaCA9IGhyZWYubWF0Y2goXG4gICAgL14od3NzPzopXFwvXFwvKChbXjovPyNdKikoPzo6KFswLTldKykpPykoWy9dezAsMX1bXj8jXSopKFxcP1teI10qfCkoIy4qfCkkL1xuICApO1xuICByZXR1cm4gKFxuICAgIG1hdGNoICYmIHtcbiAgICAgIGhyZWYsXG4gICAgICBwcm90b2NvbDogbWF0Y2hbMV0sXG4gICAgICBob3N0OiBtYXRjaFsyXSxcbiAgICAgIGhvc3RuYW1lOiBtYXRjaFszXSxcbiAgICAgIHBvcnQ6IG1hdGNoWzRdLFxuICAgICAgcGF0aG5hbWU6IG1hdGNoWzVdLFxuICAgICAgc2VhcmNoOiBtYXRjaFs2XSxcbiAgICAgIGhhc2g6IG1hdGNoWzddLFxuICAgIH1cbiAgKTtcbn1cbiJdfQ==