@hartl-services/medusa-base 0.4.0 → 1.1.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.
Files changed (258) hide show
  1. package/.medusa/server/src/admin/index.js +1657 -111
  2. package/.medusa/server/src/admin/index.mjs +1647 -101
  3. package/.medusa/server/src/api/admin/email/messages/[id]/resends/route.js +24 -0
  4. package/.medusa/server/src/api/admin/email/messages/[id]/route.js +12 -0
  5. package/.medusa/server/src/api/admin/email/messages/route.js +12 -0
  6. package/.medusa/server/src/api/admin/email/terms-versions/[id]/download/route.js +16 -0
  7. package/.medusa/server/src/api/admin/email/terms-versions/route.js +47 -0
  8. package/.medusa/server/src/api/admin/orders/[id]/documents/[document_id]/download/route.js +21 -0
  9. package/.medusa/server/src/api/admin/orders/[id]/documents/[document_id]/regenerate/route.js +38 -0
  10. package/.medusa/server/src/api/admin/orders/[id]/documents/regenerate/route.js +32 -0
  11. package/.medusa/server/src/api/admin/orders/[id]/documents/route.js +36 -0
  12. package/.medusa/server/src/api/admin/orders/[id]/packing-lists/[fulfillment_id]/download/route.js +24 -0
  13. package/.medusa/server/src/api/admin/orders/[id]/packing-lists/[fulfillment_id]/retry/route.js +44 -0
  14. package/.medusa/server/src/api/admin/orders/[id]/packing-lists/route.js +82 -0
  15. package/.medusa/server/src/api/document-download-response.js +16 -0
  16. package/.medusa/server/src/api/document-response.js +23 -0
  17. package/.medusa/server/src/api/files/[asset]/route.js +24 -0
  18. package/.medusa/server/src/api/files/file-response.js +43 -0
  19. package/.medusa/server/src/api/files/gateway-options.js +31 -0
  20. package/.medusa/server/src/api/files/private/[token]/route.js +29 -0
  21. package/.medusa/server/src/api/files/upload/[token]/route.js +66 -0
  22. package/.medusa/server/src/api/middlewares.js +168 -1
  23. package/.medusa/server/src/api/packing-list-response.js +22 -0
  24. package/.medusa/server/src/api/route.js +27 -0
  25. package/.medusa/server/src/api/store/documents/[id]/download/route.js +21 -0
  26. package/.medusa/server/src/api/store/documents/[id]/route.js +15 -0
  27. package/.medusa/server/src/api/store/documents/route.js +11 -0
  28. package/.medusa/server/src/api/terms-download-response.js +12 -0
  29. package/.medusa/server/src/documents/config/index.js +18 -0
  30. package/.medusa/server/src/documents/paths/documents.js +6 -0
  31. package/.medusa/server/src/documents/paths/index.js +18 -0
  32. package/.medusa/server/src/documents/plugin-features.js +38 -0
  33. package/.medusa/server/src/documents/schemas/documents.js +18 -0
  34. package/.medusa/server/src/documents/schemas/index.js +18 -0
  35. package/.medusa/server/src/documents/scripts/verify-documents-file-storage.js +55 -0
  36. package/.medusa/server/src/documents/templates/financial-document.js +160 -0
  37. package/.medusa/server/src/documents/templates/format.js +73 -0
  38. package/.medusa/server/src/documents/templates/html-factory.js +42 -0
  39. package/.medusa/server/src/documents/templates/html-utils.js +23 -0
  40. package/.medusa/server/src/documents/templates/layout.js +142 -0
  41. package/.medusa/server/src/documents/templates/packing-list.js +52 -0
  42. package/.medusa/server/src/documents/types/admin-api.js +3 -0
  43. package/.medusa/server/src/documents/types/document-summary.js +3 -0
  44. package/.medusa/server/src/documents/types/documents.js +3 -0
  45. package/.medusa/server/src/documents/types/html-factory.js +6 -0
  46. package/.medusa/server/src/documents/types/index.js +22 -0
  47. package/.medusa/server/src/documents/types/store-api.js +3 -0
  48. package/.medusa/server/src/documents/utils/document-merchant.js +22 -0
  49. package/.medusa/server/src/documents/utils/document-render-settings.js +59 -0
  50. package/.medusa/server/src/documents/utils/html-to-pdf.js +61 -0
  51. package/.medusa/server/src/documents/utils/private-file-storage.js +64 -0
  52. package/.medusa/server/src/documents/utils/resolve-services.js +7 -0
  53. package/.medusa/server/src/email/application/handle-invite-event.js +318 -0
  54. package/.medusa/server/src/email/application/handle-password-reset-event.js +366 -0
  55. package/.medusa/server/src/email/config/index.js +84 -0
  56. package/.medusa/server/src/email/config/notification-module.js +20 -0
  57. package/.medusa/server/src/email/domain/business-keys.js +50 -0
  58. package/.medusa/server/src/email/domain/documents-fact-fingerprint.js +7 -0
  59. package/.medusa/server/src/email/domain/event-schemas.js +36 -0
  60. package/.medusa/server/src/email/domain/failure-classification.js +53 -0
  61. package/.medusa/server/src/email/domain/order-summary.js +103 -0
  62. package/.medusa/server/src/email/domain/refund-summary.js +43 -0
  63. package/.medusa/server/src/email/domain/return-summary.js +118 -0
  64. package/.medusa/server/src/email/domain/shipment-summary.js +74 -0
  65. package/.medusa/server/src/email/plugin-features.js +39 -0
  66. package/.medusa/server/src/email/rendering/default-templates.js +719 -0
  67. package/.medusa/server/src/email/rendering/load-email-shop-details.js +36 -0
  68. package/.medusa/server/src/email/rendering/render-email.js +50 -0
  69. package/.medusa/server/src/email/rendering/resolve-shop-configuration.js +67 -0
  70. package/.medusa/server/src/email/types/email-kinds.js +18 -0
  71. package/.medusa/server/src/email/types/index.js +21 -0
  72. package/.medusa/server/src/email/types/shop-configuration.js +3 -0
  73. package/.medusa/server/src/email/types/smtp-configuration.js +3 -0
  74. package/.medusa/server/src/email/types/template-data.js +232 -0
  75. package/.medusa/server/src/files/config/index.js +256 -0
  76. package/.medusa/server/src/files/gateway/index.js +115 -0
  77. package/.medusa/server/src/files/types/index.js +6 -0
  78. package/.medusa/server/src/files/types/public.js +6 -0
  79. package/.medusa/server/src/jobs/document-fact-publication-reconciliation.js +18 -0
  80. package/.medusa/server/src/jobs/document-resolution-reconciliation.js +20 -0
  81. package/.medusa/server/src/jobs/packing-list-reconciliation.js +49 -0
  82. package/.medusa/server/src/jobs/reconcile-email-attempts.js +63 -0
  83. package/.medusa/server/src/jobs/reconcile-pending-email-messages.js +41 -0
  84. package/.medusa/server/src/jobs/retry-email-messages.js +27 -0
  85. package/.medusa/server/src/migration-scripts/dismiss-orphaned-cart-promotion-links.js +26 -0
  86. package/.medusa/server/src/modules/documents/domain/cancellation-snapshot.js +97 -0
  87. package/.medusa/server/src/modules/documents/domain/document-number.js +36 -0
  88. package/.medusa/server/src/modules/documents/domain/document-resolution.js +24 -0
  89. package/.medusa/server/src/modules/documents/domain/issuance-rules.js +37 -0
  90. package/.medusa/server/src/modules/documents/domain/merchant.js +86 -0
  91. package/.medusa/server/src/modules/documents/domain/options.js +40 -0
  92. package/.medusa/server/src/modules/documents/domain/packing-list.js +90 -0
  93. package/.medusa/server/src/modules/documents/domain/snapshot-normalization.js +17 -0
  94. package/.medusa/server/src/modules/documents/domain/tax-breakdown.js +66 -0
  95. package/.medusa/server/src/modules/documents/index.js +15 -0
  96. package/.medusa/server/src/modules/documents/loaders/assert-private-file-storage.js +20 -0
  97. package/.medusa/server/src/modules/documents/migrations/Migration20260827061749.js +75 -0
  98. package/.medusa/server/src/modules/documents/migrations/Migration20260830111207.js +28 -0
  99. package/.medusa/server/src/modules/documents/models/document-artifact.js +25 -0
  100. package/.medusa/server/src/modules/documents/models/document-number-sequence.js +29 -0
  101. package/.medusa/server/src/modules/documents/models/document.js +82 -0
  102. package/.medusa/server/src/modules/documents/models/order-cancellation-resolution.js +51 -0
  103. package/.medusa/server/src/modules/documents/models/packing-list-revision.js +36 -0
  104. package/.medusa/server/src/modules/documents/models/packing-list.js +27 -0
  105. package/.medusa/server/src/modules/documents/models/refund-document-resolution.js +66 -0
  106. package/.medusa/server/src/modules/documents/models/shipment-invoice-assignment.js +51 -0
  107. package/.medusa/server/src/modules/documents/models/shipment-invoice-coordinator.js +44 -0
  108. package/.medusa/server/src/modules/documents/service.js +1701 -0
  109. package/.medusa/server/src/modules/email/domain/attachment.js +25 -0
  110. package/.medusa/server/src/modules/email/domain/message-state.js +69 -0
  111. package/.medusa/server/src/modules/email/index.js +13 -0
  112. package/.medusa/server/src/modules/email/migrations/Migration20260826173422.js +32 -0
  113. package/.medusa/server/src/modules/email/migrations/Migration20260827172945.js +16 -0
  114. package/.medusa/server/src/modules/email/migrations/Migration20260827194804.js +22 -0
  115. package/.medusa/server/src/modules/email/migrations/Migration20260906195205.js +16 -0
  116. package/.medusa/server/src/modules/email/models/email-attempt.js +56 -0
  117. package/.medusa/server/src/modules/email/models/email-message.js +71 -0
  118. package/.medusa/server/src/modules/email/models/email-terms-version.js +37 -0
  119. package/.medusa/server/src/modules/email/service.js +1285 -0
  120. package/.medusa/server/src/modules/plugin-features/domain/plugin-settings.js +4 -3
  121. package/.medusa/server/src/providers/s3-cache/cache/atomic-write.js +25 -0
  122. package/.medusa/server/src/providers/s3-cache/cache/cache-manager.js +115 -0
  123. package/.medusa/server/src/providers/s3-cache/cache/keyed-lock.js +28 -0
  124. package/.medusa/server/src/providers/s3-cache/index.js +8 -0
  125. package/.medusa/server/src/providers/s3-cache/object-key.js +53 -0
  126. package/.medusa/server/src/providers/s3-cache/s3-cache-file.js +229 -0
  127. package/.medusa/server/src/providers/s3-cache/s3-object-store.js +86 -0
  128. package/.medusa/server/src/providers/smtp/index.js +8 -0
  129. package/.medusa/server/src/providers/smtp/service.js +236 -0
  130. package/.medusa/server/src/providers/smtp/types.js +11 -0
  131. package/.medusa/server/src/public/config.js +186 -0
  132. package/.medusa/server/src/public/descriptor.js +3 -1
  133. package/.medusa/server/src/public/gateway.js +19 -0
  134. package/.medusa/server/src/public/instrumentation.js +56 -0
  135. package/.medusa/server/src/public/shop-config.js +12 -0
  136. package/.medusa/server/src/public/shop-master-data.js +2 -2
  137. package/.medusa/server/src/public/shop-types.js +24 -0
  138. package/.medusa/server/src/shop-config/build-food-shop-config.js +252 -0
  139. package/.medusa/server/src/shop-config/options.js +75 -0
  140. package/.medusa/server/src/subscribers/affiliate-consignment-reminder-due.js +26 -0
  141. package/.medusa/server/src/subscribers/documents-order-canceled.js +24 -0
  142. package/.medusa/server/src/subscribers/documents-order-cancellation-ready.js +26 -0
  143. package/.medusa/server/src/subscribers/documents-refund-ready.js +24 -0
  144. package/.medusa/server/src/subscribers/documents-shipment-created.js +36 -0
  145. package/.medusa/server/src/subscribers/documents-shipment-invoice-assignment-decided.js +26 -0
  146. package/.medusa/server/src/subscribers/email-order-canceled.js +28 -0
  147. package/.medusa/server/src/subscribers/email-shipment-created.js +32 -0
  148. package/.medusa/server/src/subscribers/order-placed.js +27 -0
  149. package/.medusa/server/src/subscribers/packing-list-allocation-revised.js +32 -0
  150. package/.medusa/server/src/subscribers/packing-list-fulfillment-canceled.js +54 -0
  151. package/.medusa/server/src/subscribers/packing-list-fulfillment-created.js +31 -0
  152. package/.medusa/server/src/subscribers/password-reset.js +23 -0
  153. package/.medusa/server/src/subscribers/payment-refunded.js +38 -0
  154. package/.medusa/server/src/subscribers/return-received.js +27 -0
  155. package/.medusa/server/src/subscribers/return-requested.js +27 -0
  156. package/.medusa/server/src/subscribers/user-invite.js +23 -0
  157. package/.medusa/server/src/utils/cart-promotion-links.js +101 -0
  158. package/.medusa/server/src/workflows/documents/issue-cancellation-after-refund.js +246 -0
  159. package/.medusa/server/src/workflows/documents/issue-document.js +165 -0
  160. package/.medusa/server/src/workflows/documents/issue-invoice-after-shipment.js +521 -0
  161. package/.medusa/server/src/workflows/documents/issue-packing-list.js +390 -0
  162. package/.medusa/server/src/workflows/documents/publish-document-facts.js +53 -0
  163. package/.medusa/server/src/workflows/documents/reconcile-document-resolutions.js +48 -0
  164. package/.medusa/server/src/workflows/documents/reconcile-order-cancellation.js +92 -0
  165. package/.medusa/server/src/workflows/documents/regenerate-issued-document.js +61 -0
  166. package/.medusa/server/src/workflows/email/dispatch-email-message.js +301 -0
  167. package/.medusa/server/src/workflows/email/documents-required-facts.js +30 -0
  168. package/.medusa/server/src/workflows/email/prepare-affiliate-reminder-email.js +58 -0
  169. package/.medusa/server/src/workflows/email/prepare-order-canceled-email.js +102 -0
  170. package/.medusa/server/src/workflows/email/prepare-order-received-email.js +82 -0
  171. package/.medusa/server/src/workflows/email/prepare-refund-email.js +71 -0
  172. package/.medusa/server/src/workflows/email/prepare-return-email.js +136 -0
  173. package/.medusa/server/src/workflows/email/prepare-shipment-email.js +115 -0
  174. package/.medusa/server/src/workflows/email/retry-email-messages.js +31 -0
  175. package/.medusa/server/src/workflows/hooks/dismiss-deleted-promotion-cart-links.js +23 -0
  176. package/README.md +1777 -8
  177. package/dist/admin-components/features/plugin-features/components/ImageSettingInput.d.ts +15 -0
  178. package/dist/admin-components/features/plugin-features/components/ImageSettingInput.js +42 -0
  179. package/dist/admin-components/features/plugin-features/components/PluginSettingsForm.js +4 -2
  180. package/dist/admin-components/features/plugin-features/hooks/usePluginFeatureEnabled.d.ts +1 -1
  181. package/dist/admin-components/features/plugin-features/hooks/usePluginFeatures.d.ts +4 -4
  182. package/dist/admin-components/features/plugin-features/hooks/usePluginSettingsForm.d.ts +1 -1
  183. package/dist/admin-components/features/plugin-features/lib/image-upload.d.ts +6 -0
  184. package/dist/admin-components/features/plugin-features/lib/image-upload.js +17 -0
  185. package/dist/admin-components/features/plugin-features/lib/plugin-features-admin-client.d.ts +4 -4
  186. package/dist/admin-components/i18n/texts.d.ts +6 -0
  187. package/dist/admin-components/i18n/texts.js +6 -0
  188. package/dist/documents/config/index.d.ts +11 -0
  189. package/dist/documents/config/index.js +17 -0
  190. package/dist/documents/templates/financial-document.d.ts +3 -0
  191. package/dist/documents/templates/financial-document.js +159 -0
  192. package/dist/documents/templates/format.d.ts +30 -0
  193. package/dist/documents/templates/format.js +72 -0
  194. package/dist/documents/templates/html-factory.d.ts +15 -0
  195. package/dist/documents/templates/html-factory.js +41 -0
  196. package/dist/documents/templates/html-utils.d.ts +8 -0
  197. package/dist/documents/templates/html-utils.js +22 -0
  198. package/dist/documents/templates/layout.d.ts +35 -0
  199. package/dist/documents/templates/layout.js +141 -0
  200. package/dist/documents/templates/packing-list.d.ts +3 -0
  201. package/dist/documents/templates/packing-list.js +51 -0
  202. package/dist/documents/types/admin-api.d.ts +1 -0
  203. package/dist/documents/types/admin-api.js +2 -0
  204. package/dist/documents/types/document-summary.d.ts +1 -0
  205. package/dist/documents/types/document-summary.js +2 -0
  206. package/dist/documents/types/documents.d.ts +191 -0
  207. package/dist/documents/types/documents.js +2 -0
  208. package/dist/documents/types/html-factory.d.ts +8 -0
  209. package/dist/documents/types/html-factory.js +5 -0
  210. package/dist/documents/types/index.d.ts +5 -0
  211. package/dist/documents/types/index.js +21 -0
  212. package/dist/documents/types/store-api.d.ts +1 -0
  213. package/dist/documents/types/store-api.js +2 -0
  214. package/dist/email/config/index.d.ts +17 -0
  215. package/dist/email/config/index.js +83 -0
  216. package/dist/email/config/notification-module.d.ts +22 -0
  217. package/dist/email/config/notification-module.js +19 -0
  218. package/dist/email/types/email-kinds.d.ts +15 -0
  219. package/dist/email/types/email-kinds.js +17 -0
  220. package/dist/email/types/index.d.ts +4 -0
  221. package/dist/email/types/index.js +20 -0
  222. package/dist/email/types/shop-configuration.d.ts +68 -0
  223. package/dist/email/types/shop-configuration.js +2 -0
  224. package/dist/email/types/smtp-configuration.d.ts +9 -0
  225. package/dist/email/types/smtp-configuration.js +2 -0
  226. package/dist/email/types/template-data.d.ts +609 -0
  227. package/dist/email/types/template-data.js +231 -0
  228. package/dist/files/config/index.d.ts +32 -0
  229. package/dist/files/config/index.js +255 -0
  230. package/dist/files/gateway/index.d.ts +30 -0
  231. package/dist/files/gateway/index.js +114 -0
  232. package/dist/files/types/index.d.ts +2 -0
  233. package/dist/files/types/index.js +5 -0
  234. package/dist/files/types/public.d.ts +90 -0
  235. package/dist/files/types/public.js +5 -0
  236. package/dist/modules/documents/domain/merchant.d.ts +22 -0
  237. package/dist/modules/documents/domain/merchant.js +85 -0
  238. package/dist/modules/documents/domain/options.d.ts +34 -0
  239. package/dist/modules/documents/domain/options.js +39 -0
  240. package/dist/public/config.d.ts +59 -0
  241. package/dist/public/config.js +185 -0
  242. package/dist/public/descriptor.js +2 -0
  243. package/dist/public/gateway.d.ts +2 -0
  244. package/dist/public/gateway.js +18 -0
  245. package/dist/public/instrumentation.d.ts +12 -0
  246. package/dist/public/instrumentation.js +55 -0
  247. package/dist/public/shop-config.d.ts +8 -0
  248. package/dist/public/shop-config.js +11 -0
  249. package/dist/public/shop-master-data.d.ts +1 -1
  250. package/dist/public/shop-master-data.js +1 -1
  251. package/dist/public/shop-types.d.ts +7 -0
  252. package/dist/public/shop-types.js +23 -0
  253. package/dist/public/types.d.ts +19 -2
  254. package/dist/shop-config/build-food-shop-config.d.ts +44 -0
  255. package/dist/shop-config/build-food-shop-config.js +251 -0
  256. package/dist/shop-config/options.d.ts +48 -0
  257. package/dist/shop-config/options.js +74 -0
  258. package/package.json +48 -5
