{"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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"}