@allthings/cloud-toolkit 5.2.1 → 5.3.0

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.
package/README.md CHANGED
@@ -13,9 +13,54 @@ Standardizes the setup of aws, Datadog and other things
13
13
 
14
14
  ### ses
15
15
 
16
- | function | parameters | description |
17
- | -------- | ---------- | ---------------------------------------------- |
18
- | sendMail | options | Sends an email via SES or provided SMTP config |
16
+ | function | parameters | description |
17
+ | ------------ | ---------- | ------------------------------------------------------------------------ |
18
+ | sendMail | options | Sends an email via SES or provided SMTP config |
19
+ | emailHeaders | options | Builds the deliverability headers for one message, for `options.headers` |
20
+
21
+ `emailHeaders` is opt-in and pure: a message only carries these headers when a
22
+ caller builds them. Every header is omitted when the value it needs is not given.
23
+
24
+ | header | from |
25
+ | ------------------------------------------ | ------------------------------------------------------- |
26
+ | `Auto-Submitted: auto-generated` | `suppressAutoResponses` (default true) |
27
+ | `X-Auto-Response-Suppress: OOF, AutoReply` | `suppressAutoResponses` (default true) |
28
+ | `Content-Language` | `contentLanguage` |
29
+ | `Feedback-ID` | `feedbackId` |
30
+ | `List-Id` | `listId` |
31
+ | `List-Unsubscribe` | `unsubscribeUrl` |
32
+ | `List-Unsubscribe-Post` | `oneClickUnsubscribe` (default true, https target only) |
33
+ | `Precedence: bulk` | `bulk` (default false) |
34
+ | `X-Entity-Ref-ID` | `entityReferenceId` |
35
+
36
+ ```ts
37
+ import { emailHeaders, ses } from '@allthings/cloud-toolkit/ses'
38
+
39
+ await ses({}).sendMail({
40
+ from: 'noreply@allthings.me',
41
+ headers: emailHeaders({
42
+ contentLanguage: 'de-DE',
43
+ entityReferenceId: notificationId,
44
+ listId: 'AppNotificationDigest.notifications.allthings.me',
45
+ unsubscribeUrl: `${siteUrl}/settings`,
46
+ // the URL cannot answer an unauthenticated POST yet
47
+ oneClickUnsubscribe: false,
48
+ }),
49
+ html,
50
+ subject,
51
+ text,
52
+ to,
53
+ })
54
+ ```
55
+
56
+ The two suppression headers stop out of office autoresponders from replying to a
57
+ `noreply@` address. `X-Auto-Response-Suppress` is deliberately `OOF, AutoReply`
58
+ rather than `All`, so delivery status notifications keep reaching SES and its
59
+ suppression list stays accurate.
60
+
61
+ `Precedence: bulk` is off by default. Only legacy `vacation(1)` style responders
62
+ act on it, Gmail and Microsoft ignore it, and some filters read it as a mild
63
+ negative — so leave it off for anything that has to arrive.
19
64
 
20
65
  ### lambda
21
66
 
@@ -37,11 +82,11 @@ Standardizes the setup of aws, Datadog and other things
37
82
 
38
83
  ### sqs
39
84
 
40
- | function | parameters | description |
41
- | --------------- | ------------------------------------------------------------------------------- | -------------------------------------------------------- |
42
- | deleteQueueItem | queueUrl<br/>receiptHandle | Deletes item from queue |
43
- | getQueueItems | queueUrl<br/>maxNumberOfMessages (optional) | Retrieves items from queue |
44
- | getQueueUrl | queueName | Returns queue url which is needed for all other requests |
85
+ | function | parameters | description |
86
+ | --------------- | ---------------------------------------------------------------------------------------------------------- | -------------------------------------------------------- |
87
+ | deleteQueueItem | queueUrl<br/>receiptHandle | Deletes item from queue |
88
+ | getQueueItems | queueUrl<br/>maxNumberOfMessages (optional) | Retrieves items from queue |
89
+ | getQueueUrl | queueName | Returns queue url which is needed for all other requests |
45
90
  | sendMessage | queueUrl<br/>message<br/>fifoSettings(optional)<br/>messageAttributes(optional)<br/>messageDelay(optional) | Creates an item in the queue |
