@hszrdm/core 1.4.0 → 1.6.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 (182) hide show
  1. package/.medusa/server/src/admin/index.js +6361 -3789
  2. package/.medusa/server/src/admin/index.mjs +6361 -3789
  3. package/.medusa/server/src/api/admin/back-in-stock/route.d.ts +2 -0
  4. package/.medusa/server/src/api/admin/back-in-stock/route.js +70 -0
  5. package/.medusa/server/src/api/admin/core-carts/[id]/items/[itemId]/route.d.ts +3 -0
  6. package/.medusa/server/src/api/admin/core-carts/[id]/items/[itemId]/route.js +64 -0
  7. package/.medusa/server/src/api/admin/core-carts/[id]/items/route.d.ts +2 -0
  8. package/.medusa/server/src/api/admin/core-carts/[id]/items/route.js +40 -0
  9. package/.medusa/server/src/api/admin/core-carts/[id]/promotions/[code]/route.d.ts +2 -0
  10. package/.medusa/server/src/api/admin/core-carts/[id]/promotions/[code]/route.js +40 -0
  11. package/.medusa/server/src/api/admin/core-carts/[id]/promotions/route.d.ts +2 -0
  12. package/.medusa/server/src/api/admin/core-carts/[id]/promotions/route.js +41 -0
  13. package/.medusa/server/src/api/admin/core-carts/[id]/route.d.ts +2 -0
  14. package/.medusa/server/src/api/admin/core-carts/[id]/route.js +28 -0
  15. package/.medusa/server/src/api/admin/core-carts/customer/[id]/route.d.ts +2 -0
  16. package/.medusa/server/src/api/admin/core-carts/customer/[id]/route.js +34 -0
  17. package/.medusa/server/src/api/admin/core-carts/route.d.ts +3 -0
  18. package/.medusa/server/src/api/admin/core-carts/route.js +69 -0
  19. package/.medusa/server/src/api/admin/customer-activation/route.d.ts +2 -0
  20. package/.medusa/server/src/api/admin/customer-activation/route.js +97 -0
  21. package/.medusa/server/src/api/admin/customer-import/route.d.ts +2 -0
  22. package/.medusa/server/src/api/admin/customer-import/route.js +166 -0
  23. package/.medusa/server/src/api/admin/order-export/route.d.ts +2 -0
  24. package/.medusa/server/src/api/admin/order-export/route.js +88 -0
  25. package/.medusa/server/src/api/admin/product-migration/inventory/route.d.ts +3 -0
  26. package/.medusa/server/src/api/admin/product-migration/inventory/route.js +164 -0
  27. package/.medusa/server/src/api/admin/product-migration/price-list-prices/route.d.ts +3 -0
  28. package/.medusa/server/src/api/admin/product-migration/price-list-prices/route.js +204 -0
  29. package/.medusa/server/src/api/admin/product-migration/products/route.d.ts +2 -0
  30. package/.medusa/server/src/api/admin/product-migration/products/route.js +24 -0
  31. package/.medusa/server/src/api/admin/product-reviews/[id]/route.js +36 -4
  32. package/.medusa/server/src/api/admin/product-reviews/settings/route.d.ts +3 -0
  33. package/.medusa/server/src/api/admin/product-reviews/settings/route.js +63 -0
  34. package/.medusa/server/src/api/admin/shared-cart/settings/route.d.ts +5 -0
  35. package/.medusa/server/src/api/admin/shared-cart/settings/route.js +31 -0
  36. package/.medusa/server/src/api/admin/system-runtime/route.d.ts +2 -0
  37. package/.medusa/server/src/api/admin/system-runtime/route.js +18 -0
  38. package/.medusa/server/src/api/hooks/packeta/status/route.d.ts +2 -0
  39. package/.medusa/server/src/api/hooks/packeta/status/route.js +55 -0
  40. package/.medusa/server/src/api/middlewares.js +24 -1
  41. package/.medusa/server/src/api/store/abandoned-cart/recover/route.d.ts +2 -0
  42. package/.medusa/server/src/api/store/abandoned-cart/recover/route.js +37 -0
  43. package/.medusa/server/src/api/store/back-in-stock/route.d.ts +8 -0
  44. package/.medusa/server/src/api/store/back-in-stock/route.js +124 -0
  45. package/.medusa/server/src/api/store/core-carts/me/active/route.d.ts +2 -0
  46. package/.medusa/server/src/api/store/core-carts/me/active/route.js +54 -0
  47. package/.medusa/server/src/api/store/customer-activation/complete/route.d.ts +2 -0
  48. package/.medusa/server/src/api/store/customer-activation/complete/route.js +96 -0
  49. package/.medusa/server/src/api/store/customer-activation/route.d.ts +2 -0
  50. package/.medusa/server/src/api/store/customer-activation/route.js +34 -0
  51. package/.medusa/server/src/api/store/products/[id]/reviews/route.d.ts +1 -0
  52. package/.medusa/server/src/api/store/products/[id]/reviews/route.js +76 -34
  53. package/.medusa/server/src/api/store/review-request/route.d.ts +2 -0
  54. package/.medusa/server/src/api/store/review-request/route.js +60 -0
  55. package/.medusa/server/src/api/store/shared-carts/[token]/route.d.ts +2 -0
  56. package/.medusa/server/src/api/store/shared-carts/[token]/route.js +52 -0
  57. package/.medusa/server/src/api/store/shared-carts/route.d.ts +13 -0
  58. package/.medusa/server/src/api/store/shared-carts/route.js +78 -0
  59. package/.medusa/server/src/core/abandoned-cart.d.ts +64 -0
  60. package/.medusa/server/src/core/abandoned-cart.js +197 -0
  61. package/.medusa/server/src/core/admin-cart-management.d.ts +18 -0
  62. package/.medusa/server/src/core/admin-cart-management.js +102 -0
  63. package/.medusa/server/src/core/admin-cart-visibility.d.ts +94 -0
  64. package/.medusa/server/src/core/admin-cart-visibility.js +192 -0
  65. package/.medusa/server/src/core/back-in-stock.d.ts +51 -0
  66. package/.medusa/server/src/core/back-in-stock.js +107 -0
  67. package/.medusa/server/src/core/cart-observability.d.ts +23 -0
  68. package/.medusa/server/src/core/cart-observability.js +54 -0
  69. package/.medusa/server/src/core/checkout-contract.d.ts +1 -0
  70. package/.medusa/server/src/core/checkout-contract.js +2 -1
  71. package/.medusa/server/src/core/customer-account-contract.d.ts +3 -0
  72. package/.medusa/server/src/core/customer-account-contract.js +4 -1
  73. package/.medusa/server/src/core/customer-activation.d.ts +120 -0
  74. package/.medusa/server/src/core/customer-activation.js +169 -0
  75. package/.medusa/server/src/core/customer-cart-resume.d.ts +21 -0
  76. package/.medusa/server/src/core/customer-cart-resume.js +72 -0
  77. package/.medusa/server/src/core/customer-email.d.ts +1 -1
  78. package/.medusa/server/src/core/customer-email.js +4 -1
  79. package/.medusa/server/src/core/native-migration-export.d.ts +6 -0
  80. package/.medusa/server/src/core/native-migration-export.js +105 -0
  81. package/.medusa/server/src/core/order-export.d.ts +11 -0
  82. package/.medusa/server/src/core/order-export.js +297 -0
  83. package/.medusa/server/src/core/review-request.d.ts +61 -0
  84. package/.medusa/server/src/core/review-request.js +105 -0
  85. package/.medusa/server/src/core/review-reward.d.ts +94 -0
  86. package/.medusa/server/src/core/review-reward.js +124 -0
  87. package/.medusa/server/src/core/runtime-health.d.ts +39 -0
  88. package/.medusa/server/src/core/runtime-health.js +250 -0
  89. package/.medusa/server/src/core/storefront-core-config.d.ts +10 -0
  90. package/.medusa/server/src/core/storefront-core-config.js +26 -1
  91. package/.medusa/server/src/core/version.d.ts +2 -2
  92. package/.medusa/server/src/core/version.js +2 -2
  93. package/.medusa/server/src/jobs/abandoned-cart-recovery.d.ts +23 -0
  94. package/.medusa/server/src/jobs/abandoned-cart-recovery.js +137 -0
  95. package/.medusa/server/src/jobs/back-in-stock-reconciliation.d.ts +15 -0
  96. package/.medusa/server/src/jobs/back-in-stock-reconciliation.js +90 -0
  97. package/.medusa/server/src/jobs/dpd-statusdata-sync.d.ts +17 -0
  98. package/.medusa/server/src/jobs/dpd-statusdata-sync.js +107 -0
  99. package/.medusa/server/src/jobs/mpl-push-tracking.d.ts +19 -0
  100. package/.medusa/server/src/jobs/mpl-push-tracking.js +183 -0
  101. package/.medusa/server/src/jobs/mpl-status-sync.d.ts +8 -2
  102. package/.medusa/server/src/jobs/mpl-status-sync.js +12 -7
  103. package/.medusa/server/src/jobs/product-review-request-dispatch.d.ts +28 -0
  104. package/.medusa/server/src/jobs/product-review-request-dispatch.js +84 -0
  105. package/.medusa/server/src/jobs/runtime-heartbeat.d.ts +12 -0
  106. package/.medusa/server/src/jobs/runtime-heartbeat.js +13 -0
  107. package/.medusa/server/src/jobs/shipping-status-sync.d.ts +8 -2
  108. package/.medusa/server/src/jobs/shipping-status-sync.js +11 -14
  109. package/.medusa/server/src/lib/modules/shipping/idempotency.js +3 -3
  110. package/.medusa/server/src/lib/modules/shipping/index.d.ts +1 -0
  111. package/.medusa/server/src/lib/modules/shipping/index.js +2 -1
  112. package/.medusa/server/src/lib/modules/shipping/tracking.d.ts +48 -0
  113. package/.medusa/server/src/lib/modules/shipping/tracking.js +368 -0
  114. package/.medusa/server/src/lib/modules/shipping/webhooks.d.ts +6 -9
  115. package/.medusa/server/src/lib/modules/shipping/webhooks.js +24 -137
  116. package/.medusa/server/src/modules/back-in-stock/index.d.ts +23 -0
  117. package/.medusa/server/src/modules/back-in-stock/index.js +16 -0
  118. package/.medusa/server/src/modules/back-in-stock/migrations/Migration20261101202000.d.ts +5 -0
  119. package/.medusa/server/src/modules/back-in-stock/migrations/Migration20261101202000.js +18 -0
  120. package/.medusa/server/src/modules/back-in-stock/models/back-in-stock-subscription.d.ts +13 -0
  121. package/.medusa/server/src/modules/back-in-stock/models/back-in-stock-subscription.js +23 -0
  122. package/.medusa/server/src/modules/back-in-stock/service.d.ts +22 -0
  123. package/.medusa/server/src/modules/back-in-stock/service.js +12 -0
  124. package/.medusa/server/src/modules/email-center/abandoned-cart-registration.d.ts +1 -0
  125. package/.medusa/server/src/modules/email-center/abandoned-cart-registration.js +27 -0
  126. package/.medusa/server/src/modules/email-center/back-in-stock-registration.d.ts +1 -0
  127. package/.medusa/server/src/modules/email-center/back-in-stock-registration.js +27 -0
  128. package/.medusa/server/src/modules/email-center/defaults.js +7 -1
  129. package/.medusa/server/src/modules/email-center/index.d.ts +2 -0
  130. package/.medusa/server/src/modules/email-center/index.js +3 -1
  131. package/.medusa/server/src/modules/integration-settings/abandoned-cart-registration.d.ts +1 -0
  132. package/.medusa/server/src/modules/integration-settings/abandoned-cart-registration.js +30 -0
  133. package/.medusa/server/src/modules/integration-settings/index.d.ts +1 -0
  134. package/.medusa/server/src/modules/integration-settings/index.js +2 -1
  135. package/.medusa/server/src/modules/integration-settings/storefront-public-registration.js +15 -1
  136. package/.medusa/server/src/modules/product-review/index.d.ts +14 -0
  137. package/.medusa/server/src/modules/product-review/migrations/Migration20261101113000.d.ts +5 -0
  138. package/.medusa/server/src/modules/product-review/migrations/Migration20261101113000.js +28 -0
  139. package/.medusa/server/src/modules/product-review/migrations/Migration20261101114500.d.ts +5 -0
  140. package/.medusa/server/src/modules/product-review/migrations/Migration20261101114500.js +20 -0
  141. package/.medusa/server/src/modules/product-review/migrations/Migration20261101121500.d.ts +5 -0
  142. package/.medusa/server/src/modules/product-review/migrations/Migration20261101121500.js +18 -0
  143. package/.medusa/server/src/modules/product-review/models/product-review-settings.d.ts +15 -0
  144. package/.medusa/server/src/modules/product-review/models/product-review-settings.js +19 -0
  145. package/.medusa/server/src/modules/product-review/models/product-review.d.ts +6 -2
  146. package/.medusa/server/src/modules/product-review/models/product-review.js +7 -3
  147. package/.medusa/server/src/modules/product-review/service.d.ts +22 -1
  148. package/.medusa/server/src/modules/product-review/service.js +3 -2
  149. package/.medusa/server/src/modules/shared-cart/index.d.ts +21 -0
  150. package/.medusa/server/src/modules/shared-cart/index.js +13 -0
  151. package/.medusa/server/src/modules/shared-cart/migrations/Migration20261102010000.d.ts +5 -0
  152. package/.medusa/server/src/modules/shared-cart/migrations/Migration20261102010000.js +16 -0
  153. package/.medusa/server/src/modules/shared-cart/models/shared-cart.d.ts +10 -0
  154. package/.medusa/server/src/modules/shared-cart/models/shared-cart.js +17 -0
  155. package/.medusa/server/src/modules/shared-cart/service.d.ts +14 -0
  156. package/.medusa/server/src/modules/shared-cart/service.js +11 -0
  157. package/.medusa/server/src/modules/shared-cart/settings.d.ts +7 -0
  158. package/.medusa/server/src/modules/shared-cart/settings.js +64 -0
  159. package/.medusa/server/src/providers/dpd/index.d.ts +2 -0
  160. package/.medusa/server/src/providers/dpd/index.js +3 -1
  161. package/.medusa/server/src/providers/dpd/statusdata-ftp.d.ts +16 -0
  162. package/.medusa/server/src/providers/dpd/statusdata-ftp.js +268 -0
  163. package/.medusa/server/src/providers/dpd/statusdata.d.ts +14 -0
  164. package/.medusa/server/src/providers/dpd/statusdata.js +161 -0
  165. package/.medusa/server/src/providers/mpl/client.d.ts +3 -1
  166. package/.medusa/server/src/providers/mpl/client.js +154 -2
  167. package/.medusa/server/src/providers/mpl/service.js +31 -20
  168. package/.medusa/server/src/providers/mpl/types.d.ts +25 -0
  169. package/.medusa/server/src/providers/mpl/types.js +1 -1
  170. package/.medusa/server/src/providers/packeta/index.d.ts +1 -0
  171. package/.medusa/server/src/providers/packeta/index.js +2 -1
  172. package/.medusa/server/src/providers/packeta/push-tracking.d.ts +8 -0
  173. package/.medusa/server/src/providers/packeta/push-tracking.js +96 -0
  174. package/.medusa/server/src/providers/packeta/service.js +22 -2
  175. package/.medusa/server/src/scripts/core-init.d.ts +1 -1
  176. package/.medusa/server/src/scripts/core-init.js +3 -2
  177. package/.medusa/server/src/subscribers/back-in-stock-inventory-changed.d.ts +7 -0
  178. package/.medusa/server/src/subscribers/back-in-stock-inventory-changed.js +65 -0
  179. package/.medusa/server/src/workflows/link-migrated-customer.d.ts +8 -0
  180. package/.medusa/server/src/workflows/link-migrated-customer.js +17 -0
  181. package/README.md +1 -1
  182. package/package.json +30 -8
