UNPKG

@strapi/provider-email-amazon-ses

Version:

Amazon SES provider for strapi email

1 lines 11.3 kB
{"version":3,"file":"utils.mjs","sources":["../src/utils.ts"],"sourcesContent":["import type { SendEmailCommandInput, SESClientConfig } from '@aws-sdk/client-ses';\n\n/** Default SES API host when `amazon` is omitted (same as legacy node-ses). */\nexport const DEFAULT_SES_ENDPOINT = 'https://email.us-east-1.amazonaws.com';\n\nexport const SES_ENDPOINT_REGION_PATTERN = /email\\.([a-z0-9-]+)\\.amazonaws\\.com/i;\n\nexport interface ProviderCredentials {\n key: string;\n secret: string;\n sessionToken?: string;\n}\n\nexport interface ProviderOptions extends Omit<SESClientConfig, 'credentials'> {\n credentials?: ProviderCredentials | NonNullable<SESClientConfig['credentials']>;\n key?: string;\n secret?: string;\n amazon?: string;\n}\n\nexport interface ProviderSettings {\n defaultFrom: string;\n defaultReplyTo: string | string[];\n}\n\nexport interface SendOptions {\n from?: string;\n to: string | string[];\n cc?: string | string[];\n bcc?: string | string[];\n replyTo?: string | string[];\n subject: string;\n text: string;\n html: string;\n [key: string]: unknown;\n}\n\ntype EndpointInput = string | SESClientConfig['endpoint'];\n\nconst resolveEndpointUrl = (endpoint?: EndpointInput): string | undefined => {\n if (!endpoint) {\n return undefined;\n }\n\n if (typeof endpoint === 'string') {\n return endpoint;\n }\n\n if (typeof endpoint === 'object' && 'url' in endpoint && typeof endpoint.url === 'string') {\n return endpoint.url;\n }\n\n return undefined;\n};\n\nexport const regionFromEndpoint = (endpoint?: EndpointInput): string | undefined => {\n const endpointUrl = resolveEndpointUrl(endpoint);\n\n if (!endpointUrl) {\n return undefined;\n }\n\n try {\n const match = new URL(endpointUrl).hostname.match(SES_ENDPOINT_REGION_PATTERN);\n return match?.[1];\n } catch {\n return undefined;\n }\n};\n\n/** Matches node-ses `extractRecipient`: arrays pass through, strings become a single entry. */\nexport const toAddressList = (value?: string | string[]): string[] | undefined => {\n if (!value) {\n return undefined;\n }\n\n if (Array.isArray(value)) {\n return value;\n }\n\n return [value];\n};\n\nexport interface LegacyMessageTag {\n name: string;\n value: string;\n}\n\nconst mapLegacyMessageTags = (messageTags: unknown): SendEmailCommandInput['Tags'] => {\n if (!Array.isArray(messageTags)) {\n return undefined;\n }\n\n return messageTags\n .filter(\n (tag): tag is LegacyMessageTag =>\n typeof tag === 'object' &&\n tag !== null &&\n 'name' in tag &&\n 'value' in tag &&\n typeof tag.name === 'string' &&\n typeof tag.value === 'string'\n )\n .map((tag) => ({\n Name: tag.name,\n Value: tag.value,\n }));\n};\n\n/**\n * Maps legacy node-ses `providerOptions` and AWS SDK v3 `SESClient` config.\n *\n * Rewrites:\n * - `key` / `secret` → `credentials.accessKeyId` / `credentials.secretAccessKey`\n * - `credentials: { key, secret }` → AWS credential object\n * - `amazon` → `endpoint`\n * - region from `amazon` / `endpoint` host (`email.<region>.amazonaws.com`)\n * - `key` + `secret` only → `region: us-east-1` (node-ses default endpoint behavior)\n */\nexport const getClientConfig = (providerOptions: ProviderOptions): SESClientConfig => {\n const { key, secret, amazon, credentials, region, ...clientConfig } = providerOptions;\n\n const hasLegacyStaticCredentials = Boolean(key && secret);\n const endpoint =\n amazon ||\n providerOptions.endpoint ||\n (hasLegacyStaticCredentials ? DEFAULT_SES_ENDPOINT : undefined);\n\n const parsedRegionFromEndpoint = regionFromEndpoint(endpoint);\n\n const explicitCredentials =\n (credentials && typeof credentials === 'object' && 'key' in credentials\n ? {\n accessKeyId: credentials.key,\n secretAccessKey: credentials.secret,\n ...(credentials.sessionToken ? { sessionToken: credentials.sessionToken } : {}),\n }\n : credentials) ||\n (key && secret\n ? {\n accessKeyId: key,\n secretAccessKey: secret,\n }\n : undefined);\n\n const unparseableLegacyAmazon = Boolean(\n amazon && hasLegacyStaticCredentials && !parsedRegionFromEndpoint\n );\n\n const resolvedRegion =\n region ||\n parsedRegionFromEndpoint ||\n ((unparseableLegacyAmazon ||\n (hasLegacyStaticCredentials && !parsedRegionFromEndpoint && !endpoint)) &&\n 'us-east-1') ||\n undefined;\n\n // node-ses createClient only consumed key, secret, and amazon — ignore stray options.\n const sdkOnlyOptions = hasLegacyStaticCredentials ? {} : clientConfig;\n\n return {\n ...sdkOnlyOptions,\n ...(resolvedRegion ? { region: resolvedRegion } : {}),\n ...(endpoint ? { endpoint } : {}),\n ...(explicitCredentials\n ? {\n credentials: explicitCredentials,\n }\n : {}),\n };\n};\n\n/** Builds SendEmail input (html → Html body, text → Text body; legacy node-ses message/altText). */\nexport const buildSendEmailCommandInput = (\n options: SendOptions,\n settings: ProviderSettings\n): SendEmailCommandInput => {\n const { from, to, cc, bcc, replyTo, subject, text, html, ...rest } = options;\n\n const { configurationSet, messageTags, ...sdkRest } = rest;\n\n const commandInput: SendEmailCommandInput = {\n Source: from || settings.defaultFrom,\n Destination: {\n ToAddresses: toAddressList(to),\n CcAddresses: toAddressList(cc),\n BccAddresses: toAddressList(bcc),\n },\n ReplyToAddresses: toAddressList(replyTo !== undefined ? replyTo : settings.defaultReplyTo),\n Message: {\n Subject: {\n Data: subject,\n Charset: 'UTF-8',\n },\n Body: {\n ...(html\n ? {\n Html: {\n Data: html,\n Charset: 'UTF-8',\n },\n }\n : {}),\n ...(text\n ? {\n Text: {\n Data: text,\n Charset: 'UTF-8',\n },\n }\n : {}),\n },\n },\n ...sdkRest,\n };\n\n if (typeof configurationSet === 'string') {\n commandInput.ConfigurationSetName = configurationSet;\n }\n\n const tags = mapLegacyMessageTags(messageTags);\n\n if (tags?.length) {\n commandInput.Tags = tags;\n }\n\n return commandInput;\n};\n"],"names":["DEFAULT_SES_ENDPOINT","SES_ENDPOINT_REGION_PATTERN","resolveEndpointUrl","endpoint","undefined","url","regionFromEndpoint","endpointUrl","match","URL","hostname","toAddressList","value","Array","isArray","mapLegacyMessageTags","messageTags","filter","tag","name","map","Name","Value","getClientConfig","providerOptions","key","secret","amazon","credentials","region","clientConfig","hasLegacyStaticCredentials","Boolean","parsedRegionFromEndpoint","explicitCredentials","accessKeyId","secretAccessKey","sessionToken","unparseableLegacyAmazon","resolvedRegion","sdkOnlyOptions","buildSendEmailCommandInput","options","settings","from","to","cc","bcc","replyTo","subject","text","html","rest","configurationSet","sdkRest","commandInput","Source","defaultFrom","Destination","ToAddresses","CcAddresses","BccAddresses","ReplyToAddresses","defaultReplyTo","Message","Subject","Data","Charset","Body","Html","Text","ConfigurationSetName","tags","length","Tags"],"mappings":"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"}