@prismatic-io/components-aws-sns 0.0.0-stage → 0.0.1

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.
@@ -0,0 +1,1326 @@
1
+ //#region \0rolldown/runtime.js
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __copyProps = (to, from, except, desc) => {
9
+ if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
10
+ key = keys[i];
11
+ if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
12
+ get: ((k) => from[k]).bind(null, key),
13
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
14
+ });
15
+ }
16
+ return to;
17
+ };
18
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
19
+ value: mod,
20
+ enumerable: true
21
+ }) : target, mod));
22
+ //#endregion
23
+ let _prismatic_io_spectral = require("@prismatic-io/spectral");
24
+ let _aws_sdk_client_sns = require("@aws-sdk/client-sns");
25
+ let _aws_sdk_client_sts = require("@aws-sdk/client-sts");
26
+ let sns_validator = require("sns-validator");
27
+ sns_validator = __toESM(sns_validator);
28
+ let _prismatic_io_spectral_http = require("@prismatic-io/spectral/http");
29
+ //#region ../../packages/aws-utils/dist/connection/assumeRole.js
30
+ var __awaiter$3 = function(thisArg, _arguments, P, generator) {
31
+ function adopt(value) {
32
+ return value instanceof P ? value : new P(function(resolve) {
33
+ resolve(value);
34
+ });
35
+ }
36
+ return new (P || (P = Promise))(function(resolve, reject) {
37
+ function fulfilled(value) {
38
+ try {
39
+ step(generator.next(value));
40
+ } catch (e) {
41
+ reject(e);
42
+ }
43
+ }
44
+ function rejected(value) {
45
+ try {
46
+ step(generator["throw"](value));
47
+ } catch (e) {
48
+ reject(e);
49
+ }
50
+ }
51
+ function step(result) {
52
+ result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected);
53
+ }
54
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
55
+ });
56
+ };
57
+ const assumeRole = (region, accessKeyId, secretAccessKey, roleArn, externalId) => __awaiter$3(void 0, void 0, void 0, function* () {
58
+ const { Credentials: { AccessKeyId, SecretAccessKey, SessionToken } } = yield new _aws_sdk_client_sts.STSClient(Object.assign(Object.assign({}, region.length > 0 && { region }), { credentials: {
59
+ accessKeyId,
60
+ secretAccessKey
61
+ } })).send(new _aws_sdk_client_sts.AssumeRoleCommand({
62
+ RoleArn: _prismatic_io_spectral.util.types.toString(roleArn),
63
+ RoleSessionName: "integration-session",
64
+ ExternalId: externalId
65
+ }));
66
+ return {
67
+ accessKeyId: AccessKeyId,
68
+ secretAccessKey: SecretAccessKey,
69
+ sessionToken: SessionToken
70
+ };
71
+ });
72
+ //#endregion
73
+ //#region ../../packages/aws-utils/dist/connection/assumeRoleConnection.js
74
+ const assumeRoleConnection = {
75
+ key: "awsAssumeRole",
76
+ display: {
77
+ label: "AWS Role ARN",
78
+ description: "Connect to AWS using an assumed role"
79
+ },
80
+ inputs: {
81
+ roleARN: {
82
+ label: "Role ARN",
83
+ placeholder: "arn:aws:iam::OtherAccount-ID:role/assumed-role-name",
84
+ type: "string",
85
+ required: true,
86
+ shown: true,
87
+ comments: "An AWS IAM Role ARN",
88
+ example: "arn:aws:iam::OtherAccount-ID:role/assumed-role-name"
89
+ },
90
+ accessKeyId: {
91
+ label: "Access Key ID",
92
+ placeholder: "Access Key ID",
93
+ type: "string",
94
+ required: true,
95
+ shown: true,
96
+ comments: "An AWS IAM Access Key ID",
97
+ example: "AKIAIOSFODNN7EXAMPLE"
98
+ },
99
+ secretAccessKey: {
100
+ label: "Secret Access Key",
101
+ placeholder: "Secret Access Key",
102
+ type: "password",
103
+ required: true,
104
+ shown: true,
105
+ comments: "An AWS IAM Secret Access Key",
106
+ example: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
107
+ },
108
+ externalId: {
109
+ label: "External ID",
110
+ placeholder: "shared-common-secret",
111
+ type: "string",
112
+ required: false,
113
+ shown: true,
114
+ comments: "Provides enhanced security measures to the connection. Optional, but recommended. Please check [AWS docs](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_common-scenarios_third-party.html#id_roles_third-party_external-id) for more information.",
115
+ example: "shared-common-secret"
116
+ }
117
+ }
118
+ };
119
+ //#endregion
120
+ //#region ../../packages/aws-utils/dist/helpers/misc.js
121
+ const toTrimmedString = (value) => _prismatic_io_spectral.util.types.toString(value).trim();
122
+ const toOptionalString = (value) => value ? _prismatic_io_spectral.util.types.toString(value) : void 0;
123
+ //#endregion
124
+ //#region ../../packages/aws-utils/dist/data/awsRegions.js
125
+ const awsRegions = [
126
+ "af-south-1",
127
+ "ap-east-1",
128
+ "ap-east-2",
129
+ "ap-northeast-1",
130
+ "ap-northeast-2",
131
+ "ap-northeast-3",
132
+ "ap-south-1",
133
+ "ap-south-2",
134
+ "ap-southeast-1",
135
+ "ap-southeast-2",
136
+ "ap-southeast-3",
137
+ "ap-southeast-4",
138
+ "ap-southeast-5",
139
+ "ap-southeast-6",
140
+ "ap-southeast-7",
141
+ "ca-central-1",
142
+ "ca-west-1",
143
+ "eu-central-1",
144
+ "eu-central-2",
145
+ "eu-north-1",
146
+ "eu-south-1",
147
+ "eu-south-2",
148
+ "eu-west-1",
149
+ "eu-west-2",
150
+ "eu-west-3",
151
+ "il-central-1",
152
+ "me-central-1",
153
+ "me-south-1",
154
+ "mx-central-1",
155
+ "sa-east-1",
156
+ "us-east-1",
157
+ "us-east-2",
158
+ "us-gov-east-1",
159
+ "us-gov-west-1",
160
+ "us-west-1",
161
+ "us-west-2"
162
+ ];
163
+ //#endregion
164
+ //#region ../../packages/aws-utils/dist/dataSources/selectRegion.js
165
+ var __awaiter$1 = function(thisArg, _arguments, P, generator) {
166
+ function adopt(value) {
167
+ return value instanceof P ? value : new P(function(resolve) {
168
+ resolve(value);
169
+ });
170
+ }
171
+ return new (P || (P = Promise))(function(resolve, reject) {
172
+ function fulfilled(value) {
173
+ try {
174
+ step(generator.next(value));
175
+ } catch (e) {
176
+ reject(e);
177
+ }
178
+ }
179
+ function rejected(value) {
180
+ try {
181
+ step(generator["throw"](value));
182
+ } catch (e) {
183
+ reject(e);
184
+ }
185
+ }
186
+ function step(result) {
187
+ result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected);
188
+ }
189
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
190
+ });
191
+ };
192
+ const selectRegion = (0, _prismatic_io_spectral.dataSource)({
193
+ display: {
194
+ label: "Select AWS Region",
195
+ description: "Select an AWS region"
196
+ },
197
+ dataSourceType: "picklist",
198
+ perform: () => __awaiter$1(void 0, void 0, void 0, function* () {
199
+ return Promise.resolve({ result: awsRegions.map((region) => ({
200
+ label: region,
201
+ key: region
202
+ })) });
203
+ }),
204
+ inputs: {}
205
+ });
206
+ //#endregion
207
+ //#region ../../packages/aws-utils/dist/inputs/awsRegion.js
208
+ const awsRegion$1 = (0, _prismatic_io_spectral.input)({
209
+ label: "AWS Region",
210
+ placeholder: "AWS Region",
211
+ type: "string",
212
+ required: false,
213
+ comments: "AWS provides services in multiple regions, like us-west-2 or eu-west-1.",
214
+ example: "us-east-1",
215
+ dataSource: "selectRegion",
216
+ clean: _prismatic_io_spectral.util.types.toString
217
+ });
218
+ (0, _prismatic_io_spectral.input)({
219
+ label: "Connection",
220
+ type: "connection",
221
+ required: false
222
+ });
223
+ (0, _prismatic_io_spectral.input)({
224
+ label: "Dynamic Access Key ID",
225
+ type: "string",
226
+ required: false,
227
+ clean: _prismatic_io_spectral.util.types.toString,
228
+ comments: "Use this input to authenticate with AWS if you are using a dynamically-generated access key. Otherwise, use the connection to enter a static access key ID."
229
+ });
230
+ (0, _prismatic_io_spectral.input)({
231
+ label: "Dynamic Secret Access Key",
232
+ type: "password",
233
+ required: false,
234
+ clean: _prismatic_io_spectral.util.types.toString,
235
+ comments: "Use this input to authenticate with AWS if you are using a dynamically-generated secret access key. Otherwise, use the connection to enter a static secret access key."
236
+ });
237
+ (0, _prismatic_io_spectral.input)({
238
+ label: "Dynamic Session Token",
239
+ type: "password",
240
+ required: false,
241
+ clean: (value) => _prismatic_io_spectral.util.types.toString(value) || void 0,
242
+ comments: "Use this input to authenticate with AWS if you are using a OPTIONAL dynamically-generated session token."
243
+ });
244
+ //#endregion
245
+ //#region src/connections.ts
246
+ const accessKeySecretPair = (0, _prismatic_io_spectral.connection)({
247
+ key: "apiKeySecret",
248
+ display: {
249
+ label: "Access Key",
250
+ description: "Access Key connection for AWS SNS"
251
+ },
252
+ inputs: {
253
+ accessKeyId: {
254
+ label: "Access Key ID",
255
+ placeholder: "Enter Access Key ID",
256
+ type: "string",
257
+ required: true,
258
+ shown: true,
259
+ comments: "An AWS IAM Access Key ID for authenticating with Amazon SNS. [Learn more](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_access-keys.html)",
260
+ example: "AKIAIOSFODNN7EXAMPLE"
261
+ },
262
+ secretAccessKey: {
263
+ label: "Secret Access Key",
264
+ placeholder: "Enter Secret Access Key",
265
+ type: "password",
266
+ required: true,
267
+ shown: true,
268
+ comments: "An AWS IAM Secret Access Key corresponding to the Access Key ID. [Learn more](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_access-keys.html)",
269
+ example: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
270
+ }
271
+ }
272
+ });
273
+ var connections_default = [accessKeySecretPair, assumeRoleConnection];
274
+ //#endregion
275
+ //#region src/helpers/index.ts
276
+ const validateConnection = (connection) => {
277
+ if (![accessKeySecretPair.key, assumeRoleConnection.key].includes(connection.key)) throw new _prismatic_io_spectral.ConnectionError(connection, `Unsupported connection method ${connection.key}.`);
278
+ };
279
+ const getCredentials = (connection) => {
280
+ validateConnection(connection);
281
+ return {
282
+ accessKeyId: toTrimmedString(connection.fields.accessKeyId),
283
+ secretAccessKey: toTrimmedString(connection.fields.secretAccessKey)
284
+ };
285
+ };
286
+ //#endregion
287
+ //#region src/client.ts
288
+ const createSNSClient = async ({ awsRegion, awsConnection, debug, logger }) => {
289
+ const { accessKeyId, secretAccessKey } = getCredentials(awsConnection);
290
+ const credentials = awsConnection.key === assumeRoleConnection.key ? await assumeRole(awsRegion, accessKeyId, secretAccessKey, toTrimmedString(awsConnection.fields.roleARN), toOptionalString(awsConnection.fields?.externalId)) : {
291
+ accessKeyId,
292
+ secretAccessKey
293
+ };
294
+ const region = awsRegion.length > 0 ? awsRegion : void 0;
295
+ try {
296
+ return new _aws_sdk_client_sns.SNSClient({
297
+ region,
298
+ credentials,
299
+ logger: debug ? logger : void 0
300
+ });
301
+ } catch (err) {
302
+ throw new _prismatic_io_spectral.ConnectionError(awsConnection, `Invalid AWS Credentials have been configured. This is sometimes caused by missing characters from a copy/paste. Original AWS error message: ${err.message}`);
303
+ }
304
+ };
305
+ //#endregion
306
+ //#region src/constants/batchMessageEntriesExample.ts
307
+ const batchMessageEntriesExample = [
308
+ {
309
+ Id: "AN_ID",
310
+ Message: "A_MESSAGE",
311
+ Subject: "A_SUBJECT",
312
+ MessageStructure: "A_MESSAGE_STRUCTURE",
313
+ MessageAttributes: { "<keys>": {
314
+ DataType: "Number",
315
+ StringValue: "123"
316
+ } },
317
+ MessageDeduplicationId: "A_MESSAGE_DEDUPLICATION_ID",
318
+ MessageGroupId: "A_MESSAGE_GROUP_ID"
319
+ },
320
+ {
321
+ Id: "AN_ID",
322
+ Message: "A_MESSAGE",
323
+ Subject: "A_SUBJECT",
324
+ MessageStructure: "A_MESSAGE_STRUCTURE",
325
+ MessageAttributes: { "<keys>": {
326
+ DataType: "String.Array",
327
+ StringValue: "[\"test\", true, 123]"
328
+ } },
329
+ MessageDeduplicationId: "A_MESSAGE_DEDUPLICATION_ID",
330
+ MessageGroupId: "A_MESSAGE_GROUP_ID"
331
+ },
332
+ {
333
+ Id: "AN_ID",
334
+ Message: "A_MESSAGE",
335
+ Subject: "A_SUBJECT",
336
+ MessageStructure: "A_MESSAGE_STRUCTURE",
337
+ MessageAttributes: { "<keys>": {
338
+ DataType: "String",
339
+ StringValue: "test"
340
+ } },
341
+ MessageDeduplicationId: "A_MESSAGE_DEDUPLICATION_ID",
342
+ MessageGroupId: "A_MESSAGE_GROUP_ID"
343
+ },
344
+ {
345
+ Id: "AN_ID",
346
+ Message: "A_MESSAGE",
347
+ Subject: "A_SUBJECT",
348
+ MessageStructure: "A_MESSAGE_STRUCTURE",
349
+ MessageAttributes: { "<keys>": {
350
+ DataType: "Binary",
351
+ BinaryValue: "ADD A BUFFER HERE WITH A TEMPLATE FIELD"
352
+ } },
353
+ MessageDeduplicationId: "A_MESSAGE_DEDUPLICATION_ID",
354
+ MessageGroupId: "A_MESSAGE_GROUP_ID"
355
+ }
356
+ ];
357
+ //#endregion
358
+ //#region src/constants.ts
359
+ const STORE_KEY = "crossFlowState";
360
+ //#endregion
361
+ //#region src/utils.ts
362
+ const cleanStringInput = toOptionalString;
363
+ const lowerCaseHeaders = (headers) => Object.entries(headers).reduce((result, [key, val]) => {
364
+ result[key.toLowerCase()] = val;
365
+ return result;
366
+ }, {});
367
+ const fetchTopics = async (sns, fetchAllTopics, nextToken) => {
368
+ const command = new _aws_sdk_client_sns.ListTopicsCommand(fetchAllTopics ? {} : { NextToken: nextToken });
369
+ const response = await sns.send(command);
370
+ if (fetchAllTopics) {
371
+ const allTopics = response.Topics || [];
372
+ let nextToken = response.NextToken || void 0;
373
+ while (nextToken) {
374
+ const command = new _aws_sdk_client_sns.ListTopicsCommand({ NextToken: nextToken });
375
+ const response = await sns.send(command);
376
+ allTopics.push(...response.Topics);
377
+ nextToken = response.NextToken;
378
+ }
379
+ response.Topics = allTopics;
380
+ response.NextToken = void 0;
381
+ }
382
+ return response;
383
+ };
384
+ const fetchSubscriptions = async (sns, topicArn, fetchAllSubscriptions, nextToken) => {
385
+ const command = new _aws_sdk_client_sns.ListSubscriptionsByTopicCommand({
386
+ TopicArn: topicArn,
387
+ NextToken: fetchAllSubscriptions ? void 0 : nextToken
388
+ });
389
+ const response = await sns.send(command);
390
+ if (fetchAllSubscriptions) {
391
+ const allSubscriptions = response.Subscriptions || [];
392
+ let nextToken = response.NextToken || void 0;
393
+ while (nextToken) {
394
+ const command = new _aws_sdk_client_sns.ListSubscriptionsByTopicCommand({
395
+ TopicArn: topicArn,
396
+ NextToken: nextToken
397
+ });
398
+ const response = await sns.send(command);
399
+ allSubscriptions.push(...response.Subscriptions);
400
+ nextToken = response.NextToken;
401
+ }
402
+ response.Subscriptions = allSubscriptions;
403
+ response.NextToken = void 0;
404
+ }
405
+ return response;
406
+ };
407
+ const webhookPerformFn = async ({ logger, debug: { enabled: debug } }, payload, { parseMessage }) => {
408
+ const validator = new sns_validator.default();
409
+ const originalHeaders = payload.headers;
410
+ payload.headers = lowerCaseHeaders(payload.headers);
411
+ const _parseMessage = payload.headers["x-amz-sns-message-type"] === "Notification" && _prismatic_io_spectral.util.types.toBool(parseMessage);
412
+ const validateMessage = async ({ rawBody: { data }, headers }) => {
413
+ if (headers["x-amz-sns-rawdelivery"] === "true") return _parseMessage ? JSON.parse(_prismatic_io_spectral.util.types.toString(data) || "{}") : _prismatic_io_spectral.util.types.toString(data);
414
+ return await new Promise((resolve, reject) => {
415
+ validator.validate(_prismatic_io_spectral.util.types.toString(data), (error, message) => {
416
+ if (error) {
417
+ logger.error(`SNS Message could not be verified with error: ${error}`);
418
+ return reject(error);
419
+ }
420
+ return resolve(message);
421
+ });
422
+ });
423
+ };
424
+ const message = await validateMessage(payload);
425
+ let branch = "";
426
+ const messageType = payload.headers["x-amz-sns-message-type"];
427
+ const client = (0, _prismatic_io_spectral_http.createClient)({
428
+ baseUrl: message.SubscribeURL,
429
+ debug
430
+ });
431
+ switch (messageType) {
432
+ case "SubscriptionConfirmation":
433
+ await client.get("");
434
+ branch = "Subscribe";
435
+ break;
436
+ case "UnsubscribeConfirmation":
437
+ await client.get("");
438
+ branch = "Unsubscribe";
439
+ break;
440
+ case "Notification":
441
+ branch = "Notification";
442
+ break;
443
+ default: throw new Error(`Message type was not "Notification", "SubscriptionConfirmation" or "UnsubscribeConfirmation", but "${messageType}" instead.`);
444
+ }
445
+ if (_parseMessage && payload.headers["x-amz-sns-rawdelivery"] !== "true") try {
446
+ message.Message = JSON.parse(_prismatic_io_spectral.util.types.toString(message.Message));
447
+ } catch {
448
+ throw new Error(`Received a message that is not valid JSON: ${message.Message}`);
449
+ }
450
+ payload.headers = originalHeaders;
451
+ return {
452
+ branch,
453
+ payload: {
454
+ ...payload,
455
+ body: { data: message }
456
+ }
457
+ };
458
+ };
459
+ const getStateKey = (context) => context.flow.stableId;
460
+ const getLegacyStateKey = (context) => {
461
+ return `${context.webhookUrls[context.flow.name]?.split("/").pop()}:awsSnsTopicSubscription`;
462
+ };
463
+ const resolveSubscriptionState = (context) => {
464
+ const store = context[STORE_KEY];
465
+ const current = store[getStateKey(context)]?.subscriptionArn;
466
+ if (current) return {
467
+ subscriptionArn: _prismatic_io_spectral.util.types.toString(current),
468
+ isLegacy: false
469
+ };
470
+ const legacy = store[getLegacyStateKey(context)]?.subscriptionArn;
471
+ if (legacy) return {
472
+ subscriptionArn: _prismatic_io_spectral.util.types.toString(legacy),
473
+ isLegacy: true
474
+ };
475
+ return {
476
+ subscriptionArn: "",
477
+ isLegacy: false
478
+ };
479
+ };
480
+ const clearSubscriptionState = (context, isLegacy) => {
481
+ return { [isLegacy ? getLegacyStateKey(context) : getStateKey(context)]: null };
482
+ };
483
+ //#endregion
484
+ //#region src/inputs.ts
485
+ const name = (0, _prismatic_io_spectral.input)({
486
+ label: "Name",
487
+ type: "string",
488
+ required: true,
489
+ placeholder: "Enter topic name",
490
+ example: "MyExampleTopic",
491
+ comments: "The name of the SNS topic to create."
492
+ });
493
+ const topicArn = (0, _prismatic_io_spectral.input)({
494
+ label: "Topic ARN",
495
+ type: "string",
496
+ required: true,
497
+ placeholder: "Enter topic ARN",
498
+ example: "arn:aws:sns:us-east-1:123456789012:MyExampleTopic",
499
+ comments: "The Amazon Resource Name (ARN) of the SNS topic. [Learn more](https://docs.aws.amazon.com/sns/latest/api/API_CreateTopic.html)",
500
+ dataSource: "selectTopic",
501
+ clean: _prismatic_io_spectral.util.types.toString
502
+ });
503
+ const message = (0, _prismatic_io_spectral.input)({
504
+ label: "Message",
505
+ type: "string",
506
+ required: true,
507
+ placeholder: "Enter message content",
508
+ example: "Your order has been shipped!",
509
+ comments: "The message content to send to the topic or endpoint. [Learn more](https://docs.aws.amazon.com/sns/latest/api/API_Publish.html)"
510
+ });
511
+ const protocol = (0, _prismatic_io_spectral.input)({
512
+ label: "Protocol",
513
+ type: "string",
514
+ required: true,
515
+ default: "https",
516
+ model: [
517
+ {
518
+ label: "application",
519
+ value: "application"
520
+ },
521
+ {
522
+ label: "email",
523
+ value: "email"
524
+ },
525
+ {
526
+ label: "email-json",
527
+ value: "email-json"
528
+ },
529
+ {
530
+ label: "firehose",
531
+ value: "firehose"
532
+ },
533
+ {
534
+ label: "http",
535
+ value: "http"
536
+ },
537
+ {
538
+ label: "https",
539
+ value: "https"
540
+ },
541
+ {
542
+ label: "lambda",
543
+ value: "lambda"
544
+ },
545
+ {
546
+ label: "sms",
547
+ value: "sms"
548
+ },
549
+ {
550
+ label: "sqs",
551
+ value: "sqs"
552
+ }
553
+ ],
554
+ comments: "The protocol to use for delivering messages to the endpoint (application, email, email-json, firehose, http, https, lambda, sms, or sqs). [Learn more](https://docs.aws.amazon.com/sns/latest/api/API_Subscribe.html)"
555
+ });
556
+ const endpoint = (0, _prismatic_io_spectral.input)({
557
+ label: "Endpoint",
558
+ type: "string",
559
+ required: true,
560
+ placeholder: "Enter endpoint",
561
+ example: "https://example.com/webhook",
562
+ comments: "The endpoint to receive notifications. Format depends on protocol: email address (email@example.com), URL (https://example.com), phone number (+12065551234), or ARN (arn:aws:sqs:us-east-1:123456789012:MyQueue). [Learn more](https://docs.aws.amazon.com/sns/latest/api/API_Subscribe.html)"
563
+ });
564
+ const subscriptionArn = (0, _prismatic_io_spectral.input)({
565
+ label: "Subscription ARN",
566
+ type: "string",
567
+ required: true,
568
+ placeholder: "Enter subscription ARN",
569
+ example: "arn:aws:sns:us-east-1:123456789012:MyExampleTopic:12345678-1234-1234-1234-123456789012",
570
+ comments: "The Amazon Resource Name (ARN) of the subscription. [Learn more](https://docs.aws.amazon.com/sns/latest/api/API_Unsubscribe.html)",
571
+ clean: _prismatic_io_spectral.util.types.toString,
572
+ dataSource: "selectSubscription"
573
+ });
574
+ const phoneNumber = (0, _prismatic_io_spectral.input)({
575
+ label: "Phone Number",
576
+ type: "string",
577
+ required: true,
578
+ placeholder: "Enter phone number (+12065551234)",
579
+ example: "+12065551234",
580
+ comments: "The phone number in E.164 format (e.g., +12065551234) to receive SMS messages. [Learn more](https://docs.aws.amazon.com/sns/latest/dg/sms_publish-to-phone.html)"
581
+ });
582
+ const messageAttributes = (0, _prismatic_io_spectral.input)({
583
+ label: "Message Attributes",
584
+ type: "string",
585
+ required: false,
586
+ collection: "keyvaluelist",
587
+ placeholder: "Enter key-value pairs",
588
+ example: "{\"name\": \"John Doe\", \"age\": \"30\"}",
589
+ comments: "Optional message attributes as key-value pairs. The value will be automatically typed (String, Number, String.Array, or Binary for Buffer). For binary data, provide a Buffer from a previous step. [Learn more](https://docs.aws.amazon.com/sns/latest/api/API_MessageAttributeValue.html)"
590
+ });
591
+ const parseMessage = (0, _prismatic_io_spectral.input)({
592
+ label: "Parse Message",
593
+ type: "boolean",
594
+ required: true,
595
+ default: "false",
596
+ comments: "When enabled, the message from SNS will be parsed as JSON and returned. When disabled, it will be passed as received."
597
+ });
598
+ (0, _prismatic_io_spectral.input)({
599
+ label: "Max Items",
600
+ type: "string",
601
+ required: false,
602
+ placeholder: "Enter maximum items (1-50)",
603
+ example: "20",
604
+ comments: "The maximum number of items to return per request. Valid values: 1-50."
605
+ });
606
+ const nextToken = (0, _prismatic_io_spectral.input)({
607
+ label: "Next Token",
608
+ type: "string",
609
+ required: false,
610
+ placeholder: "Enter pagination token",
611
+ example: "lslTXFcbLQKkb0vP9Kgh5hy0Y0OnC7Z9ZPHPwPmMnxSk3eiDRMkct7D8E",
612
+ comments: "The pagination token returned by a previous request to retrieve the next page of results.",
613
+ clean: cleanStringInput
614
+ });
615
+ const connectionInput = (0, _prismatic_io_spectral.input)({
616
+ label: "Connection",
617
+ type: "connection",
618
+ required: true,
619
+ comments: "The Amazon SNS connection to use."
620
+ });
621
+ const publishBatchEntries = (0, _prismatic_io_spectral.input)({
622
+ label: "Message Entries",
623
+ type: "code",
624
+ language: "json",
625
+ required: true,
626
+ default: JSON.stringify(batchMessageEntriesExample, null, 2),
627
+ comments: "An array of message entries to publish in batch. Each entry must include an Id and Message. For binary messages, add a Template Field containing a Buffer to the BinaryValue attribute. [Learn more](https://docs.aws.amazon.com/sns/latest/dg/sns-message-attributes.html)"
628
+ });
629
+ const fetchAll = (0, _prismatic_io_spectral.input)({
630
+ label: "Fetch All",
631
+ type: "boolean",
632
+ required: true,
633
+ default: "false",
634
+ clean: _prismatic_io_spectral.util.types.toBool
635
+ });
636
+ const fetchAllTopics = {
637
+ ...fetchAll,
638
+ comments: "When set to true, fetches all paginated topics. When false, only 100 topics will be returned."
639
+ };
640
+ const fetchAllSubscriptions = {
641
+ ...fetchAll,
642
+ comments: "When set to true, fetches all paginated subscriptions. When false, only 100 subscriptions will be returned."
643
+ };
644
+ //#endregion
645
+ //#region src/examplePayloads.ts
646
+ const createTopicExamplePayload = { data: { TopicArn: "arn:aws:sns:us-east-1:123456789012:MyExampleTopic" } };
647
+ const publishMessageExamplePayload = { data: {
648
+ MessageId: "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
649
+ SequenceNumber: "10000000000000001000"
650
+ } };
651
+ const publishSmsExamplePayload = { data: { MessageId: "b2c3d4e5-f6a7-8901-bcde-f12345678901" } };
652
+ const publishBatchMessagesExamplePayload = { data: {
653
+ $metadata: {
654
+ httpStatusCode: 200,
655
+ requestId: "3df5ab1c-8e8a-426f-a2d1-bd7a39ef8651",
656
+ attempts: 1,
657
+ totalRetryDelay: 0
658
+ },
659
+ Successful: [{
660
+ Id: "msg-1",
661
+ MessageId: "c3d4e5f6-a7b8-9012-cdef-123456789012",
662
+ SequenceNumber: "10000000000000001001"
663
+ }, {
664
+ Id: "msg-2",
665
+ MessageId: "d4e5f6a7-b8c9-0123-def1-234567890123",
666
+ SequenceNumber: "10000000000000001002"
667
+ }],
668
+ Failed: [{
669
+ Id: "msg-3",
670
+ Code: "InvalidParameter",
671
+ Message: "Invalid message structure",
672
+ SenderFault: true
673
+ }]
674
+ } };
675
+ const subscribeExamplePayload = { data: { SubscriptionArn: "arn:aws:sns:us-east-1:123456789012:MyExampleTopic:a1b2c3d4-e5f6-7890-abcd-ef1234567890" } };
676
+ const unsubscribeExamplePayload = { data: {} };
677
+ const listTopicsExamplePayload = { data: {
678
+ Topics: [
679
+ { TopicArn: "arn:aws:sns:us-east-1:123456789012:MyExampleTopic" },
680
+ { TopicArn: "arn:aws:sns:us-east-1:123456789012:AnotherTopic" },
681
+ { TopicArn: "arn:aws:sns:us-east-1:123456789012:ProductionAlerts" }
682
+ ],
683
+ NextToken: "AAEBAf/8v+7MSvN8MkD9xZHCrFKL6RQ7UHJ9PJhWOH5Yqvf1H8EXAMPLE"
684
+ } };
685
+ const getTopicAttributesExamplePayload = { data: { Attributes: {
686
+ TopicArn: "arn:aws:sns:us-east-1:123456789012:MyExampleTopic",
687
+ Owner: "123456789012",
688
+ Policy: "{\"Version\":\"2012-10-17\",\"Id\":\"__default_policy_ID\",\"Statement\":[{\"Sid\":\"__default_statement_ID\",\"Effect\":\"Allow\",\"Principal\":{\"AWS\":\"*\"},\"Action\":[\"SNS:GetTopicAttributes\",\"SNS:SetTopicAttributes\",\"SNS:AddPermission\",\"SNS:RemovePermission\",\"SNS:DeleteTopic\",\"SNS:Subscribe\",\"SNS:ListSubscriptionsByTopic\",\"SNS:Publish\"],\"Resource\":\"arn:aws:sns:us-east-1:123456789012:MyExampleTopic\",\"Condition\":{\"StringEquals\":{\"AWS:SourceOwner\":\"123456789012\"}}}]}",
689
+ DisplayName: "My Example Topic",
690
+ SubscriptionsPending: "0",
691
+ SubscriptionsConfirmed: "3",
692
+ SubscriptionsDeleted: "0",
693
+ DeliveryPolicy: "{\"http\":{\"defaultHealthyRetryPolicy\":{\"minDelayTarget\":20,\"maxDelayTarget\":20,\"numRetries\":3,\"numMaxDelayRetries\":0,\"numNoDelayRetries\":0,\"numMinDelayRetries\":0,\"backoffFunction\":\"linear\"},\"disableSubscriptionOverrides\":false}}",
694
+ EffectiveDeliveryPolicy: "{\"http\":{\"defaultHealthyRetryPolicy\":{\"minDelayTarget\":20,\"maxDelayTarget\":20,\"numRetries\":3,\"numMaxDelayRetries\":0,\"numNoDelayRetries\":0,\"numMinDelayRetries\":0,\"backoffFunction\":\"linear\"},\"disableSubscriptionOverrides\":false}}",
695
+ TracingConfig: "PassThrough",
696
+ ContentBasedDeduplication: "false",
697
+ FifoTopic: "false"
698
+ } } };
699
+ const listSubscriptionsExamplePayload = { data: {
700
+ Subscriptions: [
701
+ {
702
+ SubscriptionArn: "arn:aws:sns:us-east-1:123456789012:MyExampleTopic:a1b2c3d4-e5f6-7890-abcd-ef1234567890",
703
+ Owner: "123456789012",
704
+ Protocol: "https",
705
+ Endpoint: "https://example.com/webhook",
706
+ TopicArn: "arn:aws:sns:us-east-1:123456789012:MyExampleTopic"
707
+ },
708
+ {
709
+ SubscriptionArn: "arn:aws:sns:us-east-1:123456789012:MyExampleTopic:b2c3d4e5-f6a7-8901-bcde-f12345678901",
710
+ Owner: "123456789012",
711
+ Protocol: "sqs",
712
+ Endpoint: "arn:aws:sqs:us-east-1:123456789012:MyQueue",
713
+ TopicArn: "arn:aws:sns:us-east-1:123456789012:MyExampleTopic"
714
+ },
715
+ {
716
+ SubscriptionArn: "PendingConfirmation",
717
+ Owner: "123456789012",
718
+ Protocol: "email",
719
+ Endpoint: "admin@example.com",
720
+ TopicArn: "arn:aws:sns:us-east-1:123456789012:MyExampleTopic"
721
+ },
722
+ {
723
+ SubscriptionArn: "PendingConfirmation",
724
+ Owner: "123456789012",
725
+ Protocol: "sms",
726
+ Endpoint: "+12125551234",
727
+ TopicArn: "arn:aws:sns:us-east-1:123456789012:MyExampleTopic"
728
+ }
729
+ ],
730
+ NextToken: "AAEBAf/8v+7MSvN8MkD9xZHCrFKL6RQ7UHJ9PJhWOH5Yqvf1H8EXAMPLE"
731
+ } };
732
+ const deleteTopicExamplePayload = { data: {} };
733
+ const listOptOutNumbersExamplePayload = { data: {
734
+ phoneNumbers: [
735
+ "+12125551001",
736
+ "+12125551002",
737
+ "+12125551003"
738
+ ],
739
+ nextToken: "AAEBAf/8v+7MSvN8MkD9xZHCrFKL6RQ7UHJ9PJhWOH5Yqvf1H8EXAMPLE"
740
+ } };
741
+ //#endregion
742
+ //#region src/actions/createTopic.ts
743
+ const createTopic = (0, _prismatic_io_spectral.action)({
744
+ display: {
745
+ label: "Create Topic",
746
+ description: "Create an Amazon SNS Topic"
747
+ },
748
+ perform: async ({ logger, debug: { enabled: debug } }, { awsConnection, awsRegion, name }) => {
749
+ const sns = await createSNSClient({
750
+ awsConnection,
751
+ awsRegion,
752
+ debug,
753
+ logger
754
+ });
755
+ const command = new _aws_sdk_client_sns.CreateTopicCommand({ Name: _prismatic_io_spectral.util.types.toString(name) });
756
+ return { data: await sns.send(command) };
757
+ },
758
+ inputs: {
759
+ awsRegion: awsRegion$1,
760
+ name,
761
+ awsConnection: connectionInput
762
+ },
763
+ examplePayload: createTopicExamplePayload
764
+ });
765
+ //#endregion
766
+ //#region src/actions/deleteTopics.ts
767
+ const deleteTopic = (0, _prismatic_io_spectral.action)({
768
+ display: {
769
+ label: "Delete Topic",
770
+ description: "Delete an Amazon SNS Topic"
771
+ },
772
+ perform: async ({ logger, debug: { enabled: debug } }, { awsConnection, awsRegion, topicArn }) => {
773
+ const sns = await createSNSClient({
774
+ awsConnection,
775
+ awsRegion,
776
+ debug,
777
+ logger
778
+ });
779
+ const command = new _aws_sdk_client_sns.DeleteTopicCommand({ TopicArn: topicArn });
780
+ return { data: await sns.send(command) };
781
+ },
782
+ inputs: {
783
+ awsRegion: awsRegion$1,
784
+ topicArn,
785
+ awsConnection: connectionInput
786
+ },
787
+ examplePayload: deleteTopicExamplePayload
788
+ });
789
+ //#endregion
790
+ //#region src/actions/getTopicAttributes.ts
791
+ const getTopicAttributes = (0, _prismatic_io_spectral.action)({
792
+ display: {
793
+ label: "Get Topic Attributes",
794
+ description: "Retrieves the attributes of an Amazon SNS Topic."
795
+ },
796
+ perform: async ({ logger, debug: { enabled: debug } }, { awsConnection, awsRegion, topicArn }) => {
797
+ const sns = await createSNSClient({
798
+ awsConnection,
799
+ awsRegion,
800
+ debug,
801
+ logger
802
+ });
803
+ const command = new _aws_sdk_client_sns.GetTopicAttributesCommand({ TopicArn: topicArn });
804
+ return { data: await sns.send(command) };
805
+ },
806
+ inputs: {
807
+ awsRegion: awsRegion$1,
808
+ topicArn,
809
+ awsConnection: connectionInput
810
+ },
811
+ examplePayload: getTopicAttributesExamplePayload
812
+ });
813
+ //#endregion
814
+ //#region src/actions/listTopics.ts
815
+ const listTopics = (0, _prismatic_io_spectral.action)({
816
+ display: {
817
+ label: "List Topics",
818
+ description: "List available Amazon SNS Topics"
819
+ },
820
+ perform: async ({ logger, debug: { enabled: debug } }, { awsConnection, awsRegion, nextToken, fetchAllTopics }) => {
821
+ return { data: await fetchTopics(await createSNSClient({
822
+ awsConnection,
823
+ awsRegion,
824
+ debug,
825
+ logger
826
+ }), fetchAllTopics, nextToken) };
827
+ },
828
+ inputs: {
829
+ awsConnection: connectionInput,
830
+ awsRegion: awsRegion$1,
831
+ fetchAllTopics,
832
+ nextToken
833
+ },
834
+ examplePayload: listTopicsExamplePayload
835
+ });
836
+ //#endregion
837
+ //#region src/actions/publishMessage.ts
838
+ const getAttributeType = (input) => {
839
+ if (typeof input === "string") {
840
+ if (_prismatic_io_spectral.util.types.isNumber(input)) return {
841
+ DataType: "Number",
842
+ StringValue: input
843
+ };
844
+ if (_prismatic_io_spectral.util.types.isJSON(input)) try {
845
+ const array = JSON.parse(input);
846
+ if (Array.isArray(array)) return {
847
+ DataType: "String.Array",
848
+ StringValue: JSON.stringify(array)
849
+ };
850
+ } catch (_error) {}
851
+ return {
852
+ DataType: "String",
853
+ StringValue: input
854
+ };
855
+ }
856
+ if (Buffer.isBuffer(input)) return {
857
+ DataType: "Binary",
858
+ BinaryValue: input
859
+ };
860
+ return {
861
+ DataType: "String",
862
+ StringValue: JSON.stringify(input)
863
+ };
864
+ };
865
+ const attributeReducer = (kvpList = []) => {
866
+ return kvpList.reduce((result, { key, value }) => {
867
+ result[key] = getAttributeType(value);
868
+ return result;
869
+ }, {});
870
+ };
871
+ const publishMessage = (0, _prismatic_io_spectral.action)({
872
+ display: {
873
+ label: "Publish Message",
874
+ description: "Publish a message to an Amazon SNS Topic"
875
+ },
876
+ perform: async ({ logger, debug: { enabled: debug } }, { awsConnection, awsRegion, message, topicArn, messageAttributes }) => {
877
+ const sns = await createSNSClient({
878
+ awsConnection,
879
+ awsRegion,
880
+ debug,
881
+ logger
882
+ });
883
+ const command = new _aws_sdk_client_sns.PublishCommand({
884
+ Message: _prismatic_io_spectral.util.types.toString(message),
885
+ MessageAttributes: attributeReducer(messageAttributes),
886
+ TopicArn: topicArn
887
+ });
888
+ return { data: await sns.send(command) };
889
+ },
890
+ inputs: {
891
+ awsRegion: awsRegion$1,
892
+ message,
893
+ topicArn,
894
+ messageAttributes,
895
+ awsConnection: connectionInput
896
+ },
897
+ examplePayload: publishMessageExamplePayload
898
+ });
899
+ //#endregion
900
+ //#region src/actions/publishBatchMessages.ts
901
+ const processBinaryValueIfPresent = (parsedEntries) => parsedEntries.map((entry) => {
902
+ if (entry.MessageAttributes) {
903
+ for (const key in entry.MessageAttributes) if (entry.MessageAttributes[key].BinaryValue && _prismatic_io_spectral.util.types.isBufferDataPayload(entry.MessageAttributes[key].BinaryValue)) entry.MessageAttributes[key].BinaryValue = Buffer.from(entry.MessageAttributes[key].BinaryValue.data);
904
+ }
905
+ return entry;
906
+ });
907
+ const publishBatchMessages = (0, _prismatic_io_spectral.action)({
908
+ display: {
909
+ label: "Publish Batch Messages",
910
+ description: "Publishes up to ten messages to the specified Amazon SNS Topic"
911
+ },
912
+ perform: async ({ logger, debug: { enabled: debug } }, { awsConnection, awsRegion, topicArn, publishBatchEntries }) => {
913
+ const sns = await createSNSClient({
914
+ awsConnection,
915
+ awsRegion,
916
+ debug,
917
+ logger
918
+ });
919
+ let parsedEntries = JSON.parse(publishBatchEntries);
920
+ if (!Array.isArray(parsedEntries)) throw new Error("Invalid Message Entries");
921
+ parsedEntries = processBinaryValueIfPresent(parsedEntries);
922
+ const batchCommand = new _aws_sdk_client_sns.PublishBatchCommand({
923
+ TopicArn: topicArn,
924
+ PublishBatchRequestEntries: parsedEntries
925
+ });
926
+ return { data: await sns.send(batchCommand) };
927
+ },
928
+ inputs: {
929
+ awsRegion: awsRegion$1,
930
+ topicArn,
931
+ publishBatchEntries,
932
+ awsConnection: connectionInput
933
+ },
934
+ examplePayload: publishBatchMessagesExamplePayload
935
+ });
936
+ //#endregion
937
+ //#region src/actions/listSubscriptions.ts
938
+ const listSubscriptions = (0, _prismatic_io_spectral.action)({
939
+ display: {
940
+ label: "List Subscriptions",
941
+ description: "Retrieve the subscriptions of an Amazon SNS Topic"
942
+ },
943
+ perform: async ({ logger, debug: { enabled: debug } }, { awsConnection, awsRegion, topicArn, nextToken, fetchAllSubscriptions }) => {
944
+ return { data: await fetchSubscriptions(await createSNSClient({
945
+ awsConnection,
946
+ awsRegion,
947
+ debug,
948
+ logger
949
+ }), topicArn, fetchAllSubscriptions, nextToken) };
950
+ },
951
+ inputs: {
952
+ awsConnection: connectionInput,
953
+ awsRegion: awsRegion$1,
954
+ topicArn,
955
+ fetchAllSubscriptions,
956
+ nextToken
957
+ },
958
+ examplePayload: listSubscriptionsExamplePayload
959
+ });
960
+ //#endregion
961
+ //#region src/actions/subscribe.ts
962
+ const subscribe = (0, _prismatic_io_spectral.action)({
963
+ display: {
964
+ label: "Subscribe to Topic",
965
+ description: "Subscribe to an Amazon SNS Topic"
966
+ },
967
+ perform: async ({ logger, debug: { enabled: debug } }, { awsConnection, awsRegion, topicArn, protocol, endpoint }) => {
968
+ const sns = await createSNSClient({
969
+ awsConnection,
970
+ awsRegion,
971
+ debug,
972
+ logger
973
+ });
974
+ const command = new _aws_sdk_client_sns.SubscribeCommand({
975
+ Protocol: _prismatic_io_spectral.util.types.toString(protocol),
976
+ TopicArn: topicArn,
977
+ Endpoint: _prismatic_io_spectral.util.types.toString(endpoint)
978
+ });
979
+ return { data: await sns.send(command) };
980
+ },
981
+ inputs: {
982
+ awsRegion: awsRegion$1,
983
+ topicArn,
984
+ protocol,
985
+ endpoint,
986
+ awsConnection: connectionInput
987
+ },
988
+ examplePayload: subscribeExamplePayload
989
+ });
990
+ //#endregion
991
+ //#region src/actions/unsubscribe.ts
992
+ const unsubscribe = (0, _prismatic_io_spectral.action)({
993
+ display: {
994
+ label: "Unsubscribe from a Topic",
995
+ description: "Unsubscribe from an Amazon SNS Topic"
996
+ },
997
+ perform: async ({ logger, debug: { enabled: debug } }, { awsConnection, awsRegion, subscriptionArn }) => {
998
+ const sns = await createSNSClient({
999
+ awsConnection,
1000
+ awsRegion,
1001
+ debug,
1002
+ logger
1003
+ });
1004
+ const command = new _aws_sdk_client_sns.UnsubscribeCommand({ SubscriptionArn: subscriptionArn });
1005
+ return { data: await sns.send(command) };
1006
+ },
1007
+ inputs: {
1008
+ awsRegion: awsRegion$1,
1009
+ subscriptionArn,
1010
+ awsConnection: connectionInput
1011
+ },
1012
+ examplePayload: unsubscribeExamplePayload
1013
+ });
1014
+ //#endregion
1015
+ //#region src/actions/publishSms.ts
1016
+ const publishSms = (0, _prismatic_io_spectral.action)({
1017
+ display: {
1018
+ label: "Publish SMS",
1019
+ description: "Publish an SMS message to an Amazon SNS Topic"
1020
+ },
1021
+ perform: async ({ logger, debug: { enabled: debug } }, { awsConnection, awsRegion, message, phoneNumber }) => {
1022
+ const sns = await createSNSClient({
1023
+ awsConnection,
1024
+ awsRegion,
1025
+ debug,
1026
+ logger
1027
+ });
1028
+ const command = new _aws_sdk_client_sns.PublishCommand({
1029
+ Message: _prismatic_io_spectral.util.types.toString(message),
1030
+ PhoneNumber: _prismatic_io_spectral.util.types.toString(phoneNumber)
1031
+ });
1032
+ return { data: await sns.send(command) };
1033
+ },
1034
+ inputs: {
1035
+ awsRegion: awsRegion$1,
1036
+ message,
1037
+ phoneNumber,
1038
+ awsConnection: connectionInput
1039
+ },
1040
+ examplePayload: publishSmsExamplePayload
1041
+ });
1042
+ //#endregion
1043
+ //#region src/actions/index.ts
1044
+ var actions_default = {
1045
+ createTopic,
1046
+ deleteTopic,
1047
+ getTopicAttributes,
1048
+ listTopics,
1049
+ publishMessage,
1050
+ publishBatchMessages,
1051
+ listSubscriptions,
1052
+ subscribe,
1053
+ unsubscribe,
1054
+ listOptOutNumbers: (0, _prismatic_io_spectral.action)({
1055
+ display: {
1056
+ label: "List Opt Out Numbers",
1057
+ description: "List all opt out numbers"
1058
+ },
1059
+ perform: async ({ logger, debug: { enabled: debug } }, { awsConnection, awsRegion, nextToken }) => {
1060
+ const sns = await createSNSClient({
1061
+ awsConnection,
1062
+ awsRegion,
1063
+ debug,
1064
+ logger
1065
+ });
1066
+ const command = new _aws_sdk_client_sns.ListPhoneNumbersOptedOutCommand({ nextToken: _prismatic_io_spectral.util.types.toString(nextToken) });
1067
+ return { data: await sns.send(command) };
1068
+ },
1069
+ inputs: {
1070
+ awsRegion: awsRegion$1,
1071
+ nextToken,
1072
+ awsConnection: connectionInput
1073
+ },
1074
+ examplePayload: listOptOutNumbersExamplePayload
1075
+ }),
1076
+ publishSms
1077
+ };
1078
+ const snsExamplePayload = {
1079
+ headers: {
1080
+ "x-amz-sns-message-type": "Notification",
1081
+ "x-amz-sns-message-id": "da41e39f-ea4d-435a-b922-c6aae3915ebe",
1082
+ "x-amz-sns-topic-arn": "arn:aws:sns:us-west-2:123456789012:MyTopic",
1083
+ "x-amz-sns-subscription-arn": "arn:aws:sns:us-west-2:123456789012:MyTopic:2bcfbf39-05c3-41de-beaa-fcfcc21c8f55",
1084
+ "Content-Length": "761",
1085
+ "Content-Type": "text/plain; charset=UTF-8",
1086
+ Host: "ec2-50-17-44-49.compute-1.amazonaws.com",
1087
+ Connection: "Keep-Alive",
1088
+ "User-Agent": "Amazon Simple Notification Service Agent"
1089
+ },
1090
+ queryParameters: {},
1091
+ rawBody: { data: {} },
1092
+ webhookUrls: {},
1093
+ webhookApiKeys: {},
1094
+ customer: {
1095
+ externalId: "abc-123",
1096
+ name: "Example Corp",
1097
+ id: "exampleId"
1098
+ },
1099
+ body: { data: {
1100
+ Type: "Notification",
1101
+ MessageId: "da41e39f-ea4d-435a-b922-c6aae3915ebe",
1102
+ TopicArn: "arn:aws:sns:us-west-2:123456789012:MyTopic",
1103
+ Subject: "test",
1104
+ Message: "test message",
1105
+ Timestamp: "2012-04-25T21:49:25.719Z",
1106
+ SignatureVersion: "1",
1107
+ Signature: "EXAMPLElDMXvB8r9R83tGoNn0ecwd5UjllzsvSvbItzfaMpN2nk5HVSw7XnOn/49IkxDKz8YrlH2qJXj2iZB0Zo2O71c4qQk1fMUDi3LGpij7RCW7AW9vYYsSqIKRnFS94ilu7NFhUzLiieYr4BKHpdTmdD6c0esKEYBpabxDSc=",
1108
+ SigningCertURL: "https://sns.us-west-2.amazonaws.com/SimpleNotificationService-f3ecfb7224c7233fe7bb5f59f96de52f.pem",
1109
+ UnsubscribeURL: "https://sns.us-west-2.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:us-west-2:123456789012:MyTopic:2bcfbf39-05c3-41de-beaa-fcfcc21c8f55"
1110
+ } },
1111
+ executionId: "",
1112
+ instance: {
1113
+ id: "example",
1114
+ name: "exampleName"
1115
+ },
1116
+ pathFragment: "example",
1117
+ invokeUrl: "Url",
1118
+ user: {
1119
+ email: "email@email.test",
1120
+ externalId: "externalId",
1121
+ id: "123",
1122
+ name: "name"
1123
+ },
1124
+ flow: {
1125
+ id: "flowId",
1126
+ name: "flowName",
1127
+ stableId: "flowStableId"
1128
+ },
1129
+ integration: {
1130
+ id: "integrationId",
1131
+ name: "integrationName",
1132
+ externalVersion: "1.0.0",
1133
+ versionSequenceId: "1"
1134
+ },
1135
+ startedAt: "2012-04-25T21:49:25.719Z",
1136
+ globalDebug: false
1137
+ };
1138
+ //#endregion
1139
+ //#region ../../packages/aws-utils/src/inputs/awsRegion.ts
1140
+ const awsRegion = (0, _prismatic_io_spectral.input)({
1141
+ label: "AWS Region",
1142
+ placeholder: "AWS Region",
1143
+ type: "string",
1144
+ required: false,
1145
+ comments: "AWS provides services in multiple regions, like us-west-2 or eu-west-1.",
1146
+ example: "us-east-1",
1147
+ dataSource: "selectRegion",
1148
+ clean: _prismatic_io_spectral.util.types.toString
1149
+ });
1150
+ var trigger_default = {
1151
+ subscriptionTrigger: (0, _prismatic_io_spectral.trigger)({
1152
+ display: {
1153
+ label: "Manual Subscription",
1154
+ description: "Receive and validate webhook requests from SNS for manually configured webhook subscriptions."
1155
+ },
1156
+ inputs: { parseMessage },
1157
+ scheduleSupport: "invalid",
1158
+ synchronousResponseSupport: "valid",
1159
+ allowsBranching: true,
1160
+ staticBranchNames: [
1161
+ "Notification",
1162
+ "Subscribe",
1163
+ "Unsubscribe"
1164
+ ],
1165
+ examplePayload: {
1166
+ payload: snsExamplePayload,
1167
+ branch: "Notification"
1168
+ },
1169
+ perform: webhookPerformFn
1170
+ }),
1171
+ webhookLifecycleTrigger: (0, _prismatic_io_spectral.trigger)({
1172
+ display: {
1173
+ label: "Topic Webhook",
1174
+ description: "Receive notifications from an SNS topic. Automatically creates and manages a topic subscription when the instance is deployed, and removes the subscription when the instance is deleted."
1175
+ },
1176
+ inputs: {
1177
+ parseMessage,
1178
+ awsConnection: connectionInput,
1179
+ awsRegion,
1180
+ topicArn
1181
+ },
1182
+ scheduleSupport: "invalid",
1183
+ synchronousResponseSupport: "valid",
1184
+ allowsBranching: true,
1185
+ staticBranchNames: [
1186
+ "Notification",
1187
+ "Subscribe",
1188
+ "Unsubscribe"
1189
+ ],
1190
+ examplePayload: {
1191
+ payload: snsExamplePayload,
1192
+ branch: "Notification"
1193
+ },
1194
+ perform: webhookPerformFn,
1195
+ webhookLifecycleHandlers: {
1196
+ create: async (context, { awsConnection, awsRegion, topicArn }) => {
1197
+ const sns = await createSNSClient({
1198
+ awsConnection,
1199
+ awsRegion,
1200
+ debug: context.debug.enabled,
1201
+ logger: context.logger
1202
+ });
1203
+ const { subscriptionArn: existingSubscriptionArn, isLegacy } = resolveSubscriptionState(context);
1204
+ let legacyStateCleanup = {};
1205
+ if (existingSubscriptionArn) {
1206
+ context.logger.info(`Existing SNS subscription found for flow ${context.flow.id}, deleting before recreating`, {
1207
+ subscriptionArn: existingSubscriptionArn,
1208
+ legacyState: isLegacy
1209
+ });
1210
+ await sns.send(new _aws_sdk_client_sns.UnsubscribeCommand({ SubscriptionArn: existingSubscriptionArn }));
1211
+ legacyStateCleanup = clearSubscriptionState(context, isLegacy);
1212
+ }
1213
+ context.logger.info(`Creating SNS subscription for flow ${context.flow.id} in region ${awsRegion} and topic ${topicArn}.`);
1214
+ const response = await sns.send(new _aws_sdk_client_sns.SubscribeCommand({
1215
+ TopicArn: topicArn,
1216
+ Protocol: "https",
1217
+ Endpoint: context.webhookUrls[context.flow.name],
1218
+ Attributes: { RawMessageDelivery: "false" },
1219
+ ReturnSubscriptionArn: true
1220
+ }));
1221
+ context.logger.info(`Created SNS subscription for topic ${topicArn}. SubscriptionArn: ${response.SubscriptionArn} (pending confirmation)`);
1222
+ return { crossFlowState: {
1223
+ ...legacyStateCleanup,
1224
+ [context.flow.stableId]: { subscriptionArn: response.SubscriptionArn }
1225
+ } };
1226
+ },
1227
+ delete: async (context, { awsConnection, awsRegion }) => {
1228
+ const { subscriptionArn: existingSubscriptionArn, isLegacy } = resolveSubscriptionState(context);
1229
+ if (!existingSubscriptionArn) {
1230
+ context.logger.warn(`No subscription ARN found for flow ${context.flow.name}. Skipping deletion.`);
1231
+ return;
1232
+ }
1233
+ await (await createSNSClient({
1234
+ awsConnection,
1235
+ awsRegion,
1236
+ debug: context.debug.enabled,
1237
+ logger: context.logger
1238
+ })).send(new _aws_sdk_client_sns.UnsubscribeCommand({ SubscriptionArn: existingSubscriptionArn }));
1239
+ context.logger.info(`Deleted SNS subscription for flow ${context.flow.id}. SubscriptionArn: ${existingSubscriptionArn}`);
1240
+ return { crossFlowState: clearSubscriptionState(context, isLegacy) };
1241
+ }
1242
+ }
1243
+ })
1244
+ };
1245
+ //#endregion
1246
+ //#region src/dataSources/index.ts
1247
+ var dataSources_default = {
1248
+ selectRegion,
1249
+ selectSubscription: (0, _prismatic_io_spectral.dataSource)({
1250
+ display: {
1251
+ label: "Select Subscription",
1252
+ description: "Select a subscription from the list of subscriptions"
1253
+ },
1254
+ inputs: {
1255
+ awsConnection: connectionInput,
1256
+ awsRegion: {
1257
+ ...awsRegion$1,
1258
+ dataSource: void 0,
1259
+ model: void 0
1260
+ },
1261
+ topicArn: {
1262
+ ...topicArn,
1263
+ dataSource: void 0
1264
+ }
1265
+ },
1266
+ perform: async (_, { awsConnection, awsRegion, topicArn }) => {
1267
+ const { Subscriptions: subscriptions } = await fetchSubscriptions(await createSNSClient({
1268
+ awsConnection,
1269
+ awsRegion
1270
+ }), topicArn, true, void 0);
1271
+ return { result: subscriptions ? subscriptions.map((subscription) => ({
1272
+ label: `Endpoint: ${subscription.Endpoint}`,
1273
+ key: subscription.SubscriptionArn
1274
+ })) : [] };
1275
+ },
1276
+ dataSourceType: "picklist"
1277
+ }),
1278
+ selectTopic: (0, _prismatic_io_spectral.dataSource)({
1279
+ display: {
1280
+ label: "Select Topic",
1281
+ description: "Select a topic from the list of topics"
1282
+ },
1283
+ inputs: {
1284
+ awsConnection: connectionInput,
1285
+ awsRegion: {
1286
+ ...awsRegion$1,
1287
+ dataSource: void 0,
1288
+ model: void 0
1289
+ }
1290
+ },
1291
+ perform: async ({ logger }, { awsConnection, awsRegion }) => {
1292
+ const { Topics: topics } = await fetchTopics(await createSNSClient({
1293
+ awsConnection,
1294
+ awsRegion
1295
+ }), true, void 0);
1296
+ return { result: topics ? topics.map((topic) => ({
1297
+ label: `Topic: ${topic.TopicArn.split(":").pop()}`,
1298
+ key: topic.TopicArn
1299
+ })) : [] };
1300
+ },
1301
+ dataSourceType: "picklist"
1302
+ })
1303
+ };
1304
+ //#endregion
1305
+ //#region src/index.ts
1306
+ var src_default = (0, _prismatic_io_spectral.component)({
1307
+ key: "aws-sns",
1308
+ documentationUrl: "https://prismatic.io/docs/components/aws-sns/",
1309
+ public: true,
1310
+ display: {
1311
+ label: "Amazon SNS",
1312
+ description: "Manage topics, subscriptions, and messages in Amazon SNS.",
1313
+ iconPath: "icon.png",
1314
+ category: "Data Platforms"
1315
+ },
1316
+ actions: actions_default,
1317
+ triggers: trigger_default,
1318
+ connections: connections_default,
1319
+ dataSources: dataSources_default,
1320
+ hooks: { error: _prismatic_io_spectral_http.handleErrors }
1321
+ });
1322
+ //#endregion
1323
+ //#region npm-dist/.entry.ts
1324
+ var _entry_default = (0, _prismatic_io_spectral.callableComponent)(src_default);
1325
+ //#endregion
1326
+ module.exports = _entry_default;