@@ -0,0 +1,61 @@
1
+ export type ReviewRequestTrigger = "order" | "fulfillment" | "delivery";
2
+ type ReviewRequestTokenPayload = {
3
+ order_id: string;
4
+ customer_id: string;
5
+ exp: number;
6
+ };
7
+ type OrderLike = {
8
+ id: string;
9
+ customer_id?: string | null;
10
+ email?: string | null;
11
+ created_at?: string | Date | null;
12
+ fulfillment_status?: string | null;
13
+ fulfillments?: Array<{
14
+ created_at?: string | Date | null;
15
+ }> | null;
16
+ metadata?: Record<string, any> | null;
17
+ };
18
+ export declare function reviewRequestDueAt(order: OrderLike, trigger: ReviewRequestTrigger, delayDays: number): Date | null;
19
+ export declare function triggerTimestamp(order: OrderLike, trigger: ReviewRequestTrigger): Date | null;
20
+ export declare function createReviewRequestToken(orderId: string, customerId: string, ttlDays?: number): string;
21
+ export declare function verifyReviewRequestToken(token: string): ReviewRequestTokenPayload | null;
22
+ export declare function reviewRequestUrl(orderId: string, customerId: string): string;
23
+ export declare function sendReviewRequestEmail(input: {
24
+ container: {
25
+ resolve: (key: string) => unknown;
26
+ };
27
+ order: OrderLike & {
28
+ customer?: {
29
+ first_name?: string | null;
30
+ } | null;
31
+ };
32
+ }): Promise<{
33
+ skipped: boolean;
34
+ reason: "missing-email";
35
+ locale?: undefined;
36
+ template?: undefined;
37
+ } | {
38
+ skipped: boolean;
39
+ reason: "disabled";
40
+ locale?: undefined;
41
+ template?: undefined;
42
+ } | {
43
+ skipped: boolean;
44
+ locale: string;
45
+ template: string;
46
+ reason?: undefined;
47
+ } | {
48
+ skipped: boolean;
49
+ reason: "provider-disabled";
50
+ locale?: undefined;
51
+ template?: undefined;
52
+ } | {
53
+ skipped: boolean;
54
+ reason: "missing-template";
55
+ locale?: undefined;
56
+ template?: undefined;
57
+ } | {
58
+ skipped: boolean;
59
+ reason: "missing-customer";
60
+ }>;
61
+ export {};
@@ -0,0 +1,105 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.reviewRequestDueAt = reviewRequestDueAt;
4
+ exports.triggerTimestamp = triggerTimestamp;
5
+ exports.createReviewRequestToken = createReviewRequestToken;
6
+ exports.verifyReviewRequestToken = verifyReviewRequestToken;
7
+ exports.reviewRequestUrl = reviewRequestUrl;
8
+ exports.sendReviewRequestEmail = sendReviewRequestEmail;
9
+ const node_crypto_1 = require("node:crypto");
10
+ const customer_email_1 = require("./customer-email");
11
+ function reviewRequestDueAt(order, trigger, delayDays) {
12
+ const base = triggerTimestamp(order, trigger);
13
+ if (!base)
14
+ return null;
15
+ const delay = Math.max(0, Math.min(90, Math.trunc(Number(delayDays) || 0)));
16
+ return new Date(base.getTime() + delay * 86_400_000);
17
+ }
18
+ function triggerTimestamp(order, trigger) {
19
+ if (trigger === "order")
20
+ return asDate(order.created_at);
21
+ if (trigger === "fulfillment") {
22
+ const fulfillments = Array.isArray(order.fulfillments) ? order.fulfillments : [];
23
+ if (!fulfillments.length)
24
+ return null;
25
+ const dates = fulfillments.map((item) => asDate(item.created_at)).filter(Boolean);
26
+ if (!dates.length)
27
+ return null;
28
+ return new Date(Math.max(...dates.map((date) => date.getTime())));
29
+ }
30
+ const metadata = order.metadata || {};
31
+ for (const carrier of ["foxpost", "gls", "packeta", "dpd", "mpl"]) {
32
+ const shipment = metadata[carrier];
33
+ if (!shipment || String(shipment.status || "").toUpperCase() !== "DELIVERED")
34
+ continue;
35
+ const deliveredAt = asDate(shipment.statusUpdatedAt || shipment.status_updated_at || shipment.deliveredAt || shipment.delivered_at);
36
+ if (deliveredAt)
37
+ return deliveredAt;
38
+ }
39
+ return null;
40
+ }
41
+ function createReviewRequestToken(orderId, customerId, ttlDays = 30) {
42
+ const payload = {
43
+ order_id: orderId,
44
+ customer_id: customerId,
45
+ exp: Math.floor(Date.now() / 1000) + Math.max(1, Math.min(180, Math.trunc(ttlDays))) * 86_400,
46
+ };
47
+ const encoded = Buffer.from(JSON.stringify(payload)).toString("base64url");
48
+ return `${encoded}.${sign(encoded)}`;
49
+ }
50
+ function verifyReviewRequestToken(token) {
51
+ const [encoded, signature] = String(token || "").split(".");
52
+ if (!encoded || !signature)
53
+ return null;
54
+ const expected = Buffer.from(sign(encoded));
55
+ const actual = Buffer.from(signature);
56
+ if (expected.length !== actual.length || !(0, node_crypto_1.timingSafeEqual)(expected, actual))
57
+ return null;
58
+ try {
59
+ const payload = JSON.parse(Buffer.from(encoded, "base64url").toString("utf8"));
60
+ if (!payload.order_id || !payload.customer_id || !payload.exp || payload.exp <= Math.floor(Date.now() / 1000))
61
+ return null;
62
+ return payload;
63
+ }
64
+ catch {
65
+ return null;
66
+ }
67
+ }
68
+ function reviewRequestUrl(orderId, customerId) {
69
+ const token = createReviewRequestToken(orderId, customerId);
70
+ return `${(0, customer_email_1.storefrontUrl)()}/ertekeles?token=${encodeURIComponent(token)}`;
71
+ }
72
+ async function sendReviewRequestEmail(input) {
73
+ const email = String(input.order.email || "").trim().toLowerCase();
74
+ const customerId = String(input.order.customer_id || "").trim();
75
+ if (!email || !customerId)
76
+ return { skipped: true, reason: "missing-customer" };
77
+ return (0, customer_email_1.queueCustomerAccountEmail)({
78
+ container: input.container,
79
+ kind: "review_request",
80
+ to: email,
81
+ resourceId: customerId,
82
+ idempotencyKey: `product-review-request:${input.order.id}`,
83
+ data: {
84
+ first_name: input.order.customer?.first_name || "",
85
+ order_id: input.order.id,
86
+ review_url: reviewRequestUrl(input.order.id, customerId),
87
+ },
88
+ });
89
+ }
90
+ function sign(value) {
91
+ return (0, node_crypto_1.createHmac)("sha256", tokenSecret()).update(value).digest("base64url");
92
+ }
93
+ function tokenSecret() {
94
+ const secret = process.env.REVIEW_REQUEST_TOKEN_SECRET || process.env.COOKIE_SECRET || process.env.JWT_SECRET;
95
+ if (!secret || secret.length < 16)
96
+ throw new Error("REVIEW_REQUEST_TOKEN_SECRET, COOKIE_SECRET vagy JWT_SECRET szükséges az értékelési linkekhez.");
97
+ return secret;
98
+ }
99
+ function asDate(value) {
100
+ if (!value)
101
+ return null;
102
+ const date = value instanceof Date ? value : new Date(String(value));
103
+ return Number.isNaN(date.getTime()) ? null : date;
104
+ }
105
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmV2aWV3LXJlcXVlc3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvY29yZS9yZXZpZXctcmVxdWVzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQXFCQSxnREFLQztBQUVELDRDQW1CQztBQUVELDREQVFDO0FBRUQsNERBYUM7QUFFRCw0Q0FHQztBQUVELHdEQW1CQztBQWxHRCw2Q0FBeUQ7QUFDekQscURBQTJFO0FBb0IzRSxTQUFnQixrQkFBa0IsQ0FBQyxLQUFnQixFQUFFLE9BQTZCLEVBQUUsU0FBaUI7SUFDbkcsTUFBTSxJQUFJLEdBQUcsZ0JBQWdCLENBQUMsS0FBSyxFQUFFLE9BQU8sQ0FBQyxDQUFBO0lBQzdDLElBQUksQ0FBQyxJQUFJO1FBQUUsT0FBTyxJQUFJLENBQUE7SUFDdEIsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFBO0lBQzNFLE9BQU8sSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxHQUFHLEtBQUssR0FBRyxVQUFVLENBQUMsQ0FBQTtBQUN0RCxDQUFDO0FBRUQsU0FBZ0IsZ0JBQWdCLENBQUMsS0FBZ0IsRUFBRSxPQUE2QjtJQUM5RSxJQUFJLE9BQU8sS0FBSyxPQUFPO1FBQUUsT0FBTyxNQUFNLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQyxDQUFBO0lBRXhELElBQUksT0FBTyxLQUFLLGFBQWEsRUFBRSxDQUFDO1FBQzlCLE1BQU0sWUFBWSxHQUFHLEtBQUssQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUE7UUFDaEYsSUFBSSxDQUFDLFlB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
@@ -0,0 +1,94 @@
1
+ type ResolveContainer = {
2
+ resolve: (key: string) => unknown;
3
+ };
4
+ type RewardSettings = {
5
+ reward_enabled?: boolean;
6
+ reward_type?: "percentage" | "fixed";
7
+ reward_value?: number;
8
+ reward_currency_code?: string;
9
+ reward_coupon_expiry_days?: number;
10
+ reward_once_per_order?: boolean;
11
+ reward_email_enabled?: boolean;
12
+ };
13
+ export declare function isSuspiciousReview(body: string): boolean;
14
+ export declare function issuePublishedReviewReward(input: {
15
+ container: ResolveContainer;
16
+ review: Record<string, any>;
17
+ settings: RewardSettings;
18
+ }): Promise<{
19
+ id: any;
20
+ code: any;
21
+ existing: boolean;
22
+ orderReward?: undefined;
23
+ customer?: undefined;
24
+ type?: undefined;
25
+ value?: undefined;
26
+ currency?: undefined;
27
+ expiryDays?: undefined;
28
+ expiresAt?: undefined;
29
+ rewardEmailEnabled?: undefined;
30
+ } | {
31
+ id: any;
32
+ code: any;
33
+ existing: boolean;
34
+ orderReward: boolean;
35
+ customer?: undefined;
36
+ type?: undefined;
37
+ value?: undefined;
38
+ currency?: undefined;
39
+ expiryDays?: undefined;
40
+ expiresAt?: undefined;
41
+ rewardEmailEnabled?: undefined;
42
+ } | {
43
+ id: any;
44
+ code: any;
45
+ customer: any;
46
+ type: string;
47
+ value: number;
48
+ currency: string;
49
+ expiryDays: number;
50
+ expiresAt: any;
51
+ rewardEmailEnabled: boolean;
52
+ existing: boolean;
53
+ orderReward?: undefined;
54
+ } | null>;
55
+ export declare function sendPublishedReviewRewardEmail(input: {
56
+ container: ResolveContainer;
57
+ review: Record<string, any>;
58
+ reward: {
59
+ code: string;
60
+ customer: Record<string, any>;
61
+ type: string;
62
+ value: number;
63
+ currency: string;
64
+ expiryDays?: number;
65
+ expiresAt?: unknown;
66
+ rewardEmailEnabled?: boolean;
67
+ };
68
+ }): Promise<{
69
+ skipped: boolean;
70
+ reason: "missing-email";
71
+ locale?: undefined;
72
+ template?: undefined;
73
+ } | {
74
+ skipped: boolean;
75
+ reason: "disabled";
76
+ locale?: undefined;
77
+ template?: undefined;
78
+ } | {
79
+ skipped: boolean;
80
+ locale: string;
81
+ template: string;
82
+ reason?: undefined;
83
+ } | {
84
+ skipped: boolean;
85
+ reason: "provider-disabled";
86
+ locale?: undefined;
87
+ template?: undefined;
88
+ } | {
89
+ skipped: boolean;
90
+ reason: "missing-template";
91
+ locale?: undefined;
92
+ template?: undefined;
93
+ }>;
94
+ export {};
@@ -0,0 +1,124 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isSuspiciousReview = isSuspiciousReview;
4
+ exports.issuePublishedReviewReward = issuePublishedReviewReward;
5
+ exports.sendPublishedReviewRewardEmail = sendPublishedReviewRewardEmail;
6
+ const node_crypto_1 = require("node:crypto");
7
+ const utils_1 = require("@medusajs/framework/utils");
8
+ const customer_email_1 = require("./customer-email");
9
+ const product_review_1 = require("../modules/product-review");
10
+ function isSuspiciousReview(body) {
11
+ const value = body.trim();
12
+ if (value.length < 8)
13
+ return true;
14
+ const links = (value.match(/https?:\/\//gi) || []).length;
15
+ if (links > 1)
16
+ return true;
17
+ if (/(.)\1{7,}/i.test(value))
18
+ return true;
19
+ const words = value.toLowerCase().split(/\s+/).filter(Boolean);
20
+ if (words.length >= 6 && new Set(words).size <= 2)
21
+ return true;
22
+ return false;
23
+ }
24
+ async function issuePublishedReviewReward(input) {
25
+ if (input.review.reward_coupon_code) {
26
+ return { id: input.review.reward_promotion_id || null, code: input.review.reward_coupon_code, existing: true };
27
+ }
28
+ if (input.settings.reward_enabled === false)
29
+ return null;
30
+ if (input.settings.reward_once_per_order !== false && input.review.order_id) {
31
+ const reviewService = input.container.resolve(product_review_1.PRODUCT_REVIEW_MODULE);
32
+ const sameOrder = await reviewService.listProductReviews({ order_id: input.review.order_id, customer_id: input.review.customer_id }, { take: 200 });
33
+ const rewarded = sameOrder.find((review) => review.id !== input.review.id && review.reward_coupon_code);
34
+ if (rewarded) {
35
+ return { id: rewarded.reward_promotion_id || null, code: rewarded.reward_coupon_code, existing: true, orderReward: true };
36
+ }
37
+ }
38
+ const customerService = input.container.resolve(utils_1.Modules.CUSTOMER);
39
+ const promotionService = input.container.resolve(utils_1.Modules.PROMOTION);
40
+ const customer = await customerService.retrieveCustomer(input.review.customer_id);
41
+ if (!customer?.email)
42
+ throw new Error("A kupon kiküldéséhez hiányzik a vevő e-mail címe.");
43
+ const type = input.settings.reward_type === "fixed" ? "fixed" : "percentage";
44
+ const rawValue = Number(input.settings.reward_value ?? (type === "percentage" ? 5 : 2000));
45
+ const value = Number.isFinite(rawValue) && rawValue > 0 ? (type === "percentage" ? Math.min(rawValue, 100) : rawValue) : (type === "percentage" ? 5 : 2000);
46
+ const currency = String(input.settings.reward_currency_code || "huf").trim().toLowerCase() || "huf";
47
+ const rawExpiryDays = Number(input.settings.reward_coupon_expiry_days ?? 30);
48
+ const expiryDays = Number.isFinite(rawExpiryDays) ? Math.max(0, Math.min(3650, Math.trunc(rawExpiryDays))) : 30;
49
+ let campaign = null;
50
+ if (expiryDays > 0) {
51
+ const suffix = (0, node_crypto_1.randomBytes)(6).toString("hex").toUpperCase();
52
+ campaign = await promotionService.createCampaigns({
53
+ name: `Review reward ${input.review.id}`,
54
+ campaign_identifier: `review-reward-${suffix}`,
55
+ description: `Automatikus értékelési jutalom ${input.review.id}`,
56
+ starts_at: new Date(),
57
+ ends_at: new Date(Date.now() + expiryDays * 24 * 60 * 60 * 1000),
58
+ });
59
+ }
60
+ let promotion;
61
+ let lastError;
62
+ for (let attempt = 0; attempt < 3; attempt++) {
63
+ const code = `REVIEW-${(0, node_crypto_1.randomBytes)(5).toString("hex").toUpperCase()}`;
64
+ try {
65
+ promotion = await promotionService.createPromotions({
66
+ code,
67
+ type: "standard",
68
+ status: "active",
69
+ limit: 1,
70
+ ...(campaign?.id ? { campaign_id: campaign.id } : {}),
71
+ application_method: {
72
+ type,
73
+ target_type: "order",
74
+ value,
75
+ ...(type === "fixed" ? { currency_code: currency } : {}),
76
+ },
77
+ rules: [{ attribute: "customer_id", operator: "eq", values: [input.review.customer_id] }],
78
+ });
79
+ break;
80
+ }
81
+ catch (error) {
82
+ lastError = error;
83
+ }
84
+ }
85
+ if (!promotion)
86
+ throw lastError instanceof Error ? lastError : new Error("Az értékelési kupon létrehozása nem sikerült.");
87
+ return {
88
+ id: promotion.id,
89
+ code: promotion.code,
90
+ customer,
91
+ type,
92
+ value,
93
+ currency,
94
+ expiryDays,
95
+ expiresAt: campaign?.ends_at || null,
96
+ rewardEmailEnabled: input.settings.reward_email_enabled !== false,
97
+ existing: false,
98
+ };
99
+ }
100
+ async function sendPublishedReviewRewardEmail(input) {
101
+ if (input.reward.rewardEmailEnabled === false) {
102
+ return { skipped: true, reason: "disabled" };
103
+ }
104
+ return (0, customer_email_1.queueCustomerAccountEmail)({
105
+ container: input.container,
106
+ kind: "review_reward",
107
+ to: input.reward.customer.email,
108
+ resourceId: input.review.customer_id,
109
+ idempotencyKey: `product-review-reward:${input.review.order_id || input.review.id}:${input.reward.code}`,
110
+ data: {
111
+ first_name: input.reward.customer.first_name || "",
112
+ coupon_code: input.reward.code,
113
+ reward_type: input.reward.type,
114
+ reward_value: input.reward.value,
115
+ reward_currency_code: input.reward.currency,
116
+ coupon_expiry_days: input.reward.expiryDays ?? null,
117
+ coupon_expires_at: input.reward.expiresAt ?? null,
118
+ product_id: input.review.product_id,
119
+ review_id: input.review.id,
120
+ order_id: input.review.order_id || null,
121
+ },
122
+ });
123
+ }
124
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmV2aWV3LXJld2FyZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9jb3JlL3Jldmlldy1yZXdhcmQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFpQkEsZ0RBU0M7QUFFRCxnRUFvRkM7QUFFRCx3RUE0QkM7QUE5SUQsNkNBQXlDO0FBQ3pDLHFEQUFtRDtBQUNuRCxxREFBNEQ7QUFDNUQsOERBQTRGO0FBYzVGLFNBQWdCLGtCQUFrQixDQUFDLElBQVk7SUFDN0MsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLElBQUksRUFBRSxDQUFBO0lBQ3pCLElBQUksS0FBSyxDQUFDLE1BQU0sR0FBRyxDQUFDO1FBQUUsT0FBTyxJQUFJLENBQUE7SUFDakMsTUFBTSxLQUFLLEdBQUcsQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLGVBQWUsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDLE1BQU0sQ0FBQTtJQUN6RCxJQUFJLEtBQUssR0FBRyxDQUFDO1FBQUUsT0FBTyxJQUFJLENBQUE7SUFDMUIsSUFBSSxZQUFZLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQztRQUFFLE9BQU8sSUFBSSxDQUFBO0lBQ3pDLE1BQU0sS0FBSyxHQUFHLEtBQUssQ0FBQyxXQUFXLEVBQUUsQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFBO0lBQzlELElBQUksS0FBSyxDQUFDLE1BQU0sSUFBSSxDQUFDLElBQUksSUFBSSxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUMsSUFBSSxJQUFJLENBQUM7UUFBRSxPQUFPLElBQUksQ0FBQTtJQUM5RCxPQUFPLEtBQUssQ0FBQTtBQUNkLENBQUM7QUFFTSxLQUFLLFVBQVUsMEJBQTBCLENBQUMsS0FJaEQ7SUFDQyxJQUFJLEtBQUssQ0FBQyxNQUFNLENBQUMsa0JBQWtCLEVBQUUsQ0FBQztRQUNwQyxPQUFPLEVBQUUsRUFBRSxFQUFFLEtBQUssQ0FBQyxNQUFNLENB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
@@ -0,0 +1,39 @@
1
+ export type RuntimeHealthState = "healthy" | "warning" | "error" | "missing";
2
+ type HeartbeatFile = {
3
+ schema_version?: number;
4
+ job?: string;
5
+ schedule?: string;
6
+ last_seen_at?: string;
7
+ pid?: number;
8
+ };
9
+ export type RuntimeHealthReport = {
10
+ generated_at: string;
11
+ project_root: string;
12
+ scheduler: {
13
+ state: RuntimeHealthState;
14
+ schedule: string;
15
+ last_seen_at: string | null;
16
+ age_minutes: number | null;
17
+ stale_after_minutes: number;
18
+ message: string;
19
+ };
20
+ backup: {
21
+ state: RuntimeHealthState;
22
+ last_attempt_status: "running" | "success" | "failed" | "unknown";
23
+ last_attempt_at: string | null;
24
+ last_success_at: string | null;
25
+ age_hours: number | null;
26
+ stale_after_hours: number;
27
+ bundle_name: string | null;
28
+ size_bytes: number | null;
29
+ database_dump: boolean;
30
+ manifest_ok: boolean;
31
+ error: string | null;
32
+ message: string;
33
+ };
34
+ };
35
+ export declare function resolveRuntimeProjectRoot(env?: NodeJS.ProcessEnv): string;
36
+ export declare function runtimeStateDirectory(env?: NodeJS.ProcessEnv): string;
37
+ export declare function writeRuntimeHeartbeat(env?: NodeJS.ProcessEnv): HeartbeatFile;
38
+ export declare function collectRuntimeHealth(env?: NodeJS.ProcessEnv, now?: Date): RuntimeHealthReport;
39
+ export {};