@bitblit/ratchet-aws 6.0.145-alpha → 6.0.147-alpha

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 (103) hide show
  1. package/package.json +5 -4
  2. package/src/batch/aws-batch-background-processor.spec.ts +22 -0
  3. package/src/batch/aws-batch-background-processor.ts +71 -0
  4. package/src/batch/aws-batch-ratchet.spec.ts +42 -0
  5. package/src/batch/aws-batch-ratchet.ts +70 -0
  6. package/src/build/ratchet-aws-info.ts +19 -0
  7. package/src/cache/memory-storage-provider.ts +39 -0
  8. package/src/cache/simple-cache-object-wrapper.ts +11 -0
  9. package/src/cache/simple-cache-read-options.ts +9 -0
  10. package/src/cache/simple-cache-storage-provider.ts +15 -0
  11. package/src/cache/simple-cache.spec.ts +42 -0
  12. package/src/cache/simple-cache.ts +81 -0
  13. package/src/cloudwatch/cloud-watch-log-group-ratchet.spec.ts +26 -0
  14. package/src/cloudwatch/cloud-watch-log-group-ratchet.ts +105 -0
  15. package/src/cloudwatch/cloud-watch-logs-ratchet.spec.ts +123 -0
  16. package/src/cloudwatch/cloud-watch-logs-ratchet.ts +232 -0
  17. package/src/cloudwatch/cloud-watch-metrics-ratchet.spec.ts +30 -0
  18. package/src/cloudwatch/cloud-watch-metrics-ratchet.ts +98 -0
  19. package/src/dao/example-prototype-dao-item.ts +8 -0
  20. package/src/dao/memory-prototype-dao-provider.ts +16 -0
  21. package/src/dao/prototype-dao-config.ts +8 -0
  22. package/src/dao/prototype-dao-db.ts +4 -0
  23. package/src/dao/prototype-dao-provider.ts +6 -0
  24. package/src/dao/prototype-dao.spec.ts +33 -0
  25. package/src/dao/prototype-dao.ts +110 -0
  26. package/src/dao/s3-simple-dao.ts +96 -0
  27. package/src/dao/simple-dao-item.ts +13 -0
  28. package/src/dynamodb/dynamo-ratchet-like.ts +61 -0
  29. package/src/dynamodb/dynamo-ratchet.spec.ts +206 -0
  30. package/src/dynamodb/dynamo-ratchet.ts +850 -0
  31. package/src/dynamodb/dynamo-table-ratchet.spec.ts +23 -0
  32. package/src/dynamodb/dynamo-table-ratchet.ts +189 -0
  33. package/src/dynamodb/hash-spreader.spec.ts +22 -0
  34. package/src/dynamodb/hash-spreader.ts +89 -0
  35. package/src/dynamodb/impl/dynamo-db-storage-provider.spec.ts +60 -0
  36. package/src/dynamodb/impl/dynamo-db-storage-provider.ts +140 -0
  37. package/src/dynamodb/impl/dynamo-db-sync-lock.spec.ts +41 -0
  38. package/src/dynamodb/impl/dynamo-db-sync-lock.ts +78 -0
  39. package/src/dynamodb/impl/dynamo-expiring-code-provider.ts +31 -0
  40. package/src/dynamodb/impl/dynamo-runtime-parameter-provider.spec.ts +65 -0
  41. package/src/dynamodb/impl/dynamo-runtime-parameter-provider.ts +44 -0
  42. package/src/ec2/ec2-ratchet.spec.ts +45 -0
  43. package/src/ec2/ec2-ratchet.ts +169 -0
  44. package/src/ecr/ecr-unused-image-cleaner-options.ts +9 -0
  45. package/src/ecr/ecr-unused-image-cleaner-output.ts +8 -0
  46. package/src/ecr/ecr-unused-image-cleaner-repository-output.ts +10 -0
  47. package/src/ecr/ecr-unused-image-cleaner.spec.ts +40 -0
  48. package/src/ecr/ecr-unused-image-cleaner.ts +183 -0
  49. package/src/ecr/retained-image-descriptor.ts +7 -0
  50. package/src/ecr/retained-image-reason.ts +4 -0
  51. package/src/ecr/used-image-finder.ts +6 -0
  52. package/src/ecr/used-image-finders/aws-batch-used-image-finder.ts +40 -0
  53. package/src/ecr/used-image-finders/lambda-used-image-finder.ts +51 -0
  54. package/src/environment/cascade-environment-service-provider.ts +28 -0
  55. package/src/environment/env-var-environment-service-provider.ts +36 -0
  56. package/src/environment/environment-service-config.ts +7 -0
  57. package/src/environment/environment-service-provider.ts +7 -0
  58. package/src/environment/environment-service.spec.ts +41 -0
  59. package/src/environment/environment-service.ts +89 -0
  60. package/src/environment/fixed-environment-service-provider.ts +26 -0
  61. package/src/environment/ssm-environment-service-provider.spec.ts +18 -0
  62. package/src/environment/ssm-environment-service-provider.ts +71 -0
  63. package/src/expiring-code/expiring-code-params.ts +7 -0
  64. package/src/expiring-code/expiring-code-provider.ts +6 -0
  65. package/src/expiring-code/expiring-code-ratchet.spec.ts +10 -0
  66. package/src/expiring-code/expiring-code-ratchet.ts +44 -0
  67. package/src/expiring-code/expiring-code.ts +6 -0
  68. package/src/iam/aws-credentials-ratchet.ts +25 -0
  69. package/src/lambda/lambda-event-detector.ts +55 -0
  70. package/src/lambda/lambda-event-type-guards.ts +38 -0
  71. package/src/model/cloud-watch-metrics-minute-level-dynamo-count-request.ts +18 -0
  72. package/src/model/dynamo-count-result.ts +8 -0
  73. package/src/route53/route-53-ratchet.ts +77 -0
  74. package/src/runtime-parameter/cached-stored-runtime-parameter.ts +5 -0
  75. package/src/runtime-parameter/global-variable-override-runtime-parameter-provider.spec.ts +41 -0
  76. package/src/runtime-parameter/global-variable-override-runtime-parameter-provider.ts +82 -0
  77. package/src/runtime-parameter/memory-runtime-parameter-provider.ts +42 -0
  78. package/src/runtime-parameter/runtime-parameter-provider.ts +12 -0
  79. package/src/runtime-parameter/runtime-parameter-ratchet.spec.ts +53 -0
  80. package/src/runtime-parameter/runtime-parameter-ratchet.ts +84 -0
  81. package/src/runtime-parameter/stored-runtime-parameter.ts +6 -0
  82. package/src/s3/expanded-file-children.ts +5 -0
  83. package/src/s3/impl/s3-environment-service-provider.ts +41 -0
  84. package/src/s3/impl/s3-expiring-code-provider.spec.ts +63 -0
  85. package/src/s3/impl/s3-expiring-code-provider.ts +71 -0
  86. package/src/s3/impl/s3-prototype-dao-provider.spec.ts +45 -0
  87. package/src/s3/impl/s3-prototype-dao-provider.ts +37 -0
  88. package/src/s3/impl/s3-remote-file-tracking-provider-options.ts +6 -0
  89. package/src/s3/impl/s3-remote-file-tracking-provider.spec.ts +67 -0
  90. package/src/s3/impl/s3-remote-file-tracking-provider.ts +157 -0
  91. package/src/s3/impl/s3-storage-provider.spec.ts +32 -0
  92. package/src/s3/impl/s3-storage-provider.ts +60 -0
  93. package/src/s3/s3-cache-ratchet-like.ts +64 -0
  94. package/src/s3/s3-cache-ratchet.spec.ts +150 -0
  95. package/src/s3/s3-cache-ratchet.ts +476 -0
  96. package/src/s3/s3-location-sync-ratchet.ts +207 -0
  97. package/src/s3/s3-ratchet.spec.ts +26 -0
  98. package/src/s3/s3-ratchet.ts +26 -0
  99. package/src/ses/ses-mail-sending-provider.ts +85 -0
  100. package/src/sns/sns-ratchet.spec.ts +24 -0
  101. package/src/sns/sns-ratchet.ts +52 -0
  102. package/src/sync-lock/memory-sync-lock.ts +48 -0
  103. package/src/sync-lock/sync-lock-provider.ts +5 -0