@@ -0,0 +1,1285 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
12
+ return function (target, key) { decorator(target, key, paramIndex); }
13
+ };
14
+ var __importDefault = (this && this.__importDefault) || function (mod) {
15
+ return (mod && mod.__esModule) ? mod : { "default": mod };
16
+ };
17
+ Object.defineProperty(exports, "__esModule", { value: true });
18
+ exports.EMAIL_ATTEMPT_LEASE_MS = void 0;
19
+ const node_crypto_1 = require("node:crypto");
20
+ const utils_1 = require("@medusajs/framework/utils");
21
+ const zod_1 = require("@medusajs/framework/zod");
22
+ const documents_1 = require("@hartl-services/medusa-food-supplements-contracts/events/documents");
23
+ const email_1 = require("@hartl-services/medusa-food-supplements-contracts/schemas/email");
24
+ const types_1 = require("../../email/types");
25
+ const business_keys_1 = require("../../email/domain/business-keys");
26
+ const plugin_features_1 = require("../../email/plugin-features");
27
+ const resolve_shop_configuration_1 = require("../../email/rendering/resolve-shop-configuration");
28
+ const failure_classification_1 = require("../../email/domain/failure-classification");
29
+ const attachment_1 = require("./domain/attachment");
30
+ const message_state_1 = require("./domain/message-state");
31
+ const email_attempt_1 = __importDefault(require("./models/email-attempt"));
32
+ const email_message_1 = __importDefault(require("./models/email-message"));
33
+ const email_terms_version_1 = __importDefault(require("./models/email-terms-version"));
34
+ exports.EMAIL_ATTEMPT_LEASE_MS = 2 * 60 * 1000;
35
+ const EmailModuleServiceBase = (0, utils_1.MedusaService)({
36
+ EmailMessage: email_message_1.default,
37
+ EmailAttempt: email_attempt_1.default,
38
+ EmailTermsVersion: email_terms_version_1.default,
39
+ });
40
+ const asNonEmptyString = (value, field) => {
41
+ if (typeof value !== "string" || !value.trim()) {
42
+ throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, `${field} must be a non-empty string.`);
43
+ }
44
+ return value.trim();
45
+ };
46
+ const asNullableString = (value) => typeof value === "string" ? value : null;
47
+ const asDate = (value, field) => {
48
+ const date = value instanceof Date ? value : new Date(String(value ?? ""));
49
+ if (Number.isNaN(date.getTime())) {
50
+ throw new utils_1.MedusaError(utils_1.MedusaError.Types.UNEXPECTED_STATE, `${field} is not a valid date.`);
51
+ }
52
+ return date;
53
+ };
54
+ const asNullableDate = (value) => value === null || value === undefined ? null : asDate(value, "date");
55
+ const asSafeStatusCode = (value, field) => {
56
+ if (!(0, message_state_1.isEmailSafeStatusCode)(value)) {
57
+ throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, `${field} must be an allowlisted email status code.`);
58
+ }
59
+ return value;
60
+ };
61
+ const equalJson = (left, right) => JSON.stringify(left) === JSON.stringify(right);
62
+ const UuidSchema = zod_1.z.string().uuid();
63
+ const TermsPdfFilenameSchema = zod_1.z
64
+ .string()
65
+ .min(5)
66
+ .max(255)
67
+ .regex(/^(?!.*\.\.)[A-Za-z0-9](?:[A-Za-z0-9._ -]*[A-Za-z0-9_-])?\.pdf$/i);
68
+ const Sha256Schema = zod_1.z.string().regex(/^[0-9a-f]{64}$/);
69
+ const asUuid = (value, field) => {
70
+ const normalized = asNonEmptyString(value, field);
71
+ if (!UuidSchema.safeParse(normalized).success) {
72
+ throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, `${field} must be a UUID.`);
73
+ }
74
+ return normalized.toLowerCase();
75
+ };
76
+ class EmailModuleService extends EmailModuleServiceBase {
77
+ /**
78
+ * Medusa passes the plugin options of the base plugin to every module; this
79
+ * service reads only its own `email` namespace.
80
+ */
81
+ constructor(container, options) {
82
+ super(container);
83
+ /** Discovered by @hartl-services/medusa-base for the feature toggles. */
84
+ this.pluginFeatures = plugin_features_1.emailPluginFeatures;
85
+ const email = options?.email;
86
+ this.dispatchConfiguration_ = email?.shop
87
+ ? (0, resolve_shop_configuration_1.resolveShopEmailConfiguration)(email.shop)
88
+ : null;
89
+ this.jwtSecret_ = email?.jwtSecret?.trim() || null;
90
+ }
91
+ getDispatchConfiguration() {
92
+ if (!this.dispatchConfiguration_) {
93
+ throw new utils_1.MedusaError(utils_1.MedusaError.Types.UNEXPECTED_STATE, "Email dispatch configuration is unavailable.");
94
+ }
95
+ return this.dispatchConfiguration_;
96
+ }
97
+ getJwtSecret() {
98
+ if (!this.jwtSecret_) {
99
+ throw new utils_1.MedusaError(utils_1.MedusaError.Types.UNEXPECTED_STATE, "Email JWT configuration is unavailable.");
100
+ }
101
+ return this.jwtSecret_;
102
+ }
103
+ async findMessageByBusinessKey(businessKey, sharedContext = {}) {
104
+ const rows = await this.requireManager(sharedContext).execute(`select * from "email_message"
105
+ where "business_key" = ? and "deleted_at" is null
106
+ limit 1`, [asNonEmptyString(businessKey, "business_key")], "all");
107
+ return rows[0] ? this.toMessageRecord(rows[0]) : null;
108
+ }
109
+ async upsertMessageFact(input, sharedContext = {}) {
110
+ const normalized = this.normalizeFactInput(input);
111
+ const manager = this.requireManager(sharedContext);
112
+ await manager.execute("select pg_advisory_xact_lock(hashtext(?))", [
113
+ `email:message:${normalized.business_key}`,
114
+ ]);
115
+ const rows = await manager.execute(`select * from "email_message" where "business_key" = ? for update`, [normalized.business_key], "all");
116
+ const existing = rows[0] ? this.toMessageRecord(rows[0]) : null;
117
+ if (!existing) {
118
+ const attachments = [...normalized.attachments];
119
+ if (normalized.terms_effective_at) {
120
+ const termsAttachment = await this.findTermsAttachmentAt(normalized.terms_effective_at, sharedContext);
121
+ if (termsAttachment) {
122
+ attachments.push(termsAttachment);
123
+ }
124
+ }
125
+ const initialState = normalized.suppression_code
126
+ ? {
127
+ status: "suppressed",
128
+ terminal_code: normalized.suppression_code,
129
+ }
130
+ : await this.resolvePendingState(normalized.required_facts, [normalized.fact], normalized.predecessor_message_id, sharedContext);
131
+ const created = (await this.createEmailMessages({
132
+ kind: normalized.kind,
133
+ business_key: normalized.business_key,
134
+ resource_type: normalized.resource_type,
135
+ resource_id: normalized.resource_id,
136
+ recipient: normalized.recipient,
137
+ template_data: normalized.template_data,
138
+ attachments,
139
+ status: initialState.status,
140
+ required_facts: normalized.required_facts,
141
+ received_facts: [normalized.fact],
142
+ predecessor_message_id: normalized.predecessor_message_id,
143
+ trigger: normalized.trigger,
144
+ request_id: normalized.request_id,
145
+ requested_by_admin_id: normalized.requested_by_admin_id,
146
+ original_message_id: normalized.original_message_id,
147
+ next_attempt_at: null,
148
+ sent_at: null,
149
+ failed_at: initialState.status === "failed" ? new Date() : null,
150
+ payload_expires_at: normalized.payload_expires_at,
151
+ terminal_code: initialState.terminal_code,
152
+ }, sharedContext));
153
+ return this.toMessageRecord(created);
154
+ }
155
+ if (existing.deleted_at) {
156
+ throw new utils_1.MedusaError(utils_1.MedusaError.Types.CONFLICT, "The email business key was already consumed.");
157
+ }
158
+ this.assertSameMessageIdentity(existing, normalized);
159
+ const receivedFacts = (0, message_state_1.canonicalizeFacts)([
160
+ ...existing.received_facts,
161
+ normalized.fact,
162
+ ]);
163
+ const templateData = this.mergeTemplateData(existing.kind, existing.template_data, normalized.template_data);
164
+ const attachments = this.mergeAttachments(existing.attachments, normalized.attachments);
165
+ const state = existing.status !== "pending" && existing.status !== "ready"
166
+ ? { status: existing.status, terminal_code: existing.terminal_code }
167
+ : normalized.suppression_code
168
+ ? {
169
+ status: "suppressed",
170
+ terminal_code: normalized.suppression_code,
171
+ }
172
+ : await this.resolvePendingState(existing.required_facts, receivedFacts, existing.predecessor_message_id, sharedContext);
173
+ const updated = (await this.updateEmailMessages({
174
+ id: existing.id,
175
+ recipient: existing.recipient ?? normalized.recipient,
176
+ template_data: templateData,
177
+ attachments,
178
+ received_facts: receivedFacts,
179
+ status: state.status,
180
+ terminal_code: state.terminal_code,
181
+ failed_at: state.status === "failed"
182
+ ? (existing.failed_at ?? new Date())
183
+ : existing.failed_at,
184
+ }, sharedContext));
185
+ const message = this.toMessageRecord(updated);
186
+ if (message.status === "failed" || message.status === "suppressed") {
187
+ await this.reevaluateDependentMessages(message, new Date(), sharedContext);
188
+ }
189
+ return message;
190
+ }
191
+ async createEmailTermsVersion(input, persistPrivatePdf, deletePrivatePdf, sharedContext = {}) {
192
+ const normalized = this.normalizeTermsVersionInput(input);
193
+ const manager = this.requireManager(sharedContext);
194
+ await manager.execute("select pg_advisory_xact_lock(hashtext(?))", [
195
+ `email:terms-version:${normalized.request_id}`,
196
+ ]);
197
+ const rows = await manager.execute(`select * from "email_terms_version" where "request_id" = ? for update`, [normalized.request_id], "all");
198
+ if (rows[0]) {
199
+ const existing = this.toTermsVersionRecord(rows[0]);
200
+ if (existing.deleted_at) {
201
+ throw new utils_1.MedusaError(utils_1.MedusaError.Types.CONFLICT, "The terms upload request was already consumed.");
202
+ }
203
+ if (existing.filename !== normalized.filename ||
204
+ existing.effective_at.getTime() !== normalized.effective_at.getTime() ||
205
+ existing.byte_size !== normalized.byte_size ||
206
+ existing.sha256 !== normalized.sha256) {
207
+ throw new utils_1.MedusaError(utils_1.MedusaError.Types.CONFLICT, "The terms upload request was reused with different PDF data.");
208
+ }
209
+ return {
210
+ created: false,
211
+ terms_version: this.toSafeAdminTermsVersion(existing),
212
+ };
213
+ }
214
+ let fileId = null;
215
+ try {
216
+ fileId = asNonEmptyString(await persistPrivatePdf(), "file_id");
217
+ await this.createEmailTermsVersions({ ...normalized, file_id: fileId }, sharedContext);
218
+ await manager.flush?.();
219
+ const createdRows = await manager.execute(`select * from "email_terms_version" where "request_id" = ? limit 1`, [normalized.request_id], "all");
220
+ if (!createdRows[0]) {
221
+ throw new utils_1.MedusaError(utils_1.MedusaError.Types.UNEXPECTED_STATE, "The terms version was not persisted.");
222
+ }
223
+ return {
224
+ created: true,
225
+ terms_version: this.toSafeAdminTermsVersion(this.toTermsVersionRecord(createdRows[0])),
226
+ };
227
+ }
228
+ catch (error) {
229
+ if (fileId) {
230
+ try {
231
+ await deletePrivatePdf(fileId);
232
+ }
233
+ catch {
234
+ // Preserve the original persistence failure; cleanup is best effort.
235
+ }
236
+ }
237
+ throw error;
238
+ }
239
+ }
240
+ async listAdminEmailTermsVersions(input, sharedContext = {}) {
241
+ const limit = this.positiveLimit(input.limit);
242
+ const offset = this.safeOffset(input.offset);
243
+ const manager = this.requireManager(sharedContext);
244
+ const [rows, countRows] = await Promise.all([
245
+ manager.execute(`select * from "email_terms_version"
246
+ where "deleted_at" is null
247
+ order by "effective_at" desc, "created_at" desc, "id" desc
248
+ limit ? offset ?`, [limit, offset], "all"),
249
+ manager.execute(`select count(*) as "count" from "email_terms_version"
250
+ where "deleted_at" is null`, [], "all"),
251
+ ]);
252
+ return {
253
+ terms_versions: rows.map((row) => this.toSafeAdminTermsVersion(this.toTermsVersionRecord(row))),
254
+ count: Number(countRows[0]?.count ?? 0),
255
+ limit,
256
+ offset,
257
+ };
258
+ }
259
+ async getEmailTermsVersionFile(termsVersionId, sharedContext = {}) {
260
+ const rows = await this.requireManager(sharedContext).execute(`select "file_id", "filename" from "email_terms_version"
261
+ where "id" = ? and "deleted_at" is null limit 1`, [asNonEmptyString(termsVersionId, "terms_version_id")], "all");
262
+ if (!rows[0]) {
263
+ throw new utils_1.MedusaError(utils_1.MedusaError.Types.NOT_FOUND, "The terms version was not found.");
264
+ }
265
+ return {
266
+ file_id: asNonEmptyString(rows[0].file_id, "file_id"),
267
+ filename: asNonEmptyString(rows[0].filename, "filename"),
268
+ };
269
+ }
270
+ async createAffiliateReminderMessage(input, resolveRecipient, sharedContext = {}) {
271
+ const factInput = {
272
+ kind: "affiliate.consignment_report_due",
273
+ business_key: input.business_key,
274
+ resource_type: "affiliate",
275
+ resource_id: input.resource_id,
276
+ template_data: input.template_data,
277
+ required_facts: ["reminder_due"],
278
+ fact: "reminder_due",
279
+ trigger: input.trigger,
280
+ };
281
+ const normalized = this.normalizeFactInput(factInput);
282
+ const manager = this.requireManager(sharedContext);
283
+ await manager.execute("select pg_advisory_xact_lock(hashtext(?))", [
284
+ `email:message:${normalized.business_key}`,
285
+ ]);
286
+ const rows = await manager.execute(`select * from "email_message" where "business_key" = ? for update`, [normalized.business_key], "all");
287
+ if (rows[0]) {
288
+ const existing = this.toMessageRecord(rows[0]);
289
+ if (existing.deleted_at) {
290
+ throw new utils_1.MedusaError(utils_1.MedusaError.Types.CONFLICT, "The email business key was already consumed.");
291
+ }
292
+ if (existing.kind !== normalized.kind ||
293
+ existing.resource_type !== normalized.resource_type ||
294
+ existing.resource_id !== normalized.resource_id) {
295
+ throw new utils_1.MedusaError(utils_1.MedusaError.Types.CONFLICT, "The email business key was reused for another resource.");
296
+ }
297
+ return existing;
298
+ }
299
+ const snapshot = this.normalizeFactInput({
300
+ ...factInput,
301
+ recipient: await resolveRecipient(),
302
+ });
303
+ return this.toMessageRecord((await this.createEmailMessages({
304
+ kind: snapshot.kind,
305
+ business_key: snapshot.business_key,
306
+ resource_type: snapshot.resource_type,
307
+ resource_id: snapshot.resource_id,
308
+ recipient: snapshot.recipient,
309
+ template_data: snapshot.template_data,
310
+ attachments: [],
311
+ status: "ready",
312
+ required_facts: snapshot.required_facts,
313
+ received_facts: [snapshot.fact],
314
+ predecessor_message_id: null,
315
+ trigger: snapshot.trigger,
316
+ request_id: null,
317
+ requested_by_admin_id: null,
318
+ original_message_id: null,
319
+ next_attempt_at: null,
320
+ sent_at: null,
321
+ failed_at: null,
322
+ payload_expires_at: null,
323
+ terminal_code: null,
324
+ }, sharedContext)));
325
+ }
326
+ async createAdminResend(input, sharedContext = {}) {
327
+ const sourceMessageId = asNonEmptyString(input.source_message_id, "source_message_id");
328
+ const requestId = asUuid(input.request_id, "request_id");
329
+ const requestedByAdminId = asNonEmptyString(input.requested_by_admin_id, "requested_by_admin_id");
330
+ const businessKey = (0, business_keys_1.adminResendBusinessKey)(sourceMessageId, requestId);
331
+ const manager = this.requireManager(sharedContext);
332
+ await manager.execute("select pg_advisory_xact_lock(hashtext(?))", [
333
+ `email:message:${businessKey}`,
334
+ ]);
335
+ const replayRows = await manager.execute(`select * from "email_message" where "business_key" = ? for update`, [businessKey], "all");
336
+ if (replayRows[0]) {
337
+ const replay = this.toMessageRecord(replayRows[0]);
338
+ if (replay.deleted_at) {
339
+ throw new utils_1.MedusaError(utils_1.MedusaError.Types.CONFLICT, "The email resend request was already consumed.");
340
+ }
341
+ if (replay.original_message_id !== sourceMessageId ||
342
+ replay.request_id !== requestId ||
343
+ replay.trigger !== "admin_resend") {
344
+ throw new utils_1.MedusaError(utils_1.MedusaError.Types.CONFLICT, "The email resend key was reused with conflicting identity.");
345
+ }
346
+ return replay;
347
+ }
348
+ const sourceRows = await manager.execute(`select * from "email_message"
349
+ where "id" = ? and "deleted_at" is null for update`, [sourceMessageId], "all");
350
+ if (!sourceRows[0]) {
351
+ throw new utils_1.MedusaError(utils_1.MedusaError.Types.NOT_FOUND, "The source email message was not found.");
352
+ }
353
+ const source = this.toMessageRecord(sourceRows[0]);
354
+ if (source.kind === "auth.password_reset") {
355
+ throw new utils_1.MedusaError(utils_1.MedusaError.Types.NOT_ALLOWED, "Password reset messages cannot be resent.");
356
+ }
357
+ if (source.status !== "sent" &&
358
+ source.status !== "unknown" &&
359
+ source.status !== "failed") {
360
+ throw new utils_1.MedusaError(utils_1.MedusaError.Types.CONFLICT, "The source email message is not eligible for resend.");
361
+ }
362
+ return this.toMessageRecord((await this.createEmailMessages({
363
+ kind: source.kind,
364
+ business_key: businessKey,
365
+ resource_type: source.resource_type,
366
+ resource_id: source.resource_id,
367
+ recipient: source.recipient,
368
+ template_data: source.template_data,
369
+ attachments: source.attachments,
370
+ status: "ready",
371
+ required_facts: ["admin_resend"],
372
+ received_facts: ["admin_resend"],
373
+ predecessor_message_id: null,
374
+ trigger: "admin_resend",
375
+ request_id: requestId,
376
+ requested_by_admin_id: requestedByAdminId,
377
+ original_message_id: source.id,
378
+ next_attempt_at: null,
379
+ sent_at: null,
380
+ failed_at: null,
381
+ payload_expires_at: null,
382
+ terminal_code: null,
383
+ }, sharedContext)));
384
+ }
385
+ async listAdminEmailMessages(input, sharedContext = {}) {
386
+ const limit = this.positiveLimit(input.limit);
387
+ const offset = this.safeOffset(input.offset);
388
+ const conditions = ['m."deleted_at" is null'];
389
+ const params = [];
390
+ if (input.kind !== undefined) {
391
+ conditions.push('m."kind" = ?');
392
+ params.push(types_1.EmailKindSchema.parse(input.kind));
393
+ }
394
+ if (input.status !== undefined) {
395
+ if (!message_state_1.EMAIL_MESSAGE_STATUSES.includes(input.status)) {
396
+ throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, "status must be an email message status.");
397
+ }
398
+ conditions.push('m."status" = ?');
399
+ params.push(input.status);
400
+ }
401
+ if (input.trigger !== undefined) {
402
+ const trigger = asNonEmptyString(input.trigger, "trigger");
403
+ if (trigger.length > 100) {
404
+ throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, "trigger must not exceed 100 characters.");
405
+ }
406
+ conditions.push('m."trigger" = ?');
407
+ params.push(trigger);
408
+ }
409
+ for (const [column, value] of [
410
+ ["resource_type", input.resource_type],
411
+ ["resource_id", input.resource_id],
412
+ ]) {
413
+ if (value !== undefined) {
414
+ const normalized = asNonEmptyString(value, column);
415
+ if (normalized.length > 255) {
416
+ throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, `${column} must not exceed 255 characters.`);
417
+ }
418
+ conditions.push(`m."${column}" = ?`);
419
+ params.push(normalized);
420
+ }
421
+ }
422
+ const where = conditions.join(" and ");
423
+ const manager = this.requireManager(sharedContext);
424
+ const [rows, countRows] = await Promise.all([
425
+ manager.execute(`select m.*,
426
+ (select count(*)::integer from "email_attempt" a
427
+ where a."message_id" = m."id" and a."deleted_at" is null)
428
+ as "attempt_count"
429
+ from "email_message" m
430
+ where ${where}
431
+ order by m."created_at" desc, m."id" desc
432
+ limit ? offset ?`, [...params, limit, offset], "all"),
433
+ manager.execute(`select count(*) as "count" from "email_message" m where ${where}`, params, "all"),
434
+ ]);
435
+ return {
436
+ messages: rows.map((row) => this.toSafeAdminMessage(row)),
437
+ count: Number(countRows[0]?.count ?? 0),
438
+ limit,
439
+ offset,
440
+ };
441
+ }
442
+ async getAdminEmailMessage(messageId, sharedContext = {}) {
443
+ const manager = this.requireManager(sharedContext);
444
+ const rows = await manager.execute(`select m.*,
445
+ (select count(*)::integer from "email_attempt" a
446
+ where a."message_id" = m."id" and a."deleted_at" is null)
447
+ as "attempt_count"
448
+ from "email_message" m
449
+ where m."id" = ? and m."deleted_at" is null
450
+ limit 1`, [asNonEmptyString(messageId, "message_id")], "all");
451
+ if (!rows[0]) {
452
+ throw new utils_1.MedusaError(utils_1.MedusaError.Types.NOT_FOUND, "The email message was not found.");
453
+ }
454
+ const attempts = await manager.execute(`select "id", "attempt_number", "status", "failure_code",
455
+ "started_at", "finished_at", "created_at", "updated_at"
456
+ from "email_attempt"
457
+ where "message_id" = ? and "deleted_at" is null
458
+ order by "attempt_number" asc, "id" asc`, [messageId], "all");
459
+ return {
460
+ message: this.toSafeAdminMessage(rows[0]),
461
+ attempts: attempts.map((attempt) => this.toSafeAdminAttempt(attempt)),
462
+ };
463
+ }
464
+ async suppressMessage(input, sharedContext = {}) {
465
+ const message = await this.lockMessage(input.message_id, sharedContext);
466
+ if (message.status === "suppressed") {
467
+ await this.reevaluateDependentMessages(message, new Date(), sharedContext);
468
+ return message;
469
+ }
470
+ if (message.status !== "pending" && message.status !== "ready") {
471
+ throw new utils_1.MedusaError(utils_1.MedusaError.Types.CONFLICT, "Only pending or ready email messages can be suppressed.");
472
+ }
473
+ const manager = this.requireManager(sharedContext);
474
+ const attempts = await manager.execute(`select count(*)::text as "count" from "email_attempt"
475
+ where "message_id" = ? and "deleted_at" is null`, [message.id], "all");
476
+ if (Number(attempts[0]?.count ?? 0) !== 0) {
477
+ throw new utils_1.MedusaError(utils_1.MedusaError.Types.CONFLICT, "An email message with transport attempts cannot be suppressed.");
478
+ }
479
+ const updated = (await this.updateEmailMessages({
480
+ id: message.id,
481
+ status: "suppressed",
482
+ terminal_code: asSafeStatusCode(input.terminal_code, "terminal_code"),
483
+ }, sharedContext));
484
+ const suppressed = this.toMessageRecord(updated);
485
+ await this.reevaluateDependentMessages(suppressed, new Date(), sharedContext);
486
+ return suppressed;
487
+ }
488
+ async claimReadyMessage(input, sharedContext = {}) {
489
+ return await this.claimReadyMessageInTransaction(input, sharedContext);
490
+ }
491
+ async claimReadyMessageForAutomaticDispatch(input, sharedContext = {}) {
492
+ return await this.claimReadyMessageInTransaction({ ...input, allow_password_reset: false }, sharedContext);
493
+ }
494
+ async claimDueRetries(input, sharedContext = {}) {
495
+ const now = asDate(input.now, "now");
496
+ const limit = this.positiveLimit(input.limit);
497
+ const manager = this.requireManager(sharedContext);
498
+ const rows = await manager.execute(`select "id" from "email_message"
499
+ where "status" = 'retry_pending'
500
+ and "next_attempt_at" <= ?
501
+ and "kind" <> 'auth.password_reset'
502
+ and "deleted_at" is null
503
+ order by "next_attempt_at" asc, "id" asc
504
+ limit ?
505
+ for update skip locked`, [now, limit], "all");
506
+ const claims = [];
507
+ for (const row of rows) {
508
+ const claim = await this.claimReadyMessageInTransaction({ message_id: row.id, now }, sharedContext);
509
+ if (claim) {
510
+ claims.push(claim);
511
+ }
512
+ }
513
+ return claims;
514
+ }
515
+ async markAttemptSent(input) {
516
+ return await this.completeAttempt({
517
+ ...input,
518
+ attempt_status: "sent",
519
+ message_status: "sent",
520
+ failure_code: null,
521
+ next_attempt_at: null,
522
+ });
523
+ }
524
+ async markAttemptRetryable(input) {
525
+ return await this.completeAttempt({
526
+ ...input,
527
+ notification_id: input.notification_id ?? null,
528
+ attempt_status: "failed",
529
+ message_status: "retry_pending",
530
+ });
531
+ }
532
+ async markAttemptFailed(input) {
533
+ return await this.completeAttempt({
534
+ ...input,
535
+ notification_id: input.notification_id ?? null,
536
+ attempt_status: "failed",
537
+ message_status: "failed",
538
+ next_attempt_at: null,
539
+ });
540
+ }
541
+ async markAttemptUnknown(input) {
542
+ return await this.completeAttempt({
543
+ ...input,
544
+ notification_id: input.notification_id ?? null,
545
+ attempt_status: "unknown",
546
+ message_status: "unknown",
547
+ next_attempt_at: null,
548
+ });
549
+ }
550
+ async renewAttemptLease(input, sharedContext = {}) {
551
+ const now = asDate(input.now ?? new Date(), "now");
552
+ const leaseDuration = input.lease_duration_ms ?? exports.EMAIL_ATTEMPT_LEASE_MS;
553
+ if (!Number.isInteger(leaseDuration) || leaseDuration <= 0) {
554
+ throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, "lease_duration_ms must be a positive integer.");
555
+ }
556
+ const rows = await this.requireManager(sharedContext).execute(`update "email_attempt" a
557
+ set "lease_started_at" = ?, "lease_expires_at" = ?, "updated_at" = now()
558
+ where a."id" = ? and a."status" = 'processing'
559
+ and a."attempt_token" = ? and a."deleted_at" is null
560
+ and exists (
561
+ select 1 from "email_message" m
562
+ where m."id" = a."message_id" and m."status" = 'sending'
563
+ and m."deleted_at" is null
564
+ )
565
+ returning a.*`, [
566
+ now,
567
+ new Date(now.getTime() + leaseDuration),
568
+ asNonEmptyString(input.attempt_id, "attempt_id"),
569
+ asNonEmptyString(input.attempt_token, "attempt_token"),
570
+ ], "all");
571
+ if (!rows[0]) {
572
+ throw new utils_1.MedusaError(utils_1.MedusaError.Types.CONFLICT, "The email attempt lease is no longer owned by this token.");
573
+ }
574
+ return this.toAttemptRecord(rows[0]);
575
+ }
576
+ async completeStaleAttempt(input) {
577
+ if (input.outcome === "sent") {
578
+ return await this.completeAttempt({
579
+ attempt_id: input.attempt_id,
580
+ attempt_status: "sent",
581
+ attempt_token: input.attempt_token,
582
+ failure_code: null,
583
+ finished_at: input.now,
584
+ message_status: "sent",
585
+ next_attempt_at: null,
586
+ notification_id: input.notification_id,
587
+ require_lease_expired_at: input.now,
588
+ });
589
+ }
590
+ return await this.completeAttempt({
591
+ attempt_id: input.attempt_id,
592
+ attempt_status: "unknown",
593
+ attempt_token: input.attempt_token,
594
+ failure_code: "lease_expired",
595
+ finished_at: input.now,
596
+ message_status: "unknown",
597
+ next_attempt_at: null,
598
+ notification_id: input.notification_id ?? null,
599
+ require_lease_expired_at: input.now,
600
+ });
601
+ }
602
+ async listStaleAttemptCandidates(input, sharedContext = {}) {
603
+ const manager = this.requireManager(sharedContext);
604
+ const rows = await manager.execute(`select a."id" as "attempt_id", a."attempt_token", a."message_id", m."kind"
605
+ from "email_attempt" a
606
+ join "email_message" m on m."id" = a."message_id"
607
+ where a."status" = 'processing' and a."lease_expires_at" <= ?
608
+ and a."attempt_token" is not null and a."deleted_at" is null
609
+ and m."status" = 'sending' and m."deleted_at" is null
610
+ order by a."lease_expires_at" asc, a."id" asc
611
+ limit ?`, [asDate(input.now, "now"), this.positiveLimit(input.limit)], "all");
612
+ return rows.map((row) => ({
613
+ attempt_id: asNonEmptyString(row.attempt_id, "attempt_id"),
614
+ attempt_token: asNonEmptyString(row.attempt_token, "attempt_token"),
615
+ kind: types_1.EmailKindSchema.parse(row.kind),
616
+ message_id: asNonEmptyString(row.message_id, "message_id"),
617
+ notification_idempotency_key: (0, failure_classification_1.emailAttemptNotificationKey)(row.attempt_id),
618
+ }));
619
+ }
620
+ async reconcilePendingMessageDependencies(input, sharedContext = {}) {
621
+ const now = asDate(input.now, "now");
622
+ const manager = this.requireManager(sharedContext);
623
+ const rows = await manager.execute(`select m.* from "email_message" m
624
+ left join "email_message" p on p."id" = m."predecessor_message_id"
625
+ and p."deleted_at" is null
626
+ where m."status" = 'pending' and m."deleted_at" is null
627
+ and (
628
+ (m."predecessor_message_id" is null
629
+ and m."received_facts" @> m."required_facts")
630
+ or p."status" in ('failed', 'unknown', 'suppressed')
631
+ or (p."status" = 'sent'
632
+ and m."received_facts" @> m."required_facts")
633
+ )
634
+ order by m."updated_at" asc, m."id" asc
635
+ limit ?
636
+ for update of m skip locked`, [this.positiveLimit(input.limit)], "all");
637
+ let transitioned = 0;
638
+ for (const row of rows) {
639
+ const message = this.toMessageRecord(row);
640
+ const state = await this.resolvePendingState(message.required_facts, message.received_facts, message.predecessor_message_id, sharedContext);
641
+ if (state.status === message.status &&
642
+ state.terminal_code === message.terminal_code) {
643
+ continue;
644
+ }
645
+ const updated = this.toMessageRecord((await this.updateEmailMessages({
646
+ id: message.id,
647
+ status: state.status,
648
+ terminal_code: state.terminal_code,
649
+ failed_at: state.status === "failed" ? now : message.failed_at,
650
+ }, sharedContext)));
651
+ transitioned += 1;
652
+ if (updated.status === "failed" || updated.status === "suppressed") {
653
+ await this.reevaluateDependentMessages(updated, now, sharedContext);
654
+ }
655
+ }
656
+ return transitioned;
657
+ }
658
+ async listReadyMessageIds(input, sharedContext = {}) {
659
+ const rows = await this.requireManager(sharedContext).execute(`select "id" from "email_message"
660
+ where "status" = 'ready' and "kind" <> 'auth.password_reset'
661
+ and "deleted_at" is null
662
+ order by "updated_at" asc, "id" asc
663
+ limit ?`, [this.positiveLimit(input.limit)], "all");
664
+ return rows.map((row) => asNonEmptyString(row.id, "id"));
665
+ }
666
+ async completeAttempt(input, sharedContext = {}) {
667
+ const manager = this.requireManager(sharedContext);
668
+ const finishedAt = asDate(input.finished_at ?? new Date(), "finished_at");
669
+ const nextAttemptAt = input.next_attempt_at === null
670
+ ? null
671
+ : asDate(input.next_attempt_at, "next_attempt_at");
672
+ if (nextAttemptAt && nextAttemptAt.getTime() <= finishedAt.getTime()) {
673
+ throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, "next_attempt_at must be later than finished_at.");
674
+ }
675
+ const failureCode = input.failure_code === null
676
+ ? null
677
+ : asSafeStatusCode(input.failure_code, "failure_code");
678
+ const notificationId = input.notification_id === null
679
+ ? null
680
+ : asNonEmptyString(input.notification_id, "notification_id");
681
+ if (input.attempt_status === "sent" && !notificationId) {
682
+ throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, "A sent email attempt requires notification_id.");
683
+ }
684
+ const requiredLeaseExpiry = input.require_lease_expired_at
685
+ ? asDate(input.require_lease_expired_at, "require_lease_expired_at")
686
+ : null;
687
+ const attempts = await manager.execute(`update "email_attempt"
688
+ set "status" = ?, "attempt_token" = null, "notification_id" = ?,
689
+ "failure_code" = ?, "finished_at" = ?, "updated_at" = now()
690
+ where "id" = ? and "status" = 'processing' and "attempt_token" = ?
691
+ and "deleted_at" is null
692
+ ${requiredLeaseExpiry ? 'and "lease_expires_at" <= ?' : ""}
693
+ returning *`, [
694
+ input.attempt_status,
695
+ notificationId,
696
+ failureCode,
697
+ finishedAt,
698
+ asNonEmptyString(input.attempt_id, "attempt_id"),
699
+ asNonEmptyString(input.attempt_token, "attempt_token"),
700
+ ...(requiredLeaseExpiry ? [requiredLeaseExpiry] : []),
701
+ ], "all");
702
+ if (!attempts[0]) {
703
+ throw new utils_1.MedusaError(utils_1.MedusaError.Types.CONFLICT, "The email attempt is no longer owned by this token.");
704
+ }
705
+ const attempt = this.toAttemptRecord(attempts[0]);
706
+ const messages = await manager.execute(`update "email_message"
707
+ set "status" = ?, "next_attempt_at" = ?,
708
+ "sent_at" = case when ? = 'sent' then ? else "sent_at" end,
709
+ "failed_at" = case when ? = 'failed' then ? else "failed_at" end,
710
+ "terminal_code" = case when ? in ('failed', 'unknown') then ? else null end,
711
+ "updated_at" = now()
712
+ where "id" = ? and "status" = 'sending' and "deleted_at" is null
713
+ returning *`, [
714
+ input.message_status,
715
+ nextAttemptAt,
716
+ input.message_status,
717
+ finishedAt,
718
+ input.message_status,
719
+ finishedAt,
720
+ input.message_status,
721
+ failureCode,
722
+ attempt.message_id,
723
+ ], "all");
724
+ if (!messages[0]) {
725
+ throw new utils_1.MedusaError(utils_1.MedusaError.Types.CONFLICT, "The email attempt no longer owns its message.");
726
+ }
727
+ const message = this.toMessageRecord(messages[0]);
728
+ if (message.status === "sent" ||
729
+ message.status === "failed" ||
730
+ message.status === "unknown") {
731
+ await this.reevaluateDependentMessages(message, finishedAt, sharedContext);
732
+ }
733
+ return {
734
+ attempt,
735
+ message,
736
+ };
737
+ }
738
+ async claimReadyMessageInTransaction(input, sharedContext) {
739
+ const now = asDate(input.now ?? new Date(), "now");
740
+ const leaseDuration = input.lease_duration_ms ?? exports.EMAIL_ATTEMPT_LEASE_MS;
741
+ if (!Number.isInteger(leaseDuration) || leaseDuration <= 0) {
742
+ throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, "lease_duration_ms must be a positive integer.");
743
+ }
744
+ const message = await this.lockMessage(input.message_id, sharedContext);
745
+ if (input.allow_password_reset === false &&
746
+ message.kind === "auth.password_reset") {
747
+ return null;
748
+ }
749
+ const eligible = message.status === "ready" ||
750
+ (message.status === "retry_pending" &&
751
+ message.next_attempt_at !== null &&
752
+ message.next_attempt_at.getTime() <= now.getTime());
753
+ if (!eligible) {
754
+ return null;
755
+ }
756
+ if (message.payload_expires_at &&
757
+ message.payload_expires_at.getTime() <= now.getTime()) {
758
+ const expired = this.toMessageRecord((await this.updateEmailMessages({
759
+ id: message.id,
760
+ status: "failed",
761
+ failed_at: now,
762
+ terminal_code: "payload_expired",
763
+ next_attempt_at: null,
764
+ }, sharedContext)));
765
+ await this.reevaluateDependentMessages(expired, now, sharedContext);
766
+ return null;
767
+ }
768
+ const state = await this.resolvePendingState(message.required_facts, message.received_facts, message.predecessor_message_id, sharedContext);
769
+ if (state.status !== "ready") {
770
+ const updated = this.toMessageRecord((await this.updateEmailMessages({
771
+ id: message.id,
772
+ status: state.status,
773
+ terminal_code: state.terminal_code,
774
+ failed_at: state.status === "failed" ? now : message.failed_at,
775
+ }, sharedContext)));
776
+ if (updated.status === "failed" || updated.status === "suppressed") {
777
+ await this.reevaluateDependentMessages(updated, now, sharedContext);
778
+ }
779
+ return null;
780
+ }
781
+ const manager = this.requireManager(sharedContext);
782
+ const numberRows = await manager.execute(`select coalesce(max("attempt_number"), 0)::integer + 1 as "next_number"
783
+ from "email_attempt" where "message_id" = ?`, [message.id], "all");
784
+ let previousRows = await manager.execute(`select "notification_id" from "email_attempt"
785
+ where "message_id" = ? and "notification_id" is not null
786
+ and "deleted_at" is null
787
+ order by "attempt_number" desc
788
+ limit 1`, [message.id], "all");
789
+ if (!previousRows[0] && message.original_message_id) {
790
+ previousRows = await manager.execute(`select "notification_id" from "email_attempt"
791
+ where "message_id" = ? and "notification_id" is not null
792
+ and "deleted_at" is null
793
+ order by "attempt_number" desc
794
+ limit 1`, [message.original_message_id], "all");
795
+ }
796
+ const attemptToken = (0, node_crypto_1.randomUUID)();
797
+ const leaseExpiresAt = new Date(now.getTime() + leaseDuration);
798
+ const created = (await this.createEmailAttempts({
799
+ message_id: message.id,
800
+ attempt_number: numberRows[0]?.next_number ?? 1,
801
+ status: "processing",
802
+ attempt_token: attemptToken,
803
+ lease_started_at: now,
804
+ lease_expires_at: leaseExpiresAt,
805
+ notification_id: null,
806
+ failure_code: null,
807
+ started_at: now,
808
+ finished_at: null,
809
+ }, sharedContext));
810
+ const updated = (await this.updateEmailMessages({
811
+ id: message.id,
812
+ status: "sending",
813
+ next_attempt_at: null,
814
+ terminal_code: null,
815
+ }, sharedContext));
816
+ return {
817
+ message: this.toMessageRecord(updated),
818
+ attempt: this.toAttemptRecord(created),
819
+ attempt_token: attemptToken,
820
+ previous_notification_id: asNullableString(previousRows[0]?.notification_id),
821
+ };
822
+ }
823
+ normalizeFactInput(input) {
824
+ const kind = types_1.EmailKindSchema.parse(input.kind);
825
+ const requiredFacts = (0, message_state_1.canonicalizeFacts)(input.required_facts);
826
+ const fact = asNonEmptyString(input.fact, "fact");
827
+ if (!requiredFacts.length || !requiredFacts.includes(fact)) {
828
+ throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, "required_facts must include the received fact.");
829
+ }
830
+ const templateData = input.template_data === undefined || input.template_data === null
831
+ ? null
832
+ : types_1.EmailPersistedDataSchemas[kind].parse(input.template_data);
833
+ const attachments = documents_1.DocumentsEmailArtifactSchema.array().parse(input.attachments ?? []);
834
+ const termsEffectiveAt = input.terms_effective_at
835
+ ? asDate(input.terms_effective_at, "terms_effective_at")
836
+ : null;
837
+ if (termsEffectiveAt && kind !== "order.received") {
838
+ throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, "terms_effective_at is only valid for customer order confirmations.");
839
+ }
840
+ const suppressionCode = input.suppression_code ?? null;
841
+ if (suppressionCode && !(0, message_state_1.isEmailSafeStatusCode)(suppressionCode)) {
842
+ throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, "suppression_code must be allowlisted.");
843
+ }
844
+ return {
845
+ kind,
846
+ business_key: asNonEmptyString(input.business_key, "business_key"),
847
+ resource_type: asNonEmptyString(input.resource_type, "resource_type"),
848
+ resource_id: input.resource_id
849
+ ? asNonEmptyString(input.resource_id, "resource_id")
850
+ : null,
851
+ recipient: input.recipient
852
+ ? asNonEmptyString(input.recipient, "recipient")
853
+ : null,
854
+ template_data: templateData,
855
+ attachments,
856
+ required_facts: requiredFacts,
857
+ fact,
858
+ predecessor_message_id: input.predecessor_message_id
859
+ ? asNonEmptyString(input.predecessor_message_id, "predecessor_message_id")
860
+ : null,
861
+ trigger: input.trigger
862
+ ? asNonEmptyString(input.trigger, "trigger")
863
+ : "automatic",
864
+ request_id: input.request_id ?? null,
865
+ requested_by_admin_id: input.requested_by_admin_id ?? null,
866
+ original_message_id: input.original_message_id ?? null,
867
+ payload_expires_at: input.payload_expires_at
868
+ ? asDate(input.payload_expires_at, "payload_expires_at")
869
+ : null,
870
+ suppression_code: suppressionCode,
871
+ terms_effective_at: termsEffectiveAt,
872
+ };
873
+ }
874
+ assertSameMessageIdentity(existing, input) {
875
+ const conflicts = existing.kind !== input.kind ||
876
+ existing.resource_type !== input.resource_type ||
877
+ existing.resource_id !== input.resource_id ||
878
+ existing.trigger !== input.trigger ||
879
+ !equalJson(existing.required_facts, input.required_facts) ||
880
+ (existing.predecessor_message_id !== null &&
881
+ existing.predecessor_message_id !== input.predecessor_message_id) ||
882
+ (existing.recipient !== null &&
883
+ input.recipient !== null &&
884
+ existing.recipient !== input.recipient) ||
885
+ (existing.payload_expires_at !== null &&
886
+ input.payload_expires_at !== null &&
887
+ existing.payload_expires_at.getTime() !==
888
+ input.payload_expires_at.getTime());
889
+ if (conflicts) {
890
+ throw new utils_1.MedusaError(utils_1.MedusaError.Types.CONFLICT, "The email business key was reused with conflicting facts.");
891
+ }
892
+ }
893
+ mergeTemplateData(kind, existing, incoming) {
894
+ if (!existing) {
895
+ return incoming;
896
+ }
897
+ if (!incoming) {
898
+ return existing;
899
+ }
900
+ const merged = { ...existing };
901
+ for (const [key, value] of Object.entries(incoming)) {
902
+ if (key in merged && !equalJson(merged[key], value)) {
903
+ throw new utils_1.MedusaError(utils_1.MedusaError.Types.CONFLICT, "The email business key was reused with conflicting template data.");
904
+ }
905
+ merged[key] = value;
906
+ }
907
+ return types_1.EmailPersistedDataSchemas[kind].parse(merged);
908
+ }
909
+ mergeAttachments(existing, incoming) {
910
+ const byId = new Map(existing.map((attachment) => [(0, attachment_1.emailAttachmentId)(attachment), attachment]));
911
+ for (const artifact of incoming) {
912
+ const id = (0, attachment_1.emailAttachmentId)(artifact);
913
+ const prior = byId.get(id);
914
+ if (prior && !equalJson(prior, artifact)) {
915
+ throw new utils_1.MedusaError(utils_1.MedusaError.Types.CONFLICT, "The email business key was reused with conflicting attachments.");
916
+ }
917
+ byId.set(id, artifact);
918
+ }
919
+ return [...byId.values()];
920
+ }
921
+ async findTermsAttachmentAt(effectiveAt, sharedContext) {
922
+ const rows = await this.requireManager(sharedContext).execute(`select * from "email_terms_version"
923
+ where "effective_at" <= ? and "deleted_at" is null
924
+ order by "effective_at" desc, "created_at" desc, "id" desc
925
+ limit 1`, [effectiveAt], "all");
926
+ if (!rows[0]) {
927
+ return null;
928
+ }
929
+ const version = this.toTermsVersionRecord(rows[0]);
930
+ return {
931
+ source: "terms",
932
+ terms_version_id: version.id,
933
+ file_id: version.file_id,
934
+ filename: version.filename,
935
+ content_type: "application/pdf",
936
+ byte_size: version.byte_size,
937
+ sha256: version.sha256,
938
+ };
939
+ }
940
+ async resolvePendingState(requiredFacts, receivedFacts, predecessorMessageId, sharedContext) {
941
+ if (!predecessorMessageId) {
942
+ return (0, message_state_1.hasRequiredFacts)(requiredFacts, receivedFacts)
943
+ ? (0, message_state_1.statusAfterPredecessor)(null)
944
+ : { status: "pending", terminal_code: null };
945
+ }
946
+ const rows = await this.requireManager(sharedContext).execute(`select * from "email_message"
947
+ where "id" = ? and "deleted_at" is null`, [asNonEmptyString(predecessorMessageId, "predecessor_message_id")], "all");
948
+ if (!rows[0]) {
949
+ throw new utils_1.MedusaError(utils_1.MedusaError.Types.NOT_FOUND, "The predecessor email message was not found.");
950
+ }
951
+ return this.resolveStateWithPredecessor(requiredFacts, receivedFacts, this.toMessageRecord(rows[0]).status);
952
+ }
953
+ resolveStateWithPredecessor(requiredFacts, receivedFacts, predecessorStatus) {
954
+ const predecessorState = (0, message_state_1.statusAfterPredecessor)(predecessorStatus);
955
+ if (predecessorState.status === "failed" ||
956
+ predecessorState.status === "suppressed") {
957
+ return predecessorState;
958
+ }
959
+ return (0, message_state_1.hasRequiredFacts)(requiredFacts, receivedFacts)
960
+ ? predecessorState
961
+ : { status: "pending", terminal_code: null };
962
+ }
963
+ async reevaluateDependentMessages(predecessor, now, sharedContext, visited = new Set()) {
964
+ if (visited.has(predecessor.id)) {
965
+ return;
966
+ }
967
+ visited.add(predecessor.id);
968
+ const manager = this.requireManager(sharedContext);
969
+ const rows = await manager.execute(`select * from "email_message"
970
+ where "predecessor_message_id" = ? and "status" = 'pending'
971
+ and "deleted_at" is null
972
+ order by "id" asc
973
+ for update skip locked`, [predecessor.id], "all");
974
+ for (const row of rows) {
975
+ const dependent = this.toMessageRecord(row);
976
+ const state = this.resolveStateWithPredecessor(dependent.required_facts, dependent.received_facts, predecessor.status);
977
+ if (state.status === "pending") {
978
+ continue;
979
+ }
980
+ const updated = this.toMessageRecord((await this.updateEmailMessages({
981
+ id: dependent.id,
982
+ status: state.status,
983
+ terminal_code: state.terminal_code,
984
+ failed_at: state.status === "failed" ? now : dependent.failed_at,
985
+ }, sharedContext)));
986
+ if (updated.status === "failed" || updated.status === "suppressed") {
987
+ await this.reevaluateDependentMessages(updated, now, sharedContext, visited);
988
+ }
989
+ }
990
+ }
991
+ async lockMessage(messageId, sharedContext) {
992
+ const manager = this.requireManager(sharedContext);
993
+ const rows = await manager.execute(`select * from "email_message"
994
+ where "id" = ? and "deleted_at" is null for update`, [asNonEmptyString(messageId, "message_id")], "all");
995
+ if (!rows[0]) {
996
+ throw new utils_1.MedusaError(utils_1.MedusaError.Types.NOT_FOUND, "The email message was not found.");
997
+ }
998
+ return this.toMessageRecord(rows[0]);
999
+ }
1000
+ toMessageRecord(value) {
1001
+ const kind = types_1.EmailKindSchema.parse(value.kind);
1002
+ const templateData = value.template_data === null || value.template_data === undefined
1003
+ ? null
1004
+ : types_1.EmailPersistedDataSchemas[kind].parse(value.template_data);
1005
+ return {
1006
+ id: asNonEmptyString(value.id, "id"),
1007
+ kind,
1008
+ business_key: asNonEmptyString(value.business_key, "business_key"),
1009
+ resource_type: asNonEmptyString(value.resource_type, "resource_type"),
1010
+ resource_id: asNullableString(value.resource_id),
1011
+ recipient: asNullableString(value.recipient),
1012
+ template_data: templateData,
1013
+ attachments: attachment_1.EmailAttachmentSchema.array().parse(value.attachments ?? []),
1014
+ status: value.status,
1015
+ required_facts: (0, message_state_1.canonicalizeFacts)(Array.isArray(value.required_facts)
1016
+ ? value.required_facts
1017
+ : []),
1018
+ received_facts: (0, message_state_1.canonicalizeFacts)(Array.isArray(value.received_facts)
1019
+ ? value.received_facts
1020
+ : []),
1021
+ predecessor_message_id: asNullableString(value.predecessor_message_id),
1022
+ trigger: asNonEmptyString(value.trigger, "trigger"),
1023
+ request_id: asNullableString(value.request_id),
1024
+ requested_by_admin_id: asNullableString(value.requested_by_admin_id),
1025
+ original_message_id: asNullableString(value.original_message_id),
1026
+ next_attempt_at: asNullableDate(value.next_attempt_at),
1027
+ sent_at: asNullableDate(value.sent_at),
1028
+ failed_at: asNullableDate(value.failed_at),
1029
+ payload_expires_at: asNullableDate(value.payload_expires_at),
1030
+ terminal_code: asNullableString(value.terminal_code),
1031
+ created_at: asNullableDate(value.created_at) ?? new Date(0),
1032
+ updated_at: asNullableDate(value.updated_at) ?? new Date(0),
1033
+ deleted_at: asNullableDate(value.deleted_at),
1034
+ };
1035
+ }
1036
+ toAttemptRecord(value) {
1037
+ return {
1038
+ id: asNonEmptyString(value.id, "id"),
1039
+ message_id: asNonEmptyString(value.message_id, "message_id"),
1040
+ attempt_number: Number(value.attempt_number),
1041
+ status: value.status,
1042
+ attempt_token: asNullableString(value.attempt_token),
1043
+ lease_started_at: asNullableDate(value.lease_started_at),
1044
+ lease_expires_at: asNullableDate(value.lease_expires_at),
1045
+ notification_id: asNullableString(value.notification_id),
1046
+ failure_code: asNullableString(value.failure_code),
1047
+ started_at: asDate(value.started_at, "started_at"),
1048
+ finished_at: asNullableDate(value.finished_at),
1049
+ created_at: asNullableDate(value.created_at) ?? new Date(0),
1050
+ updated_at: asNullableDate(value.updated_at) ?? new Date(0),
1051
+ deleted_at: asNullableDate(value.deleted_at),
1052
+ };
1053
+ }
1054
+ toSafeAdminMessage(value) {
1055
+ const message = this.toMessageRecord(value);
1056
+ return {
1057
+ id: message.id,
1058
+ kind: message.kind,
1059
+ status: message.status,
1060
+ resource_type: message.resource_type,
1061
+ resource_id: message.resource_id,
1062
+ trigger: message.trigger,
1063
+ request_id: message.request_id,
1064
+ requested_by_admin_id: message.requested_by_admin_id,
1065
+ original_message_id: message.original_message_id,
1066
+ attempt_count: Number(value.attempt_count ?? 0),
1067
+ next_attempt_at: message.next_attempt_at?.toISOString() ?? null,
1068
+ sent_at: message.sent_at?.toISOString() ?? null,
1069
+ failed_at: message.failed_at?.toISOString() ?? null,
1070
+ terminal_code: message.terminal_code === null
1071
+ ? null
1072
+ : asSafeStatusCode(message.terminal_code, "terminal_code"),
1073
+ created_at: message.created_at.toISOString(),
1074
+ updated_at: message.updated_at.toISOString(),
1075
+ };
1076
+ }
1077
+ toSafeAdminAttempt(value) {
1078
+ return {
1079
+ id: asNonEmptyString(value.id, "id"),
1080
+ attempt_number: Number(value.attempt_number),
1081
+ status: value.status,
1082
+ failure_code: value.failure_code === null || value.failure_code === undefined
1083
+ ? null
1084
+ : asSafeStatusCode(value.failure_code, "failure_code"),
1085
+ started_at: asDate(value.started_at, "started_at").toISOString(),
1086
+ finished_at: asNullableDate(value.finished_at)?.toISOString() ?? null,
1087
+ created_at: asDate(value.created_at, "created_at").toISOString(),
1088
+ updated_at: asDate(value.updated_at, "updated_at").toISOString(),
1089
+ };
1090
+ }
1091
+ normalizeTermsVersionInput(input) {
1092
+ const byteSize = Number(input.byte_size);
1093
+ if (!Number.isInteger(byteSize) ||
1094
+ byteSize < 1 ||
1095
+ byteSize > email_1.EMAIL_TERMS_MAX_PDF_BYTES) {
1096
+ throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, `byte_size must be from 1 to ${email_1.EMAIL_TERMS_MAX_PDF_BYTES}.`);
1097
+ }
1098
+ const filename = TermsPdfFilenameSchema.safeParse(input.filename);
1099
+ if (!filename.success) {
1100
+ throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, "filename must be a safe PDF filename.");
1101
+ }
1102
+ const sha256 = Sha256Schema.safeParse(input.sha256);
1103
+ if (!sha256.success) {
1104
+ throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, "sha256 must be a lowercase SHA-256 digest.");
1105
+ }
1106
+ return {
1107
+ request_id: asUuid(input.request_id, "request_id"),
1108
+ filename: filename.data,
1109
+ effective_at: asDate(input.effective_at, "effective_at"),
1110
+ byte_size: byteSize,
1111
+ sha256: sha256.data,
1112
+ };
1113
+ }
1114
+ toTermsVersionRecord(value) {
1115
+ return {
1116
+ id: asNonEmptyString(value.id, "id"),
1117
+ request_id: asUuid(value.request_id, "request_id"),
1118
+ filename: asNonEmptyString(value.filename, "filename"),
1119
+ file_id: asNonEmptyString(value.file_id, "file_id"),
1120
+ effective_at: asDate(value.effective_at, "effective_at"),
1121
+ byte_size: Number(value.byte_size),
1122
+ sha256: asNonEmptyString(value.sha256, "sha256"),
1123
+ created_at: asDate(value.created_at, "created_at"),
1124
+ updated_at: asDate(value.updated_at, "updated_at"),
1125
+ deleted_at: asNullableDate(value.deleted_at),
1126
+ };
1127
+ }
1128
+ toSafeAdminTermsVersion(value) {
1129
+ return {
1130
+ id: value.id,
1131
+ filename: value.filename,
1132
+ effective_at: value.effective_at.toISOString(),
1133
+ byte_size: value.byte_size,
1134
+ sha256: value.sha256,
1135
+ created_at: value.created_at.toISOString(),
1136
+ };
1137
+ }
1138
+ positiveLimit(value) {
1139
+ if (!Number.isInteger(value) || value < 1 || value > 100) {
1140
+ throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, "limit must be an integer from 1 to 100.");
1141
+ }
1142
+ return value;
1143
+ }
1144
+ safeOffset(value) {
1145
+ if (!Number.isInteger(value) || value < 0 || value > 10_000) {
1146
+ throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, "offset must be an integer from 0 to 10000.");
1147
+ }
1148
+ return value;
1149
+ }
1150
+ requireManager(sharedContext) {
1151
+ const manager = sharedContext.transactionManager;
1152
+ if (!manager) {
1153
+ throw new utils_1.MedusaError(utils_1.MedusaError.Types.UNEXPECTED_STATE, "Email persistence requires a database transaction manager.");
1154
+ }
1155
+ return manager;
1156
+ }
1157
+ }
1158
+ __decorate([
1159
+ (0, utils_1.InjectTransactionManager)(),
1160
+ __param(1, (0, utils_1.MedusaContext)()),
1161
+ __metadata("design:type", Function),
1162
+ __metadata("design:paramtypes", [String, Object]),
1163
+ __metadata("design:returntype", Promise)
1164
+ ], EmailModuleService.prototype, "findMessageByBusinessKey", null);
1165
+ __decorate([
1166
+ (0, utils_1.InjectTransactionManager)(),
1167
+ __param(1, (0, utils_1.MedusaContext)()),
1168
+ __metadata("design:type", Function),
1169
+ __metadata("design:paramtypes", [Object, Object]),
1170
+ __metadata("design:returntype", Promise)
1171
+ ], EmailModuleService.prototype, "upsertMessageFact", null);
1172
+ __decorate([
1173
+ (0, utils_1.InjectTransactionManager)(),
1174
+ __param(3, (0, utils_1.MedusaContext)()),
1175
+ __metadata("design:type", Function),
1176
+ __metadata("design:paramtypes", [Object, Function, Function, Object]),
1177
+ __metadata("design:returntype", Promise)
1178
+ ], EmailModuleService.prototype, "createEmailTermsVersion", null);
1179
+ __decorate([
1180
+ (0, utils_1.InjectTransactionManager)(),
1181
+ __param(1, (0, utils_1.MedusaContext)()),
1182
+ __metadata("design:type", Function),
1183
+ __metadata("design:paramtypes", [Object, Object]),
1184
+ __metadata("design:returntype", Promise)
1185
+ ], EmailModuleService.prototype, "listAdminEmailTermsVersions", null);
1186
+ __decorate([
1187
+ (0, utils_1.InjectTransactionManager)(),
1188
+ __param(1, (0, utils_1.MedusaContext)()),
1189
+ __metadata("design:type", Function),
1190
+ __metadata("design:paramtypes", [String, Object]),
1191
+ __metadata("design:returntype", Promise)
1192
+ ], EmailModuleService.prototype, "getEmailTermsVersionFile", null);
1193
+ __decorate([
1194
+ (0, utils_1.InjectTransactionManager)(),
1195
+ __param(2, (0, utils_1.MedusaContext)()),
1196
+ __metadata("design:type", Function),
1197
+ __metadata("design:paramtypes", [Object, Function, Object]),
1198
+ __metadata("design:returntype", Promise)
1199
+ ], EmailModuleService.prototype, "createAffiliateReminderMessage", null);
1200
+ __decorate([
1201
+ (0, utils_1.InjectTransactionManager)(),
1202
+ __param(1, (0, utils_1.MedusaContext)()),
1203
+ __metadata("design:type", Function),
1204
+ __metadata("design:paramtypes", [Object, Object]),
1205
+ __metadata("design:returntype", Promise)
1206
+ ], EmailModuleService.prototype, "createAdminResend", null);
1207
+ __decorate([
1208
+ (0, utils_1.InjectTransactionManager)(),
1209
+ __param(1, (0, utils_1.MedusaContext)()),
1210
+ __metadata("design:type", Function),
1211
+ __metadata("design:paramtypes", [Object, Object]),
1212
+ __metadata("design:returntype", Promise)
1213
+ ], EmailModuleService.prototype, "listAdminEmailMessages", null);
1214
+ __decorate([
1215
+ (0, utils_1.InjectTransactionManager)(),
1216
+ __param(1, (0, utils_1.MedusaContext)()),
1217
+ __metadata("design:type", Function),
1218
+ __metadata("design:paramtypes", [String, Object]),
1219
+ __metadata("design:returntype", Promise)
1220
+ ], EmailModuleService.prototype, "getAdminEmailMessage", null);
1221
+ __decorate([
1222
+ (0, utils_1.InjectTransactionManager)(),
1223
+ __param(1, (0, utils_1.MedusaContext)()),
1224
+ __metadata("design:type", Function),
1225
+ __metadata("design:paramtypes", [Object, Object]),
1226
+ __metadata("design:returntype", Promise)
1227
+ ], EmailModuleService.prototype, "suppressMessage", null);
1228
+ __decorate([
1229
+ (0, utils_1.InjectTransactionManager)(),
1230
+ __param(1, (0, utils_1.MedusaContext)()),
1231
+ __metadata("design:type", Function),
1232
+ __metadata("design:paramtypes", [Object, Object]),
1233
+ __metadata("design:returntype", Promise)
1234
+ ], EmailModuleService.prototype, "claimReadyMessage", null);
1235
+ __decorate([
1236
+ (0, utils_1.InjectTransactionManager)(),
1237
+ __param(1, (0, utils_1.MedusaContext)()),
1238
+ __metadata("design:type", Function),
1239
+ __metadata("design:paramtypes", [Object, Object]),
1240
+ __metadata("design:returntype", Promise)
1241
+ ], EmailModuleService.prototype, "claimReadyMessageForAutomaticDispatch", null);
1242
+ __decorate([
1243
+ (0, utils_1.InjectTransactionManager)(),
1244
+ __param(1, (0, utils_1.MedusaContext)()),
1245
+ __metadata("design:type", Function),
1246
+ __metadata("design:paramtypes", [Object, Object]),
1247
+ __metadata("design:returntype", Promise)
1248
+ ], EmailModuleService.prototype, "claimDueRetries", null);
1249
+ __decorate([
1250
+ (0, utils_1.InjectTransactionManager)(),
1251
+ __param(1, (0, utils_1.MedusaContext)()),
1252
+ __metadata("design:type", Function),
1253
+ __metadata("design:paramtypes", [Object, Object]),
1254
+ __metadata("design:returntype", Promise)
1255
+ ], EmailModuleService.prototype, "renewAttemptLease", null);
1256
+ __decorate([
1257
+ (0, utils_1.InjectTransactionManager)(),
1258
+ __param(1, (0, utils_1.MedusaContext)()),
1259
+ __metadata("design:type", Function),
1260
+ __metadata("design:paramtypes", [Object, Object]),
1261
+ __metadata("design:returntype", Promise)
1262
+ ], EmailModuleService.prototype, "listStaleAttemptCandidates", null);
1263
+ __decorate([
1264
+ (0, utils_1.InjectTransactionManager)(),
1265
+ __param(1, (0, utils_1.MedusaContext)()),
1266
+ __metadata("design:type", Function),
1267
+ __metadata("design:paramtypes", [Object, Object]),
1268
+ __metadata("design:returntype", Promise)
1269
+ ], EmailModuleService.prototype, "reconcilePendingMessageDependencies", null);
1270
+ __decorate([
1271
+ (0, utils_1.InjectTransactionManager)(),
1272
+ __param(1, (0, utils_1.MedusaContext)()),
1273
+ __metadata("design:type", Function),
1274
+ __metadata("design:paramtypes", [Object, Object]),
1275
+ __metadata("design:returntype", Promise)
1276
+ ], EmailModuleService.prototype, "listReadyMessageIds", null);
1277
+ __decorate([
1278
+ (0, utils_1.InjectTransactionManager)(),
1279
+ __param(1, (0, utils_1.MedusaContext)()),
1280
+ __metadata("design:type", Function),
1281
+ __metadata("design:paramtypes", [Object, Object]),
1282
+ __metadata("design:returntype", Promise)
1283
+ ], EmailModuleService.prototype, "completeAttempt", null);
1284
+ exports.default = EmailModuleService;
1285
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3NyYy9tb2R1bGVzL2VtYWlsL3NlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUEsNkNBQXlDO0FBR3pDLHFEQUttQztBQUNuQyxpREFBNEM7QUFDNUMsa0dBRzRFO0FBQzVFLDJGQUE0RztBQUU1Ryw2Q0FNMkI7QUFFM0Isb0VBQTBFO0FBQzFFLGlFQUFrRTtBQUNsRSxpR0FBaUc7QUFDakcsc0ZBQXdGO0FBQ3hGLG9EQUs2QjtBQUM3QiwwREFTZ0M7QUFDaEMsMkVBQWtEO0FBQ2xELDJFQUFrRDtBQUNsRCx1RkFBNkQ7QUFFaEQsUUFBQSxzQkFBc0IsR0FBRyxDQUFDLEdBQUcsRUFBRSxHQUFHLElBQUksQ0FBQztBQTJMcEQsTUFBTSxzQkFBc0IsR0FBRyxJQUFBLHFCQUFhLEVBQUM7SUFDM0MsWUFBWSxFQUFaLHVCQUFZO0lBQ1osWUFBWSxFQUFaLHVCQUFZO0lBQ1osaUJBQWlCLEVBQWpCLDZCQUFpQjtDQUNsQixDQUFDLENBQUM7QUFFSCxNQUFNLGdCQUFnQixHQUFHLENBQUMsS0FBYyxFQUFFLEtBQWEsRUFBVSxFQUFFO0lBQ2pFLElBQUksT0FBTyxLQUFLLEtBQUssUUFBUSxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUM7UUFDL0MsTUFBTSxJQUFJLG1CQUFXLENBQ25CLG1CQUFXLENBQUMsS0FBSyxDQUFDLFlBQVksRUFDOUIsR0FBRyxLQUFLLDhCQUE4QixDQUN2QyxDQUFDO0lBQ0osQ0FBQztJQUNELE9BQU8sS0FBSyxDQUFDLElBQUksRUFBRSxDQUFDO0FBQ3RCLENBQUMsQ0FBQztBQUVGLE1BQU0sZ0JBQWdCLEdBQUcsQ0FBQyxLQUFjLEVBQWlCLEVBQUUsQ0FDekQsT0FBTyxLQUFLLEtBQUssUUFBUSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLElBQUks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