@ts-cloud/core 0.2.2 → 0.2.4

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 (226) hide show
  1. package/dist/advanced-features.test.d.ts +1 -0
  2. package/dist/aws/cloudformation.d.ts +136 -0
  3. package/dist/aws/cloudfront.d.ts +45 -0
  4. package/dist/aws/credentials.d.ts +77 -0
  5. package/dist/aws/credentials.test.d.ts +4 -0
  6. package/dist/aws/index.d.ts +10 -0
  7. package/dist/aws/s3.d.ts +256 -0
  8. package/dist/aws/s3.test.d.ts +4 -0
  9. package/dist/aws/signature.d.ts +142 -0
  10. package/dist/aws/signature.test.d.ts +4 -0
  11. package/dist/backup/disaster-recovery.d.ts +140 -0
  12. package/dist/backup/disaster-recovery.test.d.ts +1 -0
  13. package/dist/backup/index.d.ts +8 -0
  14. package/dist/backup/manager.d.ts +172 -0
  15. package/dist/backup/manager.test.d.ts +1 -0
  16. package/dist/cicd/circleci.d.ts +50 -0
  17. package/dist/cicd/github-actions.d.ts +62 -0
  18. package/dist/cicd/gitlab-ci.d.ts +50 -0
  19. package/dist/cicd/index.d.ts +7 -0
  20. package/dist/cli/history.d.ts +137 -0
  21. package/dist/cli/index.d.ts +9 -0
  22. package/dist/cli/progress.d.ts +193 -0
  23. package/dist/cli/repl.d.ts +148 -0
  24. package/dist/cli/suggestions.d.ts +74 -0
  25. package/dist/cli/table.d.ts +73 -0
  26. package/dist/cli/table.test.d.ts +1 -0
  27. package/dist/cloudformation/builder.d.ts +93 -0
  28. package/dist/cloudformation/builder.test.d.ts +4 -0
  29. package/dist/cloudformation/builders/api-gateway.d.ts +30 -0
  30. package/dist/cloudformation/builders/cache.d.ts +35 -0
  31. package/dist/cloudformation/builders/cdn.d.ts +34 -0
  32. package/dist/cloudformation/builders/compute.d.ts +68 -0
  33. package/dist/cloudformation/builders/database.d.ts +61 -0
  34. package/dist/cloudformation/builders/functions.d.ts +32 -0
  35. package/dist/cloudformation/builders/messaging.d.ts +17 -0
  36. package/dist/cloudformation/builders/monitoring.d.ts +39 -0
  37. package/dist/cloudformation/builders/network.d.ts +14 -0
  38. package/dist/cloudformation/builders/queue.d.ts +16 -0
  39. package/dist/cloudformation/builders/security.d.ts +31 -0
  40. package/dist/cloudformation/builders/storage.d.ts +36 -0
  41. package/dist/cloudformation/index.d.ts +10 -0
  42. package/dist/cloudformation/types.d.ts +200 -0
  43. package/dist/compliance/aws-config.d.ts +175 -0
  44. package/dist/compliance/cloudtrail.d.ts +132 -0
  45. package/dist/compliance/compliance.test.d.ts +1 -0
  46. package/dist/compliance/guardduty.d.ts +176 -0
  47. package/dist/compliance/index.d.ts +12 -0
  48. package/dist/compliance/security-hub.d.ts +178 -0
  49. package/dist/containers/build-optimization.d.ts +155 -0
  50. package/dist/containers/containers.test.d.ts +1 -0
  51. package/dist/containers/image-scanning.d.ts +144 -0
  52. package/dist/containers/index.d.ts +8 -0
  53. package/dist/containers/registry.d.ts +129 -0
  54. package/dist/containers/service-mesh.d.ts +254 -0
  55. package/dist/database/database.test.d.ts +1 -0
  56. package/dist/database/index.d.ts +8 -0
  57. package/dist/database/migrations.d.ts +153 -0
  58. package/dist/database/performance.d.ts +219 -0
  59. package/dist/database/replicas.d.ts +218 -0
  60. package/dist/database/users.d.ts +165 -0
  61. package/dist/dependency-graph.d.ts +37 -0
  62. package/dist/deployment/ab-testing.d.ts +165 -0
  63. package/dist/deployment/blue-green.d.ts +140 -0
  64. package/dist/deployment/canary.d.ts +165 -0
  65. package/dist/deployment/deployment.test.d.ts +1 -0
  66. package/dist/deployment/index.d.ts +12 -0
  67. package/dist/deployment/progressive.d.ts +50 -0
  68. package/dist/dns/dns.test.d.ts +1 -0
  69. package/dist/dns/dnssec.d.ts +120 -0
  70. package/dist/dns/index.d.ts +7 -0
  71. package/dist/dns/resolver.d.ts +216 -0
  72. package/dist/dns/routing.d.ts +277 -0
  73. package/dist/email/advanced/analytics.d.ts +107 -0
  74. package/dist/email/advanced/index.d.ts +10 -0
  75. package/dist/email/advanced/rules.d.ts +131 -0
  76. package/dist/email/advanced/scheduling.d.ts +81 -0
  77. package/dist/email/advanced/search.d.ts +91 -0
  78. package/dist/email/advanced/shared-mailboxes.d.ts +109 -0
  79. package/dist/email/advanced/templates.d.ts +95 -0
  80. package/dist/email/advanced/threading.d.ts +65 -0
  81. package/dist/email/analytics.d.ts +189 -0
  82. package/dist/email/bounce-handling.d.ts +171 -0
  83. package/dist/email/email.test.d.ts +1 -0
  84. package/dist/email/handlers/__tests__/inbound.test.d.ts +1 -0
  85. package/dist/email/handlers/__tests__/outbound.test.d.ts +1 -0
  86. package/dist/email/handlers/converter.d.ts +11 -0
  87. package/dist/email/handlers/feedback.d.ts +11 -0
  88. package/dist/email/handlers/inbound.d.ts +13 -0
  89. package/dist/email/handlers/outbound.d.ts +13 -0
  90. package/dist/email/index.d.ts +10 -0
  91. package/dist/email/reputation.d.ts +133 -0
  92. package/dist/email/templates.d.ts +124 -0
  93. package/dist/errors/index.d.ts +177 -0
  94. package/dist/errors/index.test.d.ts +4 -0
  95. package/dist/health-checks/index.d.ts +35 -0
  96. package/dist/index.d.ts +15 -256
  97. package/dist/index.js +228 -80
  98. package/dist/intrinsic-functions.d.ts +77 -0
  99. package/dist/lambda/concurrency.d.ts +146 -0
  100. package/dist/lambda/destinations.d.ts +141 -0
  101. package/dist/lambda/dlq.d.ts +160 -0
  102. package/dist/lambda/index.d.ts +10 -0
  103. package/dist/lambda/lambda.test.d.ts +1 -0
  104. package/dist/lambda/layers.d.ts +117 -0
  105. package/dist/lambda/versions.d.ts +145 -0
  106. package/dist/lambda/vpc.d.ts +164 -0
  107. package/dist/local/config.d.ts +44 -0
  108. package/dist/local/index.d.ts +5 -0
  109. package/dist/local/mock-aws.d.ts +69 -0
  110. package/dist/modules/ai.d.ts +108 -0
  111. package/dist/modules/api.d.ts +157 -0
  112. package/dist/modules/auth.d.ts +262 -0
  113. package/dist/modules/cache.d.ts +108 -0
  114. package/dist/modules/cdn.d.ts +305 -0
  115. package/dist/modules/communication.d.ts +117 -0
  116. package/dist/modules/compute.d.ts +1376 -0
  117. package/dist/modules/database.d.ts +144 -0
  118. package/dist/modules/deployment.d.ts +372 -0
  119. package/dist/modules/dns.d.ts +143 -0
  120. package/dist/modules/email.d.ts +314 -0
  121. package/dist/modules/filesystem.d.ts +132 -0
  122. package/dist/modules/index.d.ts +31 -0
  123. package/dist/modules/messaging.d.ts +210 -0
  124. package/dist/modules/monitoring.d.ts +574 -0
  125. package/dist/modules/network.d.ts +148 -0
  126. package/dist/modules/parameter-store.d.ts +143 -0
  127. package/dist/modules/permissions.d.ts +245 -0
  128. package/dist/modules/phone.d.ts +125 -0
  129. package/dist/modules/queue.d.ts +411 -0
  130. package/dist/modules/redirects.d.ts +140 -0
  131. package/dist/modules/registry.d.ts +189 -0
  132. package/dist/modules/search.d.ts +135 -0
  133. package/dist/modules/secrets.d.ts +149 -0
  134. package/dist/modules/security.d.ts +219 -0
  135. package/dist/modules/sms.d.ts +130 -0
  136. package/dist/modules/storage.d.ts +344 -0
  137. package/dist/modules/workflow.d.ts +288 -0
  138. package/dist/multi-account/config.d.ts +166 -0
  139. package/dist/multi-account/index.d.ts +6 -0
  140. package/dist/multi-account/manager.d.ts +181 -0
  141. package/dist/multi-region/cross-region.d.ts +204 -0
  142. package/dist/multi-region/index.d.ts +7 -0
  143. package/dist/multi-region/manager.d.ts +136 -0
  144. package/dist/multi-region/regions.d.ts +98 -0
  145. package/dist/network-security/index.d.ts +55 -0
  146. package/dist/observability/index.d.ts +8 -0
  147. package/dist/observability/logs.d.ts +213 -0
  148. package/dist/observability/metrics.d.ts +187 -0
  149. package/dist/observability/observability.test.d.ts +1 -0
  150. package/dist/observability/synthetics.d.ts +189 -0
  151. package/dist/observability/xray.d.ts +193 -0
  152. package/dist/phone/advanced/analytics.d.ts +83 -0
  153. package/dist/phone/advanced/callbacks.d.ts +67 -0
  154. package/dist/phone/advanced/index.d.ts +7 -0
  155. package/dist/phone/advanced/ivr-builder.d.ts +130 -0
  156. package/dist/phone/advanced/recording.d.ts +62 -0
  157. package/dist/phone/handlers/__tests__/incoming-call.test.d.ts +1 -0
  158. package/dist/phone/handlers/incoming-call.d.ts +10 -0
  159. package/dist/phone/handlers/missed-call.d.ts +9 -0
  160. package/dist/phone/handlers/voicemail.d.ts +10 -0
  161. package/dist/phone/index.d.ts +5 -0
  162. package/dist/presets/api-backend.d.ts +11 -0
  163. package/dist/presets/data-pipeline.d.ts +11 -0
  164. package/dist/presets/extend.d.ts +194 -0
  165. package/dist/presets/extend.test.d.ts +4 -0
  166. package/dist/presets/fullstack-app.d.ts +12 -0
  167. package/dist/presets/index.d.ts +13 -0
  168. package/dist/presets/jamstack.d.ts +12 -0
  169. package/dist/presets/microservices.d.ts +18 -0
  170. package/dist/presets/ml-api.d.ts +13 -0
  171. package/dist/presets/nodejs-server.d.ts +14 -0
  172. package/dist/presets/nodejs-serverless.d.ts +14 -0
  173. package/dist/presets/realtime-app.d.ts +11 -0
  174. package/dist/presets/static-site.d.ts +12 -0
  175. package/dist/presets/traditional-web-app.d.ts +16 -0
  176. package/dist/presets/wordpress.d.ts +12 -0
  177. package/dist/preview/github.d.ts +32 -0
  178. package/dist/preview/github.test.d.ts +1 -0
  179. package/dist/preview/index.d.ts +10 -0
  180. package/dist/preview/manager.d.ts +101 -0
  181. package/dist/preview/manager.test.d.ts +1 -0
  182. package/dist/preview/notifications.d.ts +89 -0
  183. package/dist/preview/notifications.test.d.ts +1 -0
  184. package/dist/queue/batch-processing.d.ts +138 -0
  185. package/dist/queue/dlq-monitoring.d.ts +143 -0
  186. package/dist/queue/fifo.d.ts +131 -0
  187. package/dist/queue/index.d.ts +8 -0
  188. package/dist/queue/management.d.ts +162 -0
  189. package/dist/queue/queue.test.d.ts +1 -0
  190. package/dist/resource-mgmt/index.d.ts +44 -0
  191. package/dist/resource-naming.d.ts +26 -0
  192. package/dist/s3/index.d.ts +227 -0
  193. package/dist/schema/index.d.ts +12 -0
  194. package/dist/security/certificate-manager.d.ts +184 -0
  195. package/dist/security/index.d.ts +8 -0
  196. package/dist/security/scanning.d.ts +196 -0
  197. package/dist/security/secrets-manager.d.ts +204 -0
  198. package/dist/security/secrets-rotation.d.ts +167 -0
  199. package/dist/security/security.test.d.ts +1 -0
  200. package/dist/sms/advanced/ab-testing.d.ts +74 -0
  201. package/dist/sms/advanced/analytics.d.ts +75 -0
  202. package/dist/sms/advanced/campaigns.d.ts +96 -0
  203. package/dist/sms/advanced/chatbot.d.ts +67 -0
  204. package/dist/sms/advanced/index.d.ts +9 -0
  205. package/dist/sms/advanced/link-tracking.d.ts +60 -0
  206. package/dist/sms/advanced/mms.d.ts +60 -0
  207. package/dist/sms/handlers/__tests__/send.test.d.ts +1 -0
  208. package/dist/sms/handlers/delivery-status.d.ts +10 -0
  209. package/dist/sms/handlers/receive.d.ts +10 -0
  210. package/dist/sms/handlers/send.d.ts +10 -0
  211. package/dist/sms/index.d.ts +5 -0
  212. package/dist/stack-diff.d.ts +38 -0
  213. package/dist/static-site/index.d.ts +49 -0
  214. package/dist/template-builder.d.ts +42 -0
  215. package/dist/template-validator.d.ts +28 -0
  216. package/dist/types.d.ts +2514 -0
  217. package/dist/utils/cache.d.ts +117 -0
  218. package/dist/utils/diff.d.ts +52 -0
  219. package/dist/utils/hash.d.ts +73 -0
  220. package/dist/utils/index.d.ts +7 -0
  221. package/dist/utils/parallel.d.ts +78 -0
  222. package/dist/validators/credentials.d.ts +30 -0
  223. package/dist/validators/credentials.test.d.ts +4 -0
  224. package/dist/validators/quotas.d.ts +64 -0
  225. package/dist/validators/quotas.test.d.ts +4 -0
  226. package/package.json +2 -2