46
91
 
47
92
  ### logger
package/dist/lib.cjs.js CHANGED
@@ -904,6 +904,25 @@ const dynamodb = (userConfig) => {
904
904
  };
905
905
  };
906
906
 
907
+ const AUTO_RESPONSE_SUPPRESSION_HEADERS = {
908
+ 'Auto-Submitted': 'auto-generated',
909
+ 'X-Auto-Response-Suppress': 'OOF, AutoReply',
910
+ };
911
+ const emailHeaders = ({ bulk = false, contentLanguage, entityReferenceId, feedbackId, listId, oneClickUnsubscribe = true, suppressAutoResponses = true, unsubscribeUrl, } = {}) => Object.fromEntries(Object.entries({
912
+ ...(suppressAutoResponses ? AUTO_RESPONSE_SUPPRESSION_HEADERS : {}),
913
+ 'Content-Language': contentLanguage?.trim(),
914
+ 'Feedback-ID': feedbackId?.trim(),
915
+ 'List-Id': listId?.trim().replace(/^<*([^<>].*?)>*$/, '<$1>'),
916
+ 'List-Unsubscribe': unsubscribeUrl
917
+ ?.trim()
918
+ .replace(/^<*([^<>].*?)>*$/, '<$1>'),
919
+ 'List-Unsubscribe-Post': oneClickUnsubscribe &&
920
+ /^<?https:/i.test(unsubscribeUrl?.trim() ?? '') &&
921
+ 'List-Unsubscribe=One-Click',
922
+ Precedence: bulk && 'bulk',
923
+ 'X-Entity-Ref-ID': entityReferenceId?.trim(),
924
+ }).filter(([, value]) => value));
925
+
907
926
  const invokeLambda = async (lambdaClient, config, invocationType, payload) => {
908
927
  try {
909
928
  const invokeCommand = new clientLambda.InvokeCommand({
@@ -1190,6 +1209,7 @@ Object.defineProperty(exports, "Logger", {
1190
1209
  enumerable: true,
1191
1210
  get: function () { return winston.Logger; }
1192
1211
  });
1212
+ exports.AUTO_RESPONSE_SUPPRESSION_HEADERS = AUTO_RESPONSE_SUPPRESSION_HEADERS;
1193
1213
  exports.ClientError = ClientError;
1194
1214
  exports.DEFAULT_PARAMETER_STORE_CLIENT_CONFIG = DEFAULT_CLIENT_CONFIG$1;
1195
1215
  exports.DEFAULT_SES_CLIENT_CONFIG = DEFAULT_CLIENT_CONFIG;
@@ -1200,6 +1220,7 @@ exports.atob = atob;
1200
1220
  exports.btoa = btoa;
1201
1221
  exports.deepFlatten = deepFlatten;
1202
1222
  exports.dynamodb = dynamodb;
1223
+ exports.emailHeaders = emailHeaders;
1203
1224
  exports.flatten = flatten;
1204
1225
  exports.lambda = lambda;
1205
1226
  exports.logger = logger;
package/dist/lib.esm.mjs CHANGED
@@ -882,6 +882,25 @@ const dynamodb = (userConfig) => {
882
882
  };
883
883
  };
884
884
 
885
+ const AUTO_RESPONSE_SUPPRESSION_HEADERS = {
886
+ 'Auto-Submitted': 'auto-generated',
887
+ 'X-Auto-Response-Suppress': 'OOF, AutoReply',
888
+ };
889
+ const emailHeaders = ({ bulk = false, contentLanguage, entityReferenceId, feedbackId, listId, oneClickUnsubscribe = true, suppressAutoResponses = true, unsubscribeUrl, } = {}) => Object.fromEntries(Object.entries({
890
+ ...(suppressAutoResponses ? AUTO_RESPONSE_SUPPRESSION_HEADERS : {}),
891
+ 'Content-Language': contentLanguage?.trim(),
892
+ 'Feedback-ID': feedbackId?.trim(),
893
+ 'List-Id': listId?.trim().replace(/^<*([^<>].*?)>*$/, '<$1>'),
894
+ 'List-Unsubscribe': unsubscribeUrl
895
+ ?.trim()
896
+ .replace(/^<*([^<>].*?)>*$/, '<$1>'),
897
+ 'List-Unsubscribe-Post': oneClickUnsubscribe &&
898
+ /^<?https:/i.test(unsubscribeUrl?.trim() ?? '') &&
899
+ 'List-Unsubscribe=One-Click',
900
+ Precedence: bulk && 'bulk',
901
+ 'X-Entity-Ref-ID': entityReferenceId?.trim(),
902
+ }).filter(([, value]) => value));
903
+
885
904
  const invokeLambda = async (lambdaClient, config, invocationType, payload) => {
886
905
  try {
887
906
  const invokeCommand = new InvokeCommand({
@@ -1164,4 +1183,4 @@ const logger = (config) => {
1164
1183
  });
1165
1184
  };
1166
1185
 
1167
- export { ClientError, DEFAULT_CLIENT_CONFIG$1 as DEFAULT_PARAMETER_STORE_CLIENT_CONFIG, DEFAULT_CLIENT_CONFIG as DEFAULT_SES_CLIENT_CONFIG, ServerError, alagarr, asyncReduce, atob, btoa, deepFlatten, dynamodb, flatten, lambda, logger, parameterStore, partial, ses, splitEvery, sqs, times, until };
1186
+ export { AUTO_RESPONSE_SUPPRESSION_HEADERS, ClientError, DEFAULT_CLIENT_CONFIG$1 as DEFAULT_PARAMETER_STORE_CLIENT_CONFIG, DEFAULT_CLIENT_CONFIG as DEFAULT_SES_CLIENT_CONFIG, ServerError, alagarr, asyncReduce, atob, btoa, deepFlatten, dynamodb, emailHeaders, flatten, lambda, logger, parameterStore, partial, ses, splitEvery, sqs, times, until };
package/dist/ses.cjs.js CHANGED
@@ -3,6 +3,25 @@
3
3
  var clientSesv2 = require('@aws-sdk/client-sesv2');
4
4
  var nodemailer = require('nodemailer');
5
5
 
6
+ const AUTO_RESPONSE_SUPPRESSION_HEADERS = {
7
+ 'Auto-Submitted': 'auto-generated',
8
+ 'X-Auto-Response-Suppress': 'OOF, AutoReply',
9
+ };
10
+ const emailHeaders = ({ bulk = false, contentLanguage, entityReferenceId, feedbackId, listId, oneClickUnsubscribe = true, suppressAutoResponses = true, unsubscribeUrl, } = {}) => Object.fromEntries(Object.entries({
11
+ ...(suppressAutoResponses ? AUTO_RESPONSE_SUPPRESSION_HEADERS : {}),
12
+ 'Content-Language': contentLanguage?.trim(),
13
+ 'Feedback-ID': feedbackId?.trim(),
14
+ 'List-Id': listId?.trim().replace(/^<*([^<>].*?)>*$/, '<$1>'),
15
+ 'List-Unsubscribe': unsubscribeUrl
16
+ ?.trim()
17
+ .replace(/^<*([^<>].*?)>*$/, '<$1>'),
18
+ 'List-Unsubscribe-Post': oneClickUnsubscribe &&
19
+ /^<?https:/i.test(unsubscribeUrl?.trim() ?? '') &&
20
+ 'List-Unsubscribe=One-Click',
21
+ Precedence: bulk && 'bulk',
22
+ 'X-Entity-Ref-ID': entityReferenceId?.trim(),
23
+ }).filter(([, value]) => value));
24
+
6
25
  const DEFAULT_CLIENT_CONFIG = {
7
26
  clientConfig: { region: 'eu-west-1' },
8
27
  };
@@ -56,5 +75,7 @@ const ses = (userConfig) => {
56
75
  };
57
76
  };
58
77
 
78
+ exports.AUTO_RESPONSE_SUPPRESSION_HEADERS = AUTO_RESPONSE_SUPPRESSION_HEADERS;
59
79
  exports.DEFAULT_CLIENT_CONFIG = DEFAULT_CLIENT_CONFIG;
80
+ exports.emailHeaders = emailHeaders;
60
81
  exports.ses = ses;
package/dist/ses.esm.mjs CHANGED
@@ -1,6 +1,25 @@
1
1
  import { SESv2Client, SendEmailCommand } from '@aws-sdk/client-sesv2';
2
2
  import { createTransport } from 'nodemailer';
3
3
 
4
+ const AUTO_RESPONSE_SUPPRESSION_HEADERS = {
5
+ 'Auto-Submitted': 'auto-generated',
6
+ 'X-Auto-Response-Suppress': 'OOF, AutoReply',
7
+ };
8
+ const emailHeaders = ({ bulk = false, contentLanguage, entityReferenceId, feedbackId, listId, oneClickUnsubscribe = true, suppressAutoResponses = true, unsubscribeUrl, } = {}) => Object.fromEntries(Object.entries({
9
+ ...(suppressAutoResponses ? AUTO_RESPONSE_SUPPRESSION_HEADERS : {}),
10
+ 'Content-Language': contentLanguage?.trim(),
11
+ 'Feedback-ID': feedbackId?.trim(),
12
+ 'List-Id': listId?.trim().replace(/^<*([^<>].*?)>*$/, '<$1>'),
13
+ 'List-Unsubscribe': unsubscribeUrl
14
+ ?.trim()
15
+ .replace(/^<*([^<>].*?)>*$/, '<$1>'),
16
+ 'List-Unsubscribe-Post': oneClickUnsubscribe &&
17
+ /^<?https:/i.test(unsubscribeUrl?.trim() ?? '') &&
18
+ 'List-Unsubscribe=One-Click',
19
+ Precedence: bulk && 'bulk',
20
+ 'X-Entity-Ref-ID': entityReferenceId?.trim(),
21
+ }).filter(([, value]) => value));
22
+
4
23
  const DEFAULT_CLIENT_CONFIG = {
5
24
  clientConfig: { region: 'eu-west-1' },
6
25
  };
@@ -54,4 +73,4 @@ const ses = (userConfig) => {
54
73
  };
55
74
  };
56
75
 
57
- export { DEFAULT_CLIENT_CONFIG, ses };
76
+ export { AUTO_RESPONSE_SUPPRESSION_HEADERS, DEFAULT_CLIENT_CONFIG, emailHeaders, ses };
@@ -0,0 +1,16 @@
1
+ import { Headers } from 'nodemailer/lib/mailer';
2
+ export declare const AUTO_RESPONSE_SUPPRESSION_HEADERS: {
3
+ readonly 'Auto-Submitted': "auto-generated";
4
+ readonly 'X-Auto-Response-Suppress': "OOF, AutoReply";
5
+ };
6
+ export interface IEmailHeaderOptions {
7
+ readonly bulk?: boolean;
8
+ readonly contentLanguage?: string;
9
+ readonly entityReferenceId?: string;
10
+ readonly feedbackId?: string;
11
+ readonly listId?: string;
12
+ readonly oneClickUnsubscribe?: boolean;
13
+ readonly suppressAutoResponses?: boolean;
14
+ readonly unsubscribeUrl?: string;
15
+ }
16
+ export declare const emailHeaders: ({ bulk, contentLanguage, entityReferenceId, feedbackId, listId, oneClickUnsubscribe, suppressAutoResponses, unsubscribeUrl, }?: IEmailHeaderOptions) => Headers;
@@ -1,4 +1,5 @@
1
1
  export { dynamodb, IDynamoDBConfig, IDynamoDBInstance, IUnprocessedItems, TBatchWriteItems, TDeleteItem, TGetItem, TPutItem, TQueryTable, TScanTable, TUpdateItem, } from './dynamodb';
2
+ export { AUTO_RESPONSE_SUPPRESSION_HEADERS, emailHeaders, IEmailHeaderOptions, } from './emailHeaders';
2
3
  export { ILambda, ILambdaInstance, lambda, TInvokeLambda } from './lambda';
3
4
  export { DEFAULT_CLIENT_CONFIG as DEFAULT_PARAMETER_STORE_CLIENT_CONFIG, IParameterStore, IParameterStoreInstance, parameterStore, TGetSecret, TGetSecrets, } from './parameterStore';
4
5
  export { DEFAULT_CLIENT_CONFIG as DEFAULT_SES_CLIENT_CONFIG, IEmailAttachment, IEmailOptions, ISES, ISESInstance, ses, TSendMail, } from './ses';
@@ -33,3 +33,4 @@ export interface ISESInstance {
33
33
  sendMail: TSendMail;
34
34
  }
35
35
  export declare const ses: (userConfig: ISES) => ISESInstance;
36
+ export { AUTO_RESPONSE_SUPPRESSION_HEADERS, emailHeaders, IEmailHeaderOptions, } from './emailHeaders';
@@ -1,5 +1,5 @@
1
1
  export { Alagarr, alagarr, ClientError, HandlerFunction, IInterfaceAlagarrOptions, IInterfaceHeaders, IInterfaceQueryParameters, IInterfaceRequest, IInterfaceResponse, ServerError, } from './alagarr';
2
- export { DEFAULT_PARAMETER_STORE_CLIENT_CONFIG, DEFAULT_SES_CLIENT_CONFIG, dynamodb, IDynamoDBConfig, IDynamoDBInstance, IEmailAttachment, IEmailOptions, ILambda, ILambdaInstance, IParameterStore, IParameterStoreInstance, ISES, ISESInstance, ISQS, ISQSInstance, IUnprocessedItems, lambda, parameterStore, ses, sqs, TBatchWriteItems, TDeleteItem, TDeleteQueueItem, TGetItem, TGetQueueItems, TGetQueueUrl, TGetSecret, TGetSecrets, TInvokeLambda, TPutItem, TQueryTable, TScanTable, TSendMail, TSendMessage, TUpdateItem, } from './aws';
2
+ export { AUTO_RESPONSE_SUPPRESSION_HEADERS, DEFAULT_PARAMETER_STORE_CLIENT_CONFIG, DEFAULT_SES_CLIENT_CONFIG, dynamodb, emailHeaders, IDynamoDBConfig, IDynamoDBInstance, IEmailAttachment, IEmailHeaderOptions, IEmailOptions, ILambda, ILambdaInstance, IParameterStore, IParameterStoreInstance, ISES, ISESInstance, ISQS, ISQSInstance, IUnprocessedItems, lambda, parameterStore, ses, sqs, TBatchWriteItems, TDeleteItem, TDeleteQueueItem, TGetItem, TGetQueueItems, TGetQueueUrl, TGetSecret, TGetSecrets, TInvokeLambda, TPutItem, TQueryTable, TScanTable, TSendMail, TSendMessage, TUpdateItem, } from './aws';
3
3
  export { atob, btoa } from './base64';
4
4
  export { logger } from './logger/logger';
5
5
  export { asyncReduce, deepFlatten, flatten, List, partial, splitEvery, times, until, } from './utils';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@allthings/cloud-toolkit",
3
- "version": "5.2.1",
3
+ "version": "5.3.0",
4
4
  "description": "",
5
5
  "author": "Allthings GmbH",
6
6
  "keywords": [