@@ -0,0 +1,26 @@
1
+ import { RequireRatchet } from '@bitblit/ratchet-common/lang/require-ratchet';
2
+
3
+ export class S3Ratchet {
4
+ // Returns whether the URL passed is s3 valid (not whether it exists or not)
5
+ public static checkS3UrlForValidity(value: string): boolean {
6
+ let rval: boolean = false;
7
+ if (value) {
8
+ rval = value.startsWith('s3://') && value.trim().length > 5;
9
+ }
10
+ return rval;
11
+ }
12
+
13
+ public static extractBucketFromURL(value: string): string {
14
+ RequireRatchet.true(S3Ratchet.checkS3UrlForValidity(value), 'invalid s3 url');
15
+ const idx1: number = value.indexOf('/', 5);
16
+ const rval: string = idx1 > 0 ? value.substring(5, idx1) : value.substring(5);
17
+ return rval;
18
+ }
19
+
20
+ public static extractKeyFromURL(value: string): string {
21
+ RequireRatchet.true(S3Ratchet.checkS3UrlForValidity(value), 'invalid s3 url');
22
+ const idx1: number = value.indexOf('/', 5);
23
+ const rval: string = idx1 > 0 ? value.substring(idx1 + 1) : null;
24
+ return rval;
25
+ }
26
+ }
@@ -0,0 +1,85 @@
1
+ import { RequireRatchet } from '@bitblit/ratchet-common/lang/require-ratchet';
2
+ import { Logger } from '@bitblit/ratchet-common/logger/logger';
3
+ import { StringRatchet } from '@bitblit/ratchet-common/lang/string-ratchet';
4
+ import { SendRawEmailCommand, SendRawEmailCommandOutput, SendRawEmailRequest, SESClient } from '@aws-sdk/client-ses';
5
+ import { DateTime } from 'luxon';
6
+ import { CompleteMultipartUploadCommandOutput } from '@aws-sdk/client-s3';
7
+ import { S3CacheRatchetLike } from '../s3/s3-cache-ratchet-like.js';
8
+ import { MailSendingProvider } from '@bitblit/ratchet-common/mail/mail-sending-provider';
9
+ import { ResolvedReadyToSendEmail } from '@bitblit/ratchet-common/mail/resolved-ready-to-send-email';
10
+ import { MailerUtil } from '@bitblit/ratchet-common/mail/mailer-util';
11
+
12
+ /**
13
+ * Generic Mail Sender for AWS.
14
+ *
15
+ * Params:
16
+ * ses: AWS SES handler, properly configured
17
+ * defaultSendingAddress:
18
+ */
19
+ export class SesMailSendingProvider implements MailSendingProvider<SendRawEmailCommandOutput, CompleteMultipartUploadCommandOutput> {
20
+ constructor(
21
+ private _ses: SESClient,
22
+ private _archiveRatchet?: S3CacheRatchetLike,
23
+ private archivePrefix?: string,
24
+ ) {
25
+ RequireRatchet.notNullOrUndefined(this._ses);
26
+ if (!!_archiveRatchet && !_archiveRatchet.getDefaultBucket()) {
27
+ throw new Error('If archiveRatchet specified, must set a default bucket');
28
+ }
29
+ }
30
+
31
+ public async archiveEmail(
32
+ mail: ResolvedReadyToSendEmail,
33
+ _rawSendResult: SendRawEmailCommandOutput,
34
+ ): Promise<CompleteMultipartUploadCommandOutput> {
35
+ let rval: CompleteMultipartUploadCommandOutput = null;
36
+ if (this._archiveRatchet) {
37
+ Logger.debug('Archiving outbound email to : %j', mail.destinationAddresses);
38
+ let targetPath: string = StringRatchet.trimToEmpty(this.archivePrefix);
39
+ if (!targetPath.endsWith('/')) {
40
+ targetPath += '/';
41
+ }
42
+ const now: DateTime = DateTime.utc();
43
+ targetPath +=
44
+ 'year=' +
45
+ now.toFormat('yyyy') +
46
+ '/month=' +
47
+ now.toFormat('MM') +
48
+ '/day=' +
49
+ now.toFormat('dd') +
50
+ '/hour=' +
51
+ now.toFormat('HH') +
52
+ '/' +
53
+ now.toFormat('mm_ss__SSS');
54
+ targetPath += '.json';
55
+ try {
56
+ rval = await this._archiveRatchet.writeObjectToCacheFile(targetPath, mail);
57
+ } catch (err) {
58
+ Logger.warn('Failed to archive email %s %j : %s', targetPath, mail, err);
59
+ }
60
+ }
61
+ return rval;
62
+ }
63
+
64
+ public get sesClient(): SESClient {
65
+ return this._ses;
66
+ }
67
+
68
+ public get archiveRatchet(): S3CacheRatchetLike {
69
+ return this._archiveRatchet;
70
+ }
71
+
72
+ public async sendEmail(inRts: ResolvedReadyToSendEmail): Promise<SendRawEmailCommandOutput> {
73
+ RequireRatchet.notNullOrUndefined(inRts, 'RTS must be defined');
74
+ RequireRatchet.notNullOrUndefined(inRts.destinationAddresses, 'Destination addresses must be defined');
75
+ let rval: SendRawEmailCommandOutput = null;
76
+ const rawMail: string = MailerUtil.convertResolvedReadyToSendEmailToRaw(inRts);
77
+
78
+ const params: SendRawEmailRequest = {
79
+ RawMessage: { Data: new TextEncoder().encode(rawMail) },
80
+ };
81
+
82
+ rval = await this._ses.send(new SendRawEmailCommand(params));
83
+ return rval;
84
+ }
85
+ }
@@ -0,0 +1,24 @@
1
+ import { PublishCommand, PublishCommandOutput, SNSClient } from '@aws-sdk/client-sns';
2
+ import { SnsRatchet } from './sns-ratchet.js';
3
+ import { mockClient } from 'aws-sdk-client-mock';
4
+ import { beforeEach, describe, expect, test } from 'vitest';
5
+
6
+ let mockSNS;
7
+
8
+ describe('#SNSRatchet', function () {
9
+ mockSNS = mockClient(SNSClient);
10
+ beforeEach(() => {
11
+ mockSNS.reset();
12
+ });
13
+
14
+ test('should send a message', async () => {
15
+ //mockSNS.publish.resolves({} as PublishCommandOutput as never);
16
+ mockSNS.on(PublishCommand).resolves({} as PublishCommandOutput);
17
+
18
+ const topicArn: string = 'TOPIC-ARN-HERE';
19
+ const ratchet: SnsRatchet = new SnsRatchet(mockSNS, topicArn);
20
+ const out: PublishCommandOutput = await ratchet.sendMessage('test \n\n' + new Date() + '\n\n---\n\nTest CR');
21
+
22
+ expect(out).toBeTruthy();
23
+ });
24
+ });
@@ -0,0 +1,52 @@
1
+ import { RequireRatchet } from '@bitblit/ratchet-common/lang/require-ratchet';
2
+ import { Logger } from '@bitblit/ratchet-common/logger/logger';
3
+ import { PublishCommand, PublishCommandInput, PublishCommandOutput, SNSClient } from '@aws-sdk/client-sns';
4
+
5
+ export class SnsRatchet {
6
+ constructor(
7
+ private sns: SNSClient = new SNSClient({ region: 'us-east-1' }),
8
+ private topicArn: string,
9
+ ) {
10
+ RequireRatchet.notNullOrUndefined(this.sns, 'sns');
11
+ RequireRatchet.notNullOrUndefined(this.topicArn, 'topicArn');
12
+ }
13
+
14
+ public get snsClient(): SNSClient {
15
+ return this.sns;
16
+ }
17
+
18
+ public async sendMessage(inMsg: any, suppressErrors: boolean = false): Promise<PublishCommandOutput> {
19
+ let result: PublishCommandOutput = null;
20
+ try {
21
+ const safeInMsg: any = inMsg ? inMsg : 'NO-MESSAGE-PROVIDED';
22
+ const msg: string = typeof safeInMsg === 'string' ? safeInMsg : JSON.stringify(safeInMsg);
23
+
24
+ const params: PublishCommandInput = {
25
+ TopicArn: this.topicArn,
26
+ Message: msg,
27
+ };
28
+
29
+ Logger.debug('Sending via SNS : %j', params);
30
+ result = await this.sns.send(new PublishCommand(params));
31
+ } catch (err) {
32
+ if (suppressErrors) {
33
+ Logger.error('Failed to fire SNS notification : %j : %s', inMsg, err);
34
+ } else {
35
+ throw err;
36
+ }
37
+ }
38
+ return result;
39
+ }
40
+
41
+ // Kinda a special case, used for when you want to only send messages when a certain condition is true
42
+ // (Like when you are running in production)
43
+ public async conditionallySendMessage(inMsg: any, condition: boolean, suppressErrors: boolean = false): Promise<PublishCommandOutput> {
44
+ let rval: PublishCommandOutput = null;
45
+ if (condition) {
46
+ rval = await this.sendMessage(inMsg, suppressErrors);
47
+ } else {
48
+ Logger.info('Not sending message, condition was false : %j', inMsg);
49
+ }
50
+ return rval;
51
+ }
52
+ }
@@ -0,0 +1,48 @@
1
+ import { StringRatchet } from '@bitblit/ratchet-common/lang/string-ratchet';
2
+ import { SyncLockProvider } from './sync-lock-provider.js';
3
+
4
+ /**
5
+ * Simple in-memory implementation of the SyncLockProvider interface
6
+ */
7
+ export class MemorySyncLock implements SyncLockProvider {
8
+ private _locks: Map<string, number> = new Map<string, number>();
9
+
10
+ // Empty constructor prevents instantiation
11
+ // eslint-disable-next-line @typescript-eslint/no-useless-constructor
12
+ constructor() {
13
+ // Placeholder
14
+ }
15
+
16
+ public async acquireLock(lockKey: string, expirationSeconds: number = 30): Promise<boolean> {
17
+ let rval: boolean = false;
18
+ if (StringRatchet.trimToNull(lockKey)) {
19
+ const now: number = Date.now();
20
+ const val: number = this._locks.get(lockKey);
21
+ if (!val || val < now) {
22
+ this._locks.set(lockKey, now + expirationSeconds * 1000);
23
+ rval = true;
24
+ }
25
+ }
26
+ return rval;
27
+ }
28
+
29
+ public async releaseLock(lockKey: string): Promise<void> {
30
+ if (StringRatchet.trimToNull(lockKey)) {
31
+ this._locks.delete(lockKey);
32
+ }
33
+ }
34
+
35
+ public async clearExpiredSyncLocks(): Promise<number> {
36
+ const toRemove: string[] = [];
37
+ const now: number = Date.now();
38
+ this._locks.forEach((v, k) => {
39
+ if (v < now) {
40
+ toRemove.push(k);
41
+ }
42
+ });
43
+ toRemove.forEach((k) => {
44
+ this._locks.delete(k);
45
+ });
46
+ return toRemove.length;
47
+ }
48
+ }
@@ -0,0 +1,5 @@
1
+ export interface SyncLockProvider {
2
+ acquireLock(lockKey: string, expirationSeconds?: number): Promise<boolean>;
3
+ releaseLock(lockKey: string): Promise<void>;
4
+ clearExpiredSyncLocks?(): Promise<number>;
5
+ }