package/dist/index.js CHANGED
@@ -22157,7 +22157,8 @@ exports.handler = async (event) => {
22157
22157
 
22158
22158
  if (uri.endsWith('/')) {
22159
22159
  request.uri = uri + 'index.html';
22160
- } else if (!uri.includes('.')) {
22160
+ }
22161
+ else if (!uri.includes('.')) {
22161
22162
  request.uri = uri + '.html';
22162
22163
  }
22163
22164
 
@@ -24583,6 +24584,74 @@ systemctl enable stacks-api
24583
24584
  `;
24584
24585
  script += `
24585
24586
  echo "Server setup complete!"
24587
+ `;
24588
+ return script;
24589
+ },
24590
+ generateBunAppScript: (options) => {
24591
+ const {
24592
+ runtime = "bun",
24593
+ runtimeVersion = "latest",
24594
+ systemPackages = [],
24595
+ database
24596
+ } = options;
24597
+ const packages = new Set(systemPackages);
24598
+ if (database === "sqlite")
24599
+ packages.add("sqlite");
24600
+ else if (database === "mysql")
24601
+ packages.add("mysql");
24602
+ else if (database === "postgres")
24603
+ packages.add("postgresql15");
24604
+ let script = `#!/bin/bash
24605
+ set -euo pipefail
24606
+
24607
+ # Amazon Linux 2023 base setup
24608
+ dnf update -y
24609
+ dnf install -y curl tar gzip unzip git
24610
+ `;
24611
+ if (packages.size > 0) {
24612
+ script += `
24613
+ # System packages (latest from AL2023 repo)
24614
+ dnf install -y ${[...packages].join(" ")}
24615
+ `;
24616
+ }
24617
+ script += `
24618
+ # AWS CLI v2 (needed by the deploy step to pull release artifacts from S3)
24619
+ if ! command -v aws &> /dev/null; then
24620
+ curl -fsSL "https://awscli.amazonaws.com/awscli-exe-linux-$(uname -m).zip" -o /tmp/awscliv2.zip
24621
+ unzip -q /tmp/awscliv2.zip -d /tmp
24622
+ /tmp/aws/install
24623
+ rm -rf /tmp/aws /tmp/awscliv2.zip
24624
+ fi
24625
+ `;
24626
+ if (runtime === "bun") {
24627
+ script += `
24628
+ # Bun runtime${runtimeVersion === "latest" ? "" : ` (pinned to ${runtimeVersion})`}
24629
+ export BUN_INSTALL="/root/.bun"
24630
+ curl -fsSL https://bun.sh/install | bash${runtimeVersion === "latest" ? "" : ` -s "bun-v${runtimeVersion}"`}
24631
+ ln -sf /root/.bun/bin/bun /usr/local/bin/bun
24632
+ echo 'export BUN_INSTALL="/root/.bun"' > /etc/profile.d/bun.sh
24633
+ echo 'export PATH="$BUN_INSTALL/bin:$PATH"' >> /etc/profile.d/bun.sh
24634
+ `;
24635
+ } else if (runtime === "node") {
24636
+ const nodeMajor = runtimeVersion === "latest" || !runtimeVersion ? "20" : runtimeVersion.split(".")[0];
24637
+ script += `
24638
+ # Node.js (major ${nodeMajor})
24639
+ dnf install -y nodejs${nodeMajor}
24640
+ ln -sf /usr/bin/node /usr/local/bin/node
24641
+ ln -sf /usr/bin/npm /usr/local/bin/npm
24642
+ `;
24643
+ } else if (runtime === "deno") {
24644
+ script += `
24645
+ # Deno runtime
24646
+ curl -fsSL https://deno.land/install.sh | sh
24647
+ ln -sf /root/.deno/bin/deno /usr/local/bin/deno
24648
+ `;
24649
+ }
24650
+ script += `
24651
+ # Reserved root for site deploys (each site lands at /var/www/<site>/)
24652
+ mkdir -p /var/www
24653
+
24654
+ echo "ts-cloud bootstrap complete — instance is ready for site deploys"
24586
24655
  `;
24587
24656
  return script;
24588
24657
  },
@@ -26498,16 +26567,19 @@ exports.handler = async (event) => {
26498
26567
  try {
26499
26568
  const resp = await s3.send(new GetObjectCommand({ Bucket: bucket, Key: key }));
26500
26569
  rawEmail = await resp.Body.transformToString();
26501
- } catch (e) {
26570
+ }
26571
+ catch (e) {
26502
26572
  console.log('Raw email not in S3 yet, using SES headers only');
26503
26573
  }
26504
- } else if (event.Records && event.Records[0] && event.Records[0].s3) {
26574
+ }
26575
+ else if (event.Records && event.Records[0] && event.Records[0].s3) {
26505
26576
  // S3 event notification
26506
26577
  const key = decodeURIComponent(event.Records[0].s3.object.key.replace(/\\+/g, ' '));
26507
26578
  messageId = key.split('/').pop();
26508
26579
  const resp = await s3.send(new GetObjectCommand({ Bucket: bucket, Key: key }));
26509
26580
  rawEmail = await resp.Body.transformToString();
26510
- } else if (event.mail) {
26581
+ }
26582
+ else if (event.mail) {
26511
26583
  // Direct SES event
26512
26584
  sesMailData = event;
26513
26585
  messageId = event.mail.messageId;
@@ -26515,7 +26587,8 @@ exports.handler = async (event) => {
26515
26587
  try {
26516
26588
  const resp = await s3.send(new GetObjectCommand({ Bucket: bucket, Key: key }));
26517
26589
  rawEmail = await resp.Body.transformToString();
26518
- } catch (e) {
26590
+ }
26591
+ catch (e) {
26519
26592
  console.log('Raw email not in S3 yet');
26520
26593
  }
26521
26594
  }
@@ -26609,7 +26682,8 @@ exports.handler = async (event) => {
26609
26682
  try {
26610
26683
  const resp = await s3.send(new GetObjectCommand({ Bucket: bucket, Key: inboxKey }));
26611
26684
  inbox = JSON.parse(await resp.Body.transformToString());
26612
- } catch (e) {
26685
+ }
26686
+ catch (e) {
26613
26687
  // inbox.json doesn't exist yet
26614
26688
  }
26615
26689
 
@@ -26658,7 +26732,8 @@ function parseEmailHeaders(rawEmail) {
26658
26732
  if (line.match(/^\\s/) && currentKey) {
26659
26733
  currentValue += ' ' + line.trim();
26660
26734
  headers[currentKey] = currentValue;
26661
- } else {
26735
+ }
26736
+ else {
26662
26737
  const match = line.match(/^([^:]+):\\s*(.*)$/);
26663
26738
  if (match) {
26664
26739
  currentKey = match[1].toLowerCase();
@@ -26716,24 +26791,30 @@ function parseEmailBody(rawEmail) {
26716
26791
  const npCT = (npH.match(/Content-Type:\\s*([^;\\r\\n]+)/i)?.[1] || '').trim();
26717
26792
  if (npCT.includes('text/plain') && !result.text) {
26718
26793
  result.text = decodeContent(npContent, npH);
26719
- } else if (npCT.includes('text/html') && !result.html) {
26794
+ }
26795
+ else if (npCT.includes('text/html') && !result.html) {
26720
26796
  result.html = decodeContent(npContent, npH);
26721
26797
  }
26722
26798
  }
26723
26799
  }
26724
- } else if (partCT.includes('text/plain') && !result.text) {
26800
+ }
26801
+ else if (partCT.includes('text/plain') && !result.text) {
26725
26802
  result.text = decodeContent(partContent, partHeaders);
26726
- } else if (partCT.includes('text/html') && !result.html) {
26803
+ }
26804
+ else if (partCT.includes('text/html') && !result.html) {
26727
26805
  result.html = decodeContent(partContent, partHeaders);
26728
- } else if (partHeaders.toLowerCase().includes('content-disposition: attachment') ||
26806
+ }
26807
+ else if (partHeaders.toLowerCase().includes('content-disposition: attachment') ||
26729
26808
  partHeaders.toLowerCase().includes('content-disposition: inline')) {
26730
26809
  result.hasAttachments = true;
26731
26810
  }
26732
26811
  }
26733
26812
  }
26734
- } else if (contentType.includes('text/html')) {
26813
+ }
26814
+ else if (contentType.includes('text/html')) {
26735
26815
  result.html = body;
26736
- } else {
26816
+ }
26817
+ else {
26737
26818
  result.text = body;
26738
26819
  }
26739
26820
 
@@ -26745,7 +26826,8 @@ function decodeContent(content, headers) {
26745
26826
 
26746
26827
  if (encoding === 'base64') {
26747
26828
  return Buffer.from(content.replace(/\\s/g, ''), 'base64').toString('utf-8');
26748
- } else if (encoding === 'quoted-printable') {
26829
+ }
26830
+ else if (encoding === 'quoted-printable') {
26749
26831
  return content.replace(/=([0-9A-Fa-f]{2})/g, (_, hex) => String.fromCharCode(parseInt(hex, 16)))
26750
26832
  .replace(/=\\r?\\n/g, '');
26751
26833
  }
@@ -26850,7 +26932,8 @@ function parseEmail(rawEmail) {
26850
26932
  for (const line of headerLines) {
26851
26933
  if (line.match(/^\\s/)) {
26852
26934
  currentValue += ' ' + line.trim();
26853
- } else {
26935
+ }
26936
+ else {
26854
26937
  if (currentHeader) {
26855
26938
  result.headers[currentHeader.toLowerCase()] = currentValue;
26856
26939
  }
@@ -26883,9 +26966,11 @@ function parseEmail(rawEmail) {
26883
26966
 
26884
26967
  if (partContentType.includes('text/plain')) {
26885
26968
  result.text = decodeContent(partContent, partHeaders);
26886
- } else if (partContentType.includes('text/html')) {
26969
+ }
26970
+ else if (partContentType.includes('text/html')) {
26887
26971
  result.html = decodeContent(partContent, partHeaders);
26888
- } else if (partHeaders.toLowerCase().includes('content-disposition: attachment')) {
26972
+ }
26973
+ else if (partHeaders.toLowerCase().includes('content-disposition: attachment')) {
26889
26974
  const filenameMatch = partHeaders.match(/filename="?([^"\\r\\n]+)"?/i);
26890
26975
  result.attachments.push({
26891
26976
  filename: filenameMatch?.[1] || 'attachment',
@@ -26896,9 +26981,11 @@ function parseEmail(rawEmail) {
26896
26981
  }
26897
26982
  }
26898
26983
  }
26899
- } else if (contentType.includes('text/html')) {
26984
+ }
26985
+ else if (contentType.includes('text/html')) {
26900
26986
  result.html = body;
26901
- } else {
26987
+ }
26988
+ else {
26902
26989
  result.text = body;
26903
26990
  }
26904
26991
 
@@ -26910,7 +26997,8 @@ function decodeContent(content, headers) {
26910
26997
 
26911
26998
  if (encoding === 'base64') {
26912
26999
  return Buffer.from(content.replace(/\\s/g, ''), 'base64').toString('utf-8');
26913
- } else if (encoding === 'quoted-printable') {
27000
+ }
27001
+ else if (encoding === 'quoted-printable') {
26914
27002
  return content.replace(/=([0-9A-F]{2})/gi, (_, hex) => String.fromCharCode(parseInt(hex, 16)))
26915
27003
  .replace(/=\\r?\\n/g, '');
26916
27004
  }
@@ -27007,7 +27095,8 @@ exports.handler = async (event) => {
27007
27095
  data: callDetails,
27008
27096
  }),
27009
27097
  });
27010
- } catch (err) {
27098
+ }
27099
+ catch (err) {
27011
27100
  console.error('Webhook notification failed:', err.message);
27012
27101
  }
27013
27102
  }
@@ -27023,7 +27112,8 @@ exports.handler = async (event) => {
27023
27112
  },
27024
27113
  };
27025
27114
 
27026
- } catch (error) {
27115
+ }
27116
+ catch (error) {
27027
27117
  console.error('Error processing incoming call:', error);
27028
27118
  return {
27029
27119
  statusCode: 500,
@@ -27080,7 +27170,8 @@ exports.handler = async (event) => {
27080
27170
  Key: key.replace('.wav', '.json'),
27081
27171
  }));
27082
27172
  metadata = JSON.parse(await metaResult.Body.transformToString());
27083
- } catch {
27173
+ }
27174
+ catch {
27084
27175
  // No metadata file
27085
27176
  }
27086
27177
 
@@ -27123,11 +27214,13 @@ exports.handler = async (event) => {
27123
27214
  }));
27124
27215
  const transcriptData = JSON.parse(await transcriptResult.Body.transformToString());
27125
27216
  transcription = transcriptData.results?.transcripts?.[0]?.transcript || '';
27126
- } catch (err) {
27217
+ }
27218
+ catch (err) {
27127
27219
  console.error('Error getting transcription:', err.message);
27128
27220
  }
27129
27221
  break;
27130
- } else if (status === 'FAILED') {
27222
+ }
27223
+ else if (status === 'FAILED') {
27131
27224
  console.error('Transcription failed');
27132
27225
  break;
27133
27226
  }
@@ -27195,7 +27288,8 @@ exports.handler = async (event) => {
27195
27288
 
27196
27289
  console.log(\`Processed voicemail: \${contactId}\`);
27197
27290
 
27198
- } catch (error) {
27291
+ }
27292
+ catch (error) {
27199
27293
  console.error('Error processing voicemail:', error);
27200
27294
  }
27201
27295
  }
@@ -27292,7 +27386,8 @@ exports.handler = async (event) => {
27292
27386
  data: callDetails,
27293
27387
  }),
27294
27388
  });
27295
- } catch (err) {
27389
+ }
27390
+ catch (err) {
27296
27391
  console.error('Webhook notification failed:', err.message);
27297
27392
  }
27298
27393
  }
@@ -27302,7 +27397,8 @@ exports.handler = async (event) => {
27302
27397
  message: 'Missed call logged',
27303
27398
  };
27304
27399
 
27305
- } catch (error) {
27400
+ }
27401
+ catch (error) {
27306
27402
  console.error('Error processing missed call:', error);
27307
27403
  return {
27308
27404
  statusCode: 500,
@@ -28327,7 +28423,8 @@ async function run() {
28327
28423
  console.log(\`[Job Runner] Job \${jobClass} completed in \${duration}ms\`)
28328
28424
 
28329
28425
  process.exit(0)
28330
- } catch (error) {
28426
+ }
28427
+ catch (error) {
28331
28428
  console.error(\`[Job Runner] Job \${jobClass} failed:\`, error)
28332
28429
  process.exit(1)
28333
28430
  }
@@ -28458,7 +28555,8 @@ exports.handler = async (event) => {
28458
28555
  statusCode: result.StatusCode,
28459
28556
  });
28460
28557
 
28461
- } else {
28558
+ }
28559
+ else {
28462
28560
  // Fallback to SNS
28463
28561
  const snsResult = await sns.send(new PublishCommand({
28464
28562
  PhoneNumber: to,
@@ -28502,7 +28600,8 @@ exports.handler = async (event) => {
28502
28600
 
28503
28601
  console.log(\`SMS sent to \${to}: \${results[results.length - 1].status}\`);
28504
28602
 
28505
- } catch (error) {
28603
+ }
28604
+ catch (error) {
28506
28605
  console.error('Error sending SMS:', error);
28507
28606
  results.push({
28508
28607
  to: message.to,
@@ -28665,14 +28764,16 @@ exports.handler = async (event) => {
28665
28764
  });
28666
28765
 
28667
28766
  console.log(\`Webhook response: \${response.status}\`);
28668
- } catch (err) {
28767
+ }
28768
+ catch (err) {
28669
28769
  console.error('Webhook failed:', err.message);
28670
28770
  }
28671
28771
  }
28672
28772
 
28673
28773
  console.log(\`Processed inbound SMS from \${originationNumber}\`);
28674
28774
 
28675
- } catch (error) {
28775
+ }
28776
+ catch (error) {
28676
28777
  console.error('Error processing inbound SMS:', error);
28677
28778
  }
28678
28779
  }
@@ -28791,12 +28892,14 @@ exports.handler = async (event) => {
28791
28892
  },
28792
28893
  }),
28793
28894
  });
28794
- } catch (err) {
28895
+ }
28896
+ catch (err) {
28795
28897
  console.error('Webhook failed:', err.message);
28796
28898
  }
28797
28899
  }
28798
28900
 
28799
- } catch (error) {
28901
+ }
28902
+ catch (error) {
28800
28903
  console.error('Error processing delivery status:', error);
28801
28904
  }
28802
28905
  }
@@ -57267,7 +57370,8 @@ exports.handler = async (event) => {
57267
57370
  const previewKey = key.replace('/metadata.json', '/preview.txt');
57268
57371
  const previewResult = await s3.send(new GetObjectCommand({ Bucket: bucket, Key: previewKey }));
57269
57372
  bodyPreview = await previewResult.Body.transformToString();
57270
- } catch {}
57373
+ }
57374
+ catch {}
57271
57375
 
57272
57376
  // Get full body for indexing
57273
57377
  let body = '';
@@ -57275,7 +57379,8 @@ exports.handler = async (event) => {
57275
57379
  const textKey = key.replace('/metadata.json', '/body.txt');
57276
57380
  const textResult = await s3.send(new GetObjectCommand({ Bucket: bucket, Key: textKey }));
57277
57381
  body = await textResult.Body.transformToString();
57278
- } catch {}
57382
+ }
57383
+ catch {}
57279
57384
 
57280
57385
  // Extract mailbox from path
57281
57386
  const pathParts = key.split('/');
@@ -57304,7 +57409,8 @@ exports.handler = async (event) => {
57304
57409
  await indexDocument(doc);
57305
57410
 
57306
57411
  console.log('Indexed email:', metadata.messageId);
57307
- } catch (error) {
57412
+ }
57413
+ catch (error) {
57308
57414
  console.error('Error indexing email:', error);
57309
57415
  }
57310
57416
  }
@@ -57495,7 +57601,8 @@ exports.handler = async (event) => {
57495
57601
  await updateThreadIndex(bucket, mailboxPath, threadId, metadata);
57496
57602
 
57497
57603
  console.log(\`Threaded email \${metadata.messageId} into thread \${threadId}\`);
57498
- } catch (error) {
57604
+ }
57605
+ catch (error) {
57499
57606
  console.error('Error threading email:', error);
57500
57607
  }
57501
57608
  }
@@ -57530,7 +57637,8 @@ async function updateThreadIndex(bucket, mailboxPath, threadId, metadata) {
57530
57637
  Key: threadsKey,
57531
57638
  }));
57532
57639
  threads = JSON.parse(await result.Body.transformToString());
57533
- } catch {
57640
+ }
57641
+ catch {
57534
57642
  // No threads file yet
57535
57643
  }
57536
57644
 
@@ -57718,7 +57826,8 @@ exports.handler = async (event) => {
57718
57826
  }));
57719
57827
 
57720
57828
  console.log(\`Sent scheduled email: \${scheduled.id}\`);
57721
- } catch (sendError) {
57829
+ }
57830
+ catch (sendError) {
57722
57831
  console.error(\`Failed to send scheduled email: \${scheduled.id}\`, sendError);
57723
57832
 
57724
57833
  // Update retry count
@@ -57736,7 +57845,8 @@ exports.handler = async (event) => {
57736
57845
  ContentType: 'application/json',
57737
57846
  }));
57738
57847
  }
57739
- } catch (error) {
57848
+ }
57849
+ catch (error) {
57740
57850
  console.error(\`Error processing scheduled email: \${obj.Key}\`, error);
57741
57851
  }
57742
57852
  }
@@ -57764,10 +57874,12 @@ function buildRawEmail(email) {
57764
57874
  raw += 'Content-Type: text/html; charset=UTF-8\\r\\n\\r\\n';
57765
57875
  raw += email.html + '\\r\\n\\r\\n';
57766
57876
  raw += \`--\${boundary}--\\r\\n\`;
57767
- } else if (email.html) {
57877
+ }
57878
+ else if (email.html) {
57768
57879
  raw += 'Content-Type: text/html; charset=UTF-8\\r\\n\\r\\n';
57769
57880
  raw += email.html;
57770
- } else {
57881
+ }
57882
+ else {
57771
57883
  raw += 'Content-Type: text/plain; charset=UTF-8\\r\\n\\r\\n';
57772
57884
  raw += email.text || '';
57773
57885
  }
@@ -57928,7 +58040,8 @@ exports.handler = async (event) => {
57928
58040
 
57929
58041
  console.log(\`Tracked open for: \${messageId}\`);
57930
58042
  }
57931
- } catch (error) {
58043
+ }
58044
+ catch (error) {
57932
58045
  console.error('Error tracking open:', error);
57933
58046
  }
57934
58047
 
@@ -58004,7 +58117,8 @@ exports.handler = async (event) => {
58004
58117
  },
58005
58118
  body: '',
58006
58119
  };
58007
- } catch (error) {
58120
+ }
58121
+ catch (error) {
58008
58122
  console.error('Error tracking click:', error);
58009
58123
  return {
58010
58124
  statusCode: 500,
@@ -58090,7 +58204,8 @@ exports.handler = async (event) => {
58090
58204
  }));
58091
58205
 
58092
58206
  console.log(\`Processed \${eventType} for: \${messageId}\`);
58093
- } catch (error) {
58207
+ }
58208
+ catch (error) {
58094
58209
  console.error('Error processing SES event:', error);
58095
58210
  }
58096
58211
  }
@@ -58265,7 +58380,8 @@ exports.handler = async (event) => {
58265
58380
  headers: { 'Content-Type': 'application/json' },
58266
58381
  body: JSON.stringify(rendered),
58267
58382
  };
58268
- } catch (error) {
58383
+ }
58384
+ catch (error) {
58269
58385
  console.error('Error rendering template:', error);
58270
58386
  return {
58271
58387
  statusCode: error.name === 'NoSuchKey' ? 404 : 500,
@@ -58641,7 +58757,8 @@ exports.handler = async (event) => {
58641
58757
  default:
58642
58758
  return { statusCode: 404, body: JSON.stringify({ error: 'Not found' }) };
58643
58759
  }
58644
- } catch (error) {
58760
+ }
58761
+ catch (error) {
58645
58762
  console.error('Error:', error);
58646
58763
  return { statusCode: 500, body: JSON.stringify({ error: error.message }) };
58647
58764
  }
@@ -58816,7 +58933,8 @@ async function getMailboxMessages(mailboxId, _queryParams) {
58816
58933
  statusCode: 200,
58817
58934
  body: JSON.stringify(messages),
58818
58935
  };
58819
- } catch (error) {
58936
+ }
58937
+ catch (error) {
58820
58938
  if (error.name === 'NoSuchKey') {
58821
58939
  return { statusCode: 200, body: JSON.stringify([]) };
58822
58940
  }
@@ -58984,7 +59102,8 @@ exports.handler = async (event) => {
58984
59102
  // Stop processing if rule says so
58985
59103
  if (rule.stopProcessing) break;
58986
59104
  }
58987
- } catch (error) {
59105
+ }
59106
+ catch (error) {
58988
59107
  console.error('Error processing rules:', error);
58989
59108
  }
58990
59109
  }
@@ -59072,7 +59191,8 @@ function evaluateCondition(metadata, condition) {
59072
59191
  try {
59073
59192
  const regex = new RegExp(condition.value, condition.caseSensitive ? '' : 'i');
59074
59193
  return regex.test(value);
59075
- } catch {
59194
+ }
59195
+ catch {
59076
59196
  return false;
59077
59197
  }
59078
59198
  case 'greater-than':
@@ -59143,7 +59263,8 @@ async function moveEmail(bucket, basePath, folder, mailbox) {
59143
59263
  Bucket: bucket,
59144
59264
  Key: \`\${basePath}/\${file}\`,
59145
59265
  }));
59146
- } catch {}
59266
+ }
59267
+ catch {}
59147
59268
  }
59148
59269
  }
59149
59270
 
@@ -59159,7 +59280,8 @@ async function copyEmail(bucket, basePath, folder, mailbox) {
59159
59280
  CopySource: \`\${bucket}/\${basePath}/\${file}\`,
59160
59281
  Key: \`\${newBasePath}/\${file}\`,
59161
59282
  }));
59162
- } catch {}
59283
+ }
59284
+ catch {}
59163
59285
  }
59164
59286
  }
59165
59287
 
@@ -59171,7 +59293,8 @@ async function deleteEmail(bucket, basePath) {
59171
59293
  Bucket: bucket,
59172
59294
  Key: \`\${basePath}/\${file}\`,
59173
59295
  }));
59174
- } catch {}
59296
+ }
59297
+ catch {}
59175
59298
  }
59176
59299
  }
59177
59300
 
@@ -59355,7 +59478,8 @@ exports.handler = async (event) => {
59355
59478
  Key: sourceKey,
59356
59479
  }));
59357
59480
  rawEmail = await getResult.Body.transformToString();
59358
- } catch (err) {
59481
+ }
59482
+ catch (err) {
59359
59483
  console.log('Could not retrieve raw email:', err.message);
59360
59484
  continue;
59361
59485
  }
@@ -59370,7 +59494,8 @@ exports.handler = async (event) => {
59370
59494
  const colonIndex = line.indexOf(':');
59371
59495
  currentHeader = line.substring(0, colonIndex).toLowerCase();
59372
59496
  headers[currentHeader] = line.substring(colonIndex + 1).trim();
59373
- } else if (currentHeader && (line.startsWith(' ') || line.startsWith('\\t'))) {
59497
+ }
59498
+ else if (currentHeader && (line.startsWith(' ') || line.startsWith('\\t'))) {
59374
59499
  headers[currentHeader] += ' ' + line.trim();
59375
59500
  }
59376
59501
  }
@@ -59445,7 +59570,8 @@ exports.handler = async (event) => {
59445
59570
  Key: indexKey,
59446
59571
  }));
59447
59572
  inbox = JSON.parse(await indexResult.Body.transformToString());
59448
- } catch {
59573
+ }
59574
+ catch {
59449
59575
  // Index doesn't exist yet
59450
59576
  }
59451
59577
 
@@ -59470,7 +59596,8 @@ exports.handler = async (event) => {
59470
59596
 
59471
59597
  console.log(\`Processed email: \${messageId} from \${fromEmail} to \${toEmail}\`);
59472
59598
 
59473
- } catch (error) {
59599
+ }
59600
+ catch (error) {
59474
59601
  console.error('Error processing email:', error);
59475
59602
  }
59476
59603
  }
@@ -59560,7 +59687,8 @@ exports.handler = async (event) => {
59560
59687
  }));
59561
59688
 
59562
59689
  console.log(\`Started transcription for: \${recordingId}\`);
59563
- } catch (error) {
59690
+ }
59691
+ catch (error) {
59564
59692
  console.error('Error processing recording:', error);
59565
59693
  }
59566
59694
  }
@@ -59637,7 +59765,8 @@ exports.handler = async (event) => {
59637
59765
  text: content,
59638
59766
  confidence,
59639
59767
  };
59640
- } else {
59768
+ }
59769
+ else {
59641
59770
  currentSegment.endTime = endTime;
59642
59771
  currentSegment.text += ' ' + content;
59643
59772
  currentSegment.confidence = (currentSegment.confidence + confidence) / 2;
@@ -59665,7 +59794,8 @@ exports.handler = async (event) => {
59665
59794
  }));
59666
59795
 
59667
59796
  console.log(\`Transcription completed for: \${recordingId}\`);
59668
- } else if (jobStatus === 'FAILED') {
59797
+ }
59798
+ else if (jobStatus === 'FAILED') {
59669
59799
  await dynamodb.send(new UpdateItemCommand({
59670
59800
  TableName: RECORDINGS_TABLE,
59671
59801
  Key: { recordingId: { S: recordingId } },
@@ -60147,7 +60277,8 @@ exports.handler = async (event) => {
60147
60277
 
60148
60278
  console.log('Metrics aggregated successfully');
60149
60279
  return { statusCode: 200 };
60150
- } catch (error) {
60280
+ }
60281
+ catch (error) {
60151
60282
  console.error('Error aggregating metrics:', error);
60152
60283
  return { statusCode: 500, error: error.message };
60153
60284
  }
@@ -60272,7 +60403,8 @@ exports.handler = async (event) => {
60272
60403
  headers: { 'Content-Type': 'application/json' },
60273
60404
  body: JSON.stringify(metrics),
60274
60405
  };
60275
- } catch (error) {
60406
+ }
60407
+ catch (error) {
60276
60408
  console.error('Error getting queue metrics:', error);
60277
60409
  return {
60278
60410
  statusCode: 500,
@@ -60382,7 +60514,8 @@ exports.handler = async (event) => {
60382
60514
  default:
60383
60515
  return { statusCode: 405, body: JSON.stringify({ error: 'Method not allowed' }) };
60384
60516
  }
60385
- } catch (error) {
60517
+ }
60518
+ catch (error) {
60386
60519
  console.error('Error:', error);
60387
60520
  return { statusCode: 500, body: JSON.stringify({ error: error.message }) };
60388
60521
  }
@@ -60599,7 +60732,8 @@ exports.handler = async (event) => {
60599
60732
  },
60600
60733
  }));
60601
60734
 
60602
- } catch (callError) {
60735
+ }
60736
+ catch (callError) {
60603
60737
  console.error(\`Failed to call \${phoneNumber}:\`, callError);
60604
60738
 
60605
60739
  // Check if max attempts reached
@@ -60614,7 +60748,8 @@ exports.handler = async (event) => {
60614
60748
  ':error': { S: callError.message },
60615
60749
  },
60616
60750
  }));
60617
- } else {
60751
+ }
60752
+ else {
60618
60753
  // Reset to pending for retry
60619
60754
  await dynamodb.send(new UpdateItemCommand({
60620
60755
  TableName: CALLBACKS_TABLE,
@@ -60630,7 +60765,8 @@ exports.handler = async (event) => {
60630
60765
  }
60631
60766
 
60632
60767
  return { statusCode: 200, processed: toProcess.length };
60633
- } catch (error) {
60768
+ }
60769
+ catch (error) {
60634
60770
  console.error('Error processing callbacks:', error);
60635
60771
  return { statusCode: 500, error: error.message };
60636
60772
  }
@@ -60750,7 +60886,8 @@ exports.handler = async (event) => {
60750
60886
  default:
60751
60887
  return { statusCode: 405, body: JSON.stringify({ error: 'Method not allowed' }) };
60752
60888
  }
60753
- } catch (error) {
60889
+ }
60890
+ catch (error) {
60754
60891
  console.error('Error:', error);
60755
60892
  return { statusCode: 500, body: JSON.stringify({ error: error.message }) };
60756
60893
  }
@@ -60951,7 +61088,8 @@ exports.handler = async (event) => {
60951
61088
  }
60952
61089
 
60953
61090
  return { statusCode: 200 };
60954
- } catch (error) {
61091
+ }
61092
+ catch (error) {
60955
61093
  console.error('Error executing campaigns:', error);
60956
61094
  return { statusCode: 500, error: error.message };
60957
61095
  }
@@ -61017,11 +61155,13 @@ async function executeCampaign(campaign) {
61017
61155
  if (status === 'SUCCESSFUL') {
61018
61156
  delivered++;
61019
61157
  cost += 0.00645; // Approximate US SMS cost
61020
- } else {
61158
+ }
61159
+ else {
61021
61160
  failed++;
61022
61161
  }
61023
61162
  sent++;
61024
- } catch (error) {
61163
+ }
61164
+ catch (error) {
61025
61165
  console.error(\`Failed to send to \${recipient.phoneNumber}:\`, error);
61026
61166
  failed++;
61027
61167
  }
@@ -61237,7 +61377,8 @@ exports.handler = async (event) => {
61237
61377
 
61238
61378
  console.log('SMS analytics aggregated successfully');
61239
61379
  return { statusCode: 200 };
61240
- } catch (error) {
61380
+ }
61381
+ catch (error) {
61241
61382
  console.error('Error aggregating SMS analytics:', error);
61242
61383
  return { statusCode: 500, error: error.message };
61243
61384
  }
@@ -61334,7 +61475,8 @@ exports.handler = async (event) => {
61334
61475
  }));
61335
61476
 
61336
61477
  console.log(\`Tracked delivery for \${messageId}: \${messageStatus}\`);
61337
- } catch (error) {
61478
+ }
61479
+ catch (error) {
61338
61480
  console.error('Error tracking delivery:', error);
61339
61481
  }
61340
61482
  }
@@ -61465,7 +61607,8 @@ exports.handler = async (event) => {
61465
61607
  try {
61466
61608
  const media = await processMedia(url, messageId);
61467
61609
  processedMedia.push(media);
61468
- } catch (error) {
61610
+ }
61611
+ catch (error) {
61469
61612
  console.error(\`Failed to process media \${url}:\`, error);
61470
61613
  }
61471
61614
  }
@@ -61536,7 +61679,8 @@ exports.handler = async (event) => {
61536
61679
  snsMessageId: snsResult.MessageId,
61537
61680
  }),
61538
61681
  };
61539
- } catch (error) {
61682
+ }
61683
+ catch (error) {
61540
61684
  console.error('Error sending MMS:', error);
61541
61685
  return {
61542
61686
  statusCode: 500,
@@ -61848,13 +61992,15 @@ exports.handler = async (event) => {
61848
61992
  // Create short link
61849
61993
  const data = JSON.parse(body || '{}');
61850
61994
  return await createShortLink(data);
61851
- } else if (httpMethod === 'GET' && pathParameters?.id) {
61995
+ }
61996
+ else if (httpMethod === 'GET' && pathParameters?.id) {
61852
61997
  // Redirect to original URL
61853
61998
  return await handleRedirect(pathParameters.id, event);
61854
61999
  }
61855
62000
 
61856
62001
  return { statusCode: 405, body: 'Method not allowed' };
61857
- } catch (error) {
62002
+ }
62003
+ catch (error) {
61858
62004
  console.error('Error:', error);
61859
62005
  return { statusCode: 500, body: JSON.stringify({ error: error.message }) };
61860
62006
  }
@@ -61939,7 +62085,8 @@ async function handleRedirect(id, event) {
61939
62085
  ':visitor': { L: [{ S: visitorId }] },
61940
62086
  },
61941
62087
  }));
61942
- } catch (e) {
62088
+ }
62089
+ catch (e) {
61943
62090
  console.error('Error tracking click:', e);
61944
62091
  }
61945
62092
 
@@ -62050,7 +62197,8 @@ exports.handler = async (event) => {
62050
62197
  default:
62051
62198
  return { statusCode: 405, body: 'Method not allowed' };
62052
62199
  }
62053
- } catch (error) {
62200
+ }
62201
+ catch (error) {
62054
62202
  console.error('Error:', error);
62055
62203
  return { statusCode: 500, body: JSON.stringify({ error: error.message }) };
62056
62204
  }