@hszrdm/core 1.0.3 → 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 (124) hide show
  1. package/.medusa/server/src/admin/index.js +3582 -2374
  2. package/.medusa/server/src/admin/index.mjs +3582 -2374
  3. package/.medusa/server/src/api/admin/cms/entries/[id]/route.d.ts +6 -0
  4. package/.medusa/server/src/api/admin/cms/entries/[id]/route.js +78 -0
  5. package/.medusa/server/src/api/admin/cms/entries/route.d.ts +5 -0
  6. package/.medusa/server/src/api/admin/cms/entries/route.js +77 -0
  7. package/.medusa/server/src/api/admin/cms/taxonomy/[id]/route.d.ts +5 -0
  8. package/.medusa/server/src/api/admin/cms/taxonomy/[id]/route.js +50 -0
  9. package/.medusa/server/src/api/admin/cms/taxonomy/route.d.ts +5 -0
  10. package/.medusa/server/src/api/admin/cms/taxonomy/route.js +60 -0
  11. package/.medusa/server/src/api/admin/core/status/route.d.ts +2 -0
  12. package/.medusa/server/src/api/admin/core/status/route.js +11 -0
  13. package/.medusa/server/src/api/admin/featured-products/[id]/route.d.ts +7 -0
  14. package/.medusa/server/src/api/admin/featured-products/[id]/route.js +54 -0
  15. package/.medusa/server/src/api/admin/leads/[id]/route.d.ts +9 -0
  16. package/.medusa/server/src/api/admin/leads/[id]/route.js +64 -0
  17. package/.medusa/server/src/api/admin/leads/route.d.ts +2 -0
  18. package/.medusa/server/src/api/admin/leads/route.js +26 -0
  19. package/.medusa/server/src/api/admin/quote-requests/[id]/draft-order/route.d.ts +8 -0
  20. package/.medusa/server/src/api/admin/quote-requests/[id]/draft-order/route.js +160 -0
  21. package/.medusa/server/src/api/admin/quote-requests/[id]/order/route.d.ts +2 -0
  22. package/.medusa/server/src/api/admin/quote-requests/[id]/order/route.js +54 -0
  23. package/.medusa/server/src/api/admin/quote-requests/[id]/route.d.ts +5 -0
  24. package/.medusa/server/src/api/admin/quote-requests/[id]/route.js +80 -0
  25. package/.medusa/server/src/api/admin/quote-requests/route.d.ts +2 -0
  26. package/.medusa/server/src/api/admin/quote-requests/route.js +19 -0
  27. package/.medusa/server/src/api/middlewares.js +11 -6
  28. package/.medusa/server/src/api/store/cms/config/route.d.ts +2 -0
  29. package/.medusa/server/src/api/store/cms/config/route.js +17 -0
  30. package/.medusa/server/src/api/store/cms/entries/[slug]/route.d.ts +2 -0
  31. package/.medusa/server/src/api/store/cms/entries/[slug]/route.js +62 -0
  32. package/.medusa/server/src/api/store/cms/entries/route.d.ts +2 -0
  33. package/.medusa/server/src/api/store/cms/entries/route.js +87 -0
  34. package/.medusa/server/src/api/store/cms/taxonomy/route.d.ts +2 -0
  35. package/.medusa/server/src/api/store/cms/taxonomy/route.js +44 -0
  36. package/.medusa/server/src/api/store/core/pricing/variants/[id]/route.d.ts +2 -0
  37. package/.medusa/server/src/api/store/core/pricing/variants/[id]/route.js +152 -0
  38. package/.medusa/server/src/api/store/featured-products/route.d.ts +2 -0
  39. package/.medusa/server/src/api/store/featured-products/route.js +38 -0
  40. package/.medusa/server/src/api/store/leads/config/route.d.ts +2 -0
  41. package/.medusa/server/src/api/store/leads/config/route.js +21 -0
  42. package/.medusa/server/src/api/store/leads/route.d.ts +4 -0
  43. package/.medusa/server/src/api/store/leads/route.js +176 -0
  44. package/.medusa/server/src/api/store/quote-requests/config/route.d.ts +2 -0
  45. package/.medusa/server/src/api/store/quote-requests/config/route.js +13 -0
  46. package/.medusa/server/src/api/store/quote-requests/route.d.ts +5 -0
  47. package/.medusa/server/src/api/store/quote-requests/route.js +214 -0
  48. package/.medusa/server/src/api/store/seo/route.js +42 -10
  49. package/.medusa/server/src/api/store/seo/structured-data/route.js +3 -2
  50. package/.medusa/server/src/config.js +7 -1
  51. package/.medusa/server/src/core/admin-analytics-dashboard.d.ts +1 -0
  52. package/.medusa/server/src/core/admin-analytics-dashboard.js +15 -3
  53. package/.medusa/server/src/core/featured-products.d.ts +19 -0
  54. package/.medusa/server/src/core/featured-products.js +45 -0
  55. package/.medusa/server/src/core/pricing-tiers.d.ts +25 -0
  56. package/.medusa/server/src/core/pricing-tiers.js +88 -0
  57. package/.medusa/server/src/core/release-info.d.ts +10 -0
  58. package/.medusa/server/src/core/release-info.js +22 -0
  59. package/.medusa/server/src/core/version.d.ts +4 -4
  60. package/.medusa/server/src/core/version.js +3 -3
  61. package/.medusa/server/src/lib/modules/arukereso/config.js +2 -2
  62. package/.medusa/server/src/lib/modules/google-merchant/config.d.ts +2 -0
  63. package/.medusa/server/src/lib/modules/google-merchant/config.js +9 -2
  64. package/.medusa/server/src/lib/modules/google-merchant/feed.d.ts +1 -0
  65. package/.medusa/server/src/lib/modules/google-merchant/feed.js +4 -2
  66. package/.medusa/server/src/localized-config.d.ts +9 -0
  67. package/.medusa/server/src/localized-config.js +14 -0
  68. package/.medusa/server/src/modules/cms/config.d.ts +10 -0
  69. package/.medusa/server/src/modules/cms/config.js +50 -0
  70. package/.medusa/server/src/modules/cms/index.d.ts +8 -0
  71. package/.medusa/server/src/modules/cms/index.js +28 -0
  72. package/.medusa/server/src/modules/cms/migrations/Migration20261029170000.d.ts +5 -0
  73. package/.medusa/server/src/modules/cms/migrations/Migration20261029170000.js +27 -0
  74. package/.medusa/server/src/modules/cms/migrations/Migration20261029190000.d.ts +5 -0
  75. package/.medusa/server/src/modules/cms/migrations/Migration20261029190000.js +52 -0
  76. package/.medusa/server/src/modules/cms/models/cms.d.ts +67 -0
  77. package/.medusa/server/src/modules/cms/models/cms.js +64 -0
  78. package/.medusa/server/src/modules/cms/service.d.ts +82 -0
  79. package/.medusa/server/src/modules/cms/service.js +9 -0
  80. package/.medusa/server/src/modules/cms/utils.d.ts +67 -0
  81. package/.medusa/server/src/modules/cms/utils.js +190 -0
  82. package/.medusa/server/src/modules/integration-settings/arukereso-registration.js +2 -2
  83. package/.medusa/server/src/modules/integration-settings/google-merchant-registration.js +6 -2
  84. package/.medusa/server/src/modules/lead/config.d.ts +37 -0
  85. package/.medusa/server/src/modules/lead/config.js +147 -0
  86. package/.medusa/server/src/modules/lead/email.d.ts +17 -0
  87. package/.medusa/server/src/modules/lead/email.js +68 -0
  88. package/.medusa/server/src/modules/lead/index.d.ts +9 -0
  89. package/.medusa/server/src/modules/lead/index.js +27 -0
  90. package/.medusa/server/src/modules/lead/migrations/Migration20261029163000.d.ts +5 -0
  91. package/.medusa/server/src/modules/lead/migrations/Migration20261029163000.js +19 -0
  92. package/.medusa/server/src/modules/lead/models/lead.d.ts +26 -0
  93. package/.medusa/server/src/modules/lead/models/lead.js +53 -0
  94. package/.medusa/server/src/modules/lead/service.d.ts +29 -0
  95. package/.medusa/server/src/modules/lead/service.js +11 -0
  96. package/.medusa/server/src/modules/lead/spam.d.ts +24 -0
  97. package/.medusa/server/src/modules/lead/spam.js +114 -0
  98. package/.medusa/server/src/modules/quote-request/config.d.ts +14 -0
  99. package/.medusa/server/src/modules/quote-request/config.js +52 -0
  100. package/.medusa/server/src/modules/quote-request/email.d.ts +17 -0
  101. package/.medusa/server/src/modules/quote-request/email.js +133 -0
  102. package/.medusa/server/src/modules/quote-request/index.d.ts +8 -0
  103. package/.medusa/server/src/modules/quote-request/index.js +23 -0
  104. package/.medusa/server/src/modules/quote-request/migrations/Migration20261029160000.d.ts +5 -0
  105. package/.medusa/server/src/modules/quote-request/migrations/Migration20261029160000.js +20 -0
  106. package/.medusa/server/src/modules/quote-request/models/quote-request.d.ts +24 -0
  107. package/.medusa/server/src/modules/quote-request/models/quote-request.js +54 -0
  108. package/.medusa/server/src/modules/quote-request/service.d.ts +32 -0
  109. package/.medusa/server/src/modules/quote-request/service.js +12 -0
  110. package/.medusa/server/src/modules/seo/models/seo-page.js +5 -5
  111. package/.medusa/server/src/modules/seo/sitemap.js +44 -10
  112. package/.medusa/server/src/modules/seo/structured-data.d.ts +1 -1
  113. package/.medusa/server/src/modules/seo/structured-data.js +41 -25
  114. package/.medusa/server/src/modules/seo/technical.d.ts +7 -2
  115. package/.medusa/server/src/modules/seo/technical.js +45 -6
  116. package/.medusa/server/src/modules/seo/types.d.ts +2 -0
  117. package/.medusa/server/src/scripts/ensure-locales.d.ts +2 -0
  118. package/.medusa/server/src/scripts/ensure-locales.js +34 -0
  119. package/.medusa/server/src/scripts/ensure-shipping.d.ts +3 -0
  120. package/.medusa/server/src/scripts/ensure-shipping.js +211 -0
  121. package/.medusa/server/src/scripts/verify-bootstrap.js +19 -2
  122. package/.medusa/server/src/subscribers/quote-request-order-placed.d.ts +7 -0
  123. package/.medusa/server/src/subscribers/quote-request-order-placed.js +27 -0
  124. package/package.json +2 -2
@@ -0,0 +1,68 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.leadAdminEmail = leadAdminEmail;
4
+ exports.leadCustomerEmail = leadCustomerEmail;
5
+ exports.leadStatusEmail = leadStatusEmail;
6
+ function leadAdminEmail(lead, brand = "HSZRDM Commerce") {
7
+ const subject = `Új érdeklődő – ${text(lead.name) || text(lead.company) || text(lead.email) || text(lead.id)}`;
8
+ const body = [
9
+ `Új lead érkezett a ${brand} rendszerbe.`,
10
+ "",
11
+ `Űrlap: ${text(lead.form_key) || "—"}`,
12
+ `Azonosító: ${text(lead.id)}`,
13
+ `Név: ${text(lead.name) || "—"}`,
14
+ `Cég: ${text(lead.company) || "—"}`,
15
+ `E-mail: ${text(lead.email) || "—"}`,
16
+ `Telefon: ${text(lead.phone) || "—"}`,
17
+ lead.message ? `Üzenet: ${text(lead.message)}` : "",
18
+ ].filter(Boolean).join("\n");
19
+ return { subject, text: body, html: simpleHtml(body) };
20
+ }
21
+ function leadCustomerEmail(lead, brand = "HSZRDM Commerce") {
22
+ const subject = `Megkaptuk az üzeneted – ${brand}`;
23
+ const body = [
24
+ `Kedves ${text(lead.name) || "Érdeklődő"}!`,
25
+ "",
26
+ "Megkaptuk az üzenetedet, hamarosan jelentkezünk.",
27
+ `Azonosító: ${text(lead.id)}`,
28
+ "",
29
+ brand,
30
+ ].join("\n");
31
+ return { subject, text: body, html: simpleHtml(body) };
32
+ }
33
+ function leadStatusEmail(lead, brand = "HSZRDM Commerce") {
34
+ const labels = {
35
+ contacted: "felvettük veled a kapcsolatot",
36
+ qualified: "feldolgozás alatt",
37
+ won: "sikeresen lezárva",
38
+ lost: "lezárva",
39
+ closed: "lezárva",
40
+ };
41
+ const label = labels[text(lead.status)] || text(lead.status);
42
+ const subject = `Érdeklődés frissítés – ${brand}`;
43
+ const body = [
44
+ `Kedves ${text(lead.name) || "Érdeklődő"}!`,
45
+ "",
46
+ `Az érdeklődésed státusza frissült: ${label}.`,
47
+ `Azonosító: ${text(lead.id)}`,
48
+ "",
49
+ brand,
50
+ ].join("\n");
51
+ return { subject, text: body, html: simpleHtml(body) };
52
+ }
53
+ function simpleHtml(value) {
54
+ return `<div style="font-family:Arial,sans-serif;white-space:pre-line">${escapeHtml(value)}</div>`;
55
+ }
56
+ function escapeHtml(value) {
57
+ return value.replace(/[&<>"']/g, (char) => ({
58
+ "&": "&amp;",
59
+ "<": "&lt;",
60
+ ">": "&gt;",
61
+ '"': "&quot;",
62
+ "'": "&#39;",
63
+ })[char] || char);
64
+ }
65
+ function text(value) {
66
+ return typeof value === "string" ? value.trim() : "";
67
+ }
68
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZW1haWwuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9zcmMvbW9kdWxlcy9sZWFkL2VtYWlsLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBRUEsd0NBY0M7QUFFRCw4Q0FXQztBQUVELDBDQW1CQztBQWhERCxTQUFnQixjQUFjLENBQUMsSUFBYyxFQUFFLEtBQUssR0FBRyxpQkFBaUI7SUFDdEUsTUFBTSxPQUFPLEdBQUcsa0JBQWtCLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQTtJQUM5RyxNQUFNLElBQUksR0FBRztRQUNYLHNCQUFzQixLQUFLLGNBQWM7UUFDekMsRUFBRTtRQUNGLFVBQVUsSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxHQUFHLEVBQUU7UUFDdEMsY0FBYyxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxFQUFFO1FBQzdCLFFBQVEsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxHQUFHLEVBQUU7UUFDaEMsUUFBUSxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLEdBQUcsRUFBRTtRQUNuQyxXQUFXLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksR0FBRyxFQUFFO1FBQ3BDLFlBQVksSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxHQUFHLEVBQUU7UUFDckMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsV0FBVyxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUU7S0FDcEQsQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLENBQUMsSUFBSSxD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
@@ -0,0 +1,9 @@
1
+ import LeadService from "./service";
2
+ export declare const LEAD_MODULE = "lead";
3
+ declare const _default: any;
4
+ export default _default;
5
+ export { LeadService };
6
+ export { LEAD_STATUSES } from "./models/lead";
7
+ export { loadLeadConfig, type LeadConfig, type LeadFieldDefinition, type LeadFormDefinition, } from "./config";
8
+ export { leadAdminEmail, leadCustomerEmail, leadStatusEmail, } from "./email";
9
+ export { assessLeadSpam, checkLeadRateLimit, clientFingerprint, verifyTurnstile, } from "./spam";
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.verifyTurnstile = exports.clientFingerprint = exports.checkLeadRateLimit = exports.assessLeadSpam = exports.leadStatusEmail = exports.leadCustomerEmail = exports.leadAdminEmail = exports.loadLeadConfig = exports.LEAD_STATUSES = exports.LeadService = exports.LEAD_MODULE = void 0;
7
+ const utils_1 = require("@medusajs/framework/utils");
8
+ const service_1 = __importDefault(require("./service"));
9
+ exports.LeadService = service_1.default;
10
+ exports.LEAD_MODULE = "lead";
11
+ exports.default = (0, utils_1.Module)(exports.LEAD_MODULE, {
12
+ service: service_1.default,
13
+ });
14
+ var lead_1 = require("./models/lead");
15
+ Object.defineProperty(exports, "LEAD_STATUSES", { enumerable: true, get: function () { return lead_1.LEAD_STATUSES; } });
16
+ var config_1 = require("./config");
17
+ Object.defineProperty(exports, "loadLeadConfig", { enumerable: true, get: function () { return config_1.loadLeadConfig; } });
18
+ var email_1 = require("./email");
19
+ Object.defineProperty(exports, "leadAdminEmail", { enumerable: true, get: function () { return email_1.leadAdminEmail; } });
20
+ Object.defineProperty(exports, "leadCustomerEmail", { enumerable: true, get: function () { return email_1.leadCustomerEmail; } });
21
+ Object.defineProperty(exports, "leadStatusEmail", { enumerable: true, get: function () { return email_1.leadStatusEmail; } });
22
+ var spam_1 = require("./spam");
23
+ Object.defineProperty(exports, "assessLeadSpam", { enumerable: true, get: function () { return spam_1.assessLeadSpam; } });
24
+ Object.defineProperty(exports, "checkLeadRateLimit", { enumerable: true, get: function () { return spam_1.checkLeadRateLimit; } });
25
+ Object.defineProperty(exports, "clientFingerprint", { enumerable: true, get: function () { return spam_1.clientFingerprint; } });
26
+ Object.defineProperty(exports, "verifyTurnstile", { enumerable: true, get: function () { return spam_1.verifyTurnstile; } });
27
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9zcmMvbW9kdWxlcy9sZWFkL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7OztBQUFBLHFEQUFrRDtBQUNsRCx3REFBbUM7QUFRMUIsc0JBUkYsaUJBQVcsQ0FRRTtBQU5QLFFBQUEsV0FBVyxHQUFHLE1BQU0sQ0FBQTtBQUVqQyxrQkFBZSxJQUFBLGNBQU0sRUFBQyxtQkFBVyxFQUFFO0lBQ2pDLE9BQU8sRUFBRSxpQkFBVztDQUNyQixDQUFDLENBQUE7QUFHRixzQ0FBNkM7QUFBcEMscUdBQUEsYUFBYSxPQUFBO0FBQ3RCLG1DQUtpQjtBQUpmLHdHQUFBLGNBQWMsT0FBQTtBQUtoQixpQ0FJZ0I7QUFIZCx1R0FBQSxjQUFjLE9BQUE7QUFDZCwwR0FBQSxpQkFBaUIsT0FBQTtBQUNqQix3R0FBQSxlQUFlLE9BQUE7QUFFakIsK0JBS2U7QUFKYixzR0FBQSxjQUFjLE9BQUE7QUFDZCwwR0FBQSxrQkFBa0IsT0FBQTtBQUNsQix5R0FBQSxpQkFBaUIsT0FBQTtBQUNqQix1R0FBQSxlQUFlLE9BQUEifQ==
@@ -0,0 +1,5 @@
1
+ import { Migration } from "@medusajs/framework/mikro-orm/migrations";
2
+ export declare class Migration20261029163000 extends Migration {
3
+ up(): Promise<void>;
4
+ down(): Promise<void>;
5
+ }
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Migration20261029163000 = void 0;
4
+ const migrations_1 = require("@medusajs/framework/mikro-orm/migrations");
5
+ class Migration20261029163000 extends migrations_1.Migration {
6
+ async up() {
7
+ this.addSql(`create table if not exists "lead" ("id" text not null, "form_key" text not null, "status" text check ("status" in ('new','contacted','qualified','won','lost','spam','closed')) not null, "name" text null, "email" text null, "phone" text null, "company" text null, "message" text null, "fields" jsonb null, "source" text null, "page_url" text null, "referrer" text null, "utm" jsonb null, "customer_id" text null, "admin_note" text null, "privacy_consent_at" timestamptz null, "privacy_policy_version" text not null, "privacy_policy_url" text null, "privacy_policy_label" text null, "request_fingerprint" text null, "spam_score" integer not null default 0, "spam_reasons" jsonb null, "created_at" timestamptz not null default now(), "updated_at" timestamptz not null default now(), "deleted_at" timestamptz null, constraint "lead_pkey" primary key ("id"));`);
8
+ this.addSql(`create index if not exists "IDX_lead_status_created" on "lead" ("status", "created_at") where deleted_at is null;`);
9
+ this.addSql(`create index if not exists "IDX_lead_form_created" on "lead" ("form_key", "created_at") where deleted_at is null;`);
10
+ this.addSql(`create index if not exists "IDX_lead_email_created" on "lead" ("email", "created_at") where deleted_at is null;`);
11
+ this.addSql(`create index if not exists "IDX_lead_customer" on "lead" ("customer_id") where deleted_at is null;`);
12
+ this.addSql(`create index if not exists "IDX_lead_fingerprint_created" on "lead" ("request_fingerprint", "created_at") where deleted_at is null;`);
13
+ }
14
+ async down() {
15
+ this.addSql(`drop table if exists "lead" cascade;`);
16
+ }
17
+ }
18
+ exports.Migration20261029163000 = Migration20261029163000;
19
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiTWlncmF0aW9uMjAyNjEwMjkxNjMwMDAuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvbW9kdWxlcy9sZWFkL21pZ3JhdGlvbnMvTWlncmF0aW9uMjAyNjEwMjkxNjMwMDAudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEseUVBQW9FO0FBRXBFLE1BQWEsdUJBQXdCLFNBQVEsc0JBQVM7SUFDcEQsS0FBSyxDQUFDLEVBQUU7UUFDTixJQUFJLENBQUMsTUFBTSxDQUFDLHcxQkFBdzFCLENBQUMsQ0FBQTtRQUNyMkIsSUFBSSxDQUFDLE1BQU0sQ0FBQyxtSEFBbUgsQ0FBQyxDQUFBO1FBQ2hJLElBQUksQ0FBQyxNQUFNLENBQUMsbUhBQW1ILENBQUMsQ0FBQTtRQUNoSSxJQUFJLENBQUMsTUFBTSxDQUFDLGlIQUFpSCxDQUFDLENBQUE7UUFDOUgsSUFBSSxDQUFDLE1BQU0sQ0FBQyxvR0FBb0csQ0FBQyxDQUFBO1FBQ2pILElBQUksQ0FBQyxNQUFNLENBQUMscUlBQXFJLENBQUMsQ0FBQTtJQUNwSixDQUFDO0lBRUQsS0FBSyxDQUFDLElBQUk7UUFDUixJQUFJLENBQUMsTUFBTSxDQUFDLHNDQUFzQyxDQUFDLENBQUE7SUFDckQsQ0FBQztDQUNGO0FBYkQsMERBYUMifQ==
@@ -0,0 +1,26 @@
1
+ export declare const LEAD_STATUSES: readonly ["new", "contacted", "qualified", "won", "lost", "spam", "closed"];
2
+ declare const Lead: import("@medusajs/framework/utils").DmlEntity<import("@medusajs/framework/utils").DMLEntitySchemaBuilder<{
3
+ id: import("@medusajs/framework/utils").PrimaryKeyModifier<string, import("@medusajs/framework/utils").IdProperty>;
4
+ form_key: import("@medusajs/framework/utils").TextProperty;
5
+ status: import("@medusajs/framework/utils").EnumProperty<["new", "contacted", "qualified", "won", "lost", "spam", "closed"]>;
6
+ name: import("@medusajs/framework/utils").NullableModifier<string, import("@medusajs/framework/utils").TextProperty>;
7
+ email: import("@medusajs/framework/utils").NullableModifier<string, import("@medusajs/framework/utils").TextProperty>;
8
+ phone: import("@medusajs/framework/utils").NullableModifier<string, import("@medusajs/framework/utils").TextProperty>;
9
+ company: import("@medusajs/framework/utils").NullableModifier<string, import("@medusajs/framework/utils").TextProperty>;
10
+ message: import("@medusajs/framework/utils").NullableModifier<string, import("@medusajs/framework/utils").TextProperty>;
11
+ fields: import("@medusajs/framework/utils").NullableModifier<NoInfer<Record<string, unknown>>, import("@medusajs/framework/utils").JSONProperty<NoInfer<Record<string, unknown>>>>;
12
+ source: import("@medusajs/framework/utils").NullableModifier<string, import("@medusajs/framework/utils").TextProperty>;
13
+ page_url: import("@medusajs/framework/utils").NullableModifier<string, import("@medusajs/framework/utils").TextProperty>;
14
+ referrer: import("@medusajs/framework/utils").NullableModifier<string, import("@medusajs/framework/utils").TextProperty>;
15
+ utm: import("@medusajs/framework/utils").NullableModifier<NoInfer<Record<string, unknown>>, import("@medusajs/framework/utils").JSONProperty<NoInfer<Record<string, unknown>>>>;
16
+ customer_id: import("@medusajs/framework/utils").NullableModifier<string, import("@medusajs/framework/utils").TextProperty>;
17
+ admin_note: import("@medusajs/framework/utils").NullableModifier<string, import("@medusajs/framework/utils").TextProperty>;
18
+ privacy_consent_at: import("@medusajs/framework/utils").NullableModifier<Date, import("@medusajs/framework/utils").DateTimeProperty>;
19
+ privacy_policy_version: import("@medusajs/framework/utils").TextProperty;
20
+ privacy_policy_url: import("@medusajs/framework/utils").NullableModifier<string, import("@medusajs/framework/utils").TextProperty>;
21
+ privacy_policy_label: import("@medusajs/framework/utils").NullableModifier<string, import("@medusajs/framework/utils").TextProperty>;
22
+ request_fingerprint: import("@medusajs/framework/utils").NullableModifier<string, import("@medusajs/framework/utils").TextProperty>;
23
+ spam_score: import("@medusajs/framework/utils").NumberProperty;
24
+ spam_reasons: import("@medusajs/framework/utils").NullableModifier<NoInfer<Record<string, unknown>>, import("@medusajs/framework/utils").JSONProperty<NoInfer<Record<string, unknown>>>>;
25
+ }>, "lead">;
26
+ export default Lead;
@@ -0,0 +1,53 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.LEAD_STATUSES = void 0;
4
+ const utils_1 = require("@medusajs/framework/utils");
5
+ exports.LEAD_STATUSES = [
6
+ "new",
7
+ "contacted",
8
+ "qualified",
9
+ "won",
10
+ "lost",
11
+ "spam",
12
+ "closed",
13
+ ];
14
+ const Lead = utils_1.model.define("lead", {
15
+ id: utils_1.model.id().primaryKey(),
16
+ form_key: utils_1.model.text(),
17
+ status: utils_1.model.enum([
18
+ "new",
19
+ "contacted",
20
+ "qualified",
21
+ "won",
22
+ "lost",
23
+ "spam",
24
+ "closed",
25
+ ]),
26
+ name: utils_1.model.text().nullable(),
27
+ email: utils_1.model.text().nullable(),
28
+ phone: utils_1.model.text().nullable(),
29
+ company: utils_1.model.text().nullable(),
30
+ message: utils_1.model.text().nullable(),
31
+ fields: utils_1.model.json().nullable(),
32
+ source: utils_1.model.text().nullable(),
33
+ page_url: utils_1.model.text().nullable(),
34
+ referrer: utils_1.model.text().nullable(),
35
+ utm: utils_1.model.json().nullable(),
36
+ customer_id: utils_1.model.text().nullable(),
37
+ admin_note: utils_1.model.text().nullable(),
38
+ privacy_consent_at: utils_1.model.dateTime().nullable(),
39
+ privacy_policy_version: utils_1.model.text(),
40
+ privacy_policy_url: utils_1.model.text().nullable(),
41
+ privacy_policy_label: utils_1.model.text().nullable(),
42
+ request_fingerprint: utils_1.model.text().nullable(),
43
+ spam_score: utils_1.model.number().default(0),
44
+ spam_reasons: utils_1.model.json().nullable(),
45
+ }).indexes([
46
+ { on: ["status", "created_at"] },
47
+ { on: ["form_key", "created_at"] },
48
+ { on: ["email", "created_at"] },
49
+ { on: ["customer_id"] },
50
+ { on: ["request_fingerprint", "created_at"] },
51
+ ]);
52
+ exports.default = Lead;
53
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGVhZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3NyYy9tb2R1bGVzL2xlYWQvbW9kZWxzL2xlYWQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEscURBQWlEO0FBRXBDLFFBQUEsYUFBYSxHQUFHO0lBQzNCLEtBQUs7SUFDTCxXQUFXO0lBQ1gsV0FBVztJQUNYLEtBQUs7SUFDTCxNQUFNO0lBQ04sTUFBTTtJQUNOLFFBQVE7Q0FDQSxDQUFBO0FBRVYsTUFBTSxJQUFJLEdBQUcsYUFBSyxDQUFDLE1BQU0sQ0FBQyxNQUFNLEVBQUU7SUFDaEMsRUFBRSxFQUFFLGFBQUssQ0FBQyxFQUFFLEVBQUUsQ0FBQyxVQUFVLEVBQUU7SUFDM0IsUUFBUSxFQUFFLGFBQUssQ0FBQyxJQUFJLEVBQUU7SUFDdEIsTUFBTSxFQUFFLGFBQUssQ0FBQyxJQUFJLENBQUM7UUFDakIsS0FBSztRQUNMLFdBQVc7UUFDWCxXQUFXO1FBQ1gsS0FBSztRQUNMLE1BQU07UUFDTixNQUFNO1FBQ04sUUFBUTtLQUNULENBQUM7SUFDRixJQUFJLEVBQUUsYUFBSyxDQUFDLElBQUksRUFBRSxDQUFDLFFBQVEsRUFBRTtJQUM3QixLQUFLLEVBQUUsYUFBSyxDQUFDLElBQUksRUFBRSxDQUFDLFFBQVEsRUFBRTtJQUM5QixLQUFLLEVBQUUsYUFBSyxDQUFDLElBQUksRUFBRSxDQUFDLFFBQVEsRUFBRTtJQUM5QixPQUFPLEVBQUUsYUFBSyxDQUFDLElBQUksRUFBRSxDQUFDLFFBQVEsRUFBRTtJQUNoQyxPQUFPLEVBQUUsYUFBSyxDQUFDLElBQUksRUFBRSxDQUFDLFFBQVEsRUFBRTtJQUNoQyxNQUFNLEVBQUUsYUFBSyxDQUFDLElBQUksRUFBRSxDQUFDLFFBQVEsRUFBRTtJQUMvQixNQUFNLEVBQUUsYUFBSyxDQUFDLElBQUksRUFBRSxDQUFDLFFBQVEsRUFBRTtJQUMvQixRQUFRLEVBQUUsYUFBSyxDQUFDLElBQUksRUFBRSxDQUFDLFFBQVEsRUFBRTtJQUNqQyxRQUFRLEVBQUUsYUFBSyxDQUFDLElBQUksRUFBRSxDQUFDLFFBQVEsRUFBRTtJQUNqQyxHQUFHLEVBQUUsYUFBSyxDQUFDLElBQUksRUFBRSxDQUFDLFFBQVEsRUFBRTtJQUM1QixXQUFXLEVBQUUsYUFBSyxDQUFDLElBQUksRUFBRSxDQUFDLFFBQVEsRUFBRTtJQUNwQyxVQUFVLEVBQUUsYUFBSyxDQUFDLElBQUksRUFBRSxDQUFDLFFBQVEsRUFBRTtJQUNuQyxrQkFBa0IsRUFBRSxhQUFLLENBQUMsUUFBUSxFQUFFLENBQUMsUUFBUSxFQUFFO0lBQy9DLHNCQUFzQixFQUFFLGFBQUssQ0FBQyxJQUFJLEVBQUU7SUFDcEMsa0JBQWtCLEVBQUUsYUFBSyxDQUFDLElBQUksRUFBRSxDQUFDLFFBQVEsRUFBRTtJQUMzQyxvQkFBb0IsRUFBRSxhQUFLLENBQUMsSUFBSSxFQUFFLENBQUMsUUFBUSxFQUFFO0lBQzdDLG1CQUFtQixFQUFFLGFBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQyxRQUFRLEVBQUU7SUFDNUMsVUFBVSxFQUFFLGFBQUssQ0FBQyxNQUFNLEVBQUUsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDO0lBQ3JDLFlBQVksRUFBRSxhQUFLLENBQUMsSUFBSSxFQUFFLENBQUMsUUFBUSxFQUFFO0NBQ3RDLENBQUMsQ0FBQyxPQUFPLENBQUM7SUFDVCxFQUFFLEVBQUUsRUFBRSxDQUFDLFFBQVEsRUFBRSxZQUFZLENBQUMsRUFBRTtJQUNoQyxFQUFFLEVBQUUsRUFBRSxDQUFDLFVBQVUsRUFBRSxZQUFZLENBQUMsRUFBRTtJQUNsQyxFQUFFLEVBQUUsRUFBRSxDQUFDLE9BQU8sRUFBRSxZQUFZLENBQUMsRUFBRTtJQUMvQixFQUFFLEVBQUUsRUFBRSxDQUFDLGFBQWEsQ0FBQyxFQUFFO0lBQ3ZCLEVBQUUsRUFBRSxFQUFFLENBQUMscUJBQXFCLEVBQUUsWUFBWSxDQUFDLEVBQUU7Q0FDOUMsQ0FBQyxDQUFBO0FBRUYsa0JBQWUsSUFBSSxDQUFBIn0=
@@ -0,0 +1,29 @@
1
+ declare const LeadService_base: import("@medusajs/framework/utils").MedusaServiceReturnType<import("@medusajs/framework/utils").ModelConfigurationsToConfigTemplate<{
2
+ readonly Lead: import("@medusajs/framework/utils").DmlEntity<import("@medusajs/framework/utils").DMLEntitySchemaBuilder<{
3
+ id: import("@medusajs/framework/utils").PrimaryKeyModifier<string, import("@medusajs/framework/utils").IdProperty>;
4
+ form_key: import("@medusajs/framework/utils").TextProperty;
5
+ status: import("@medusajs/framework/utils").EnumProperty<["new", "contacted", "qualified", "won", "lost", "spam", "closed"]>;
6
+ name: import("@medusajs/framework/utils").NullableModifier<string, import("@medusajs/framework/utils").TextProperty>;
7
+ email: import("@medusajs/framework/utils").NullableModifier<string, import("@medusajs/framework/utils").TextProperty>;
8
+ phone: import("@medusajs/framework/utils").NullableModifier<string, import("@medusajs/framework/utils").TextProperty>;
9
+ company: import("@medusajs/framework/utils").NullableModifier<string, import("@medusajs/framework/utils").TextProperty>;
10
+ message: import("@medusajs/framework/utils").NullableModifier<string, import("@medusajs/framework/utils").TextProperty>;
11
+ fields: import("@medusajs/framework/utils").NullableModifier<NoInfer<Record<string, unknown>>, import("@medusajs/framework/utils").JSONProperty<NoInfer<Record<string, unknown>>>>;
12
+ source: import("@medusajs/framework/utils").NullableModifier<string, import("@medusajs/framework/utils").TextProperty>;
13
+ page_url: import("@medusajs/framework/utils").NullableModifier<string, import("@medusajs/framework/utils").TextProperty>;
14
+ referrer: import("@medusajs/framework/utils").NullableModifier<string, import("@medusajs/framework/utils").TextProperty>;
15
+ utm: import("@medusajs/framework/utils").NullableModifier<NoInfer<Record<string, unknown>>, import("@medusajs/framework/utils").JSONProperty<NoInfer<Record<string, unknown>>>>;
16
+ customer_id: import("@medusajs/framework/utils").NullableModifier<string, import("@medusajs/framework/utils").TextProperty>;
17
+ admin_note: import("@medusajs/framework/utils").NullableModifier<string, import("@medusajs/framework/utils").TextProperty>;
18
+ privacy_consent_at: import("@medusajs/framework/utils").NullableModifier<Date, import("@medusajs/framework/utils").DateTimeProperty>;
19
+ privacy_policy_version: import("@medusajs/framework/utils").TextProperty;
20
+ privacy_policy_url: import("@medusajs/framework/utils").NullableModifier<string, import("@medusajs/framework/utils").TextProperty>;
21
+ privacy_policy_label: import("@medusajs/framework/utils").NullableModifier<string, import("@medusajs/framework/utils").TextProperty>;
22
+ request_fingerprint: import("@medusajs/framework/utils").NullableModifier<string, import("@medusajs/framework/utils").TextProperty>;
23
+ spam_score: import("@medusajs/framework/utils").NumberProperty;
24
+ spam_reasons: import("@medusajs/framework/utils").NullableModifier<NoInfer<Record<string, unknown>>, import("@medusajs/framework/utils").JSONProperty<NoInfer<Record<string, unknown>>>>;
25
+ }>, "lead">;
26
+ }>>;
27
+ declare class LeadService extends LeadService_base {
28
+ }
29
+ export default LeadService;
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const utils_1 = require("@medusajs/framework/utils");
7
+ const lead_1 = __importDefault(require("./models/lead"));
8
+ class LeadService extends (0, utils_1.MedusaService)({ Lead: lead_1.default }) {
9
+ }
10
+ exports.default = LeadService;
11
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3NyYy9tb2R1bGVzL2xlYWQvc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUFBLHFEQUF5RDtBQUN6RCx5REFBZ0M7QUFFaEMsTUFBTSxXQUFZLFNBQVEsSUFBQSxxQkFBYSxFQUFDLEVBQUUsSUFBSSxFQUFKLGNBQUksRUFBRSxDQUFDO0NBQUc7QUFFcEQsa0JBQWUsV0FBVyxDQUFBIn0=
@@ -0,0 +1,24 @@
1
+ export type SpamAssessment = {
2
+ score: number;
3
+ reasons: string[];
4
+ spam: boolean;
5
+ };
6
+ type RateLimitInput = {
7
+ fingerprint: string | null;
8
+ email?: string | null;
9
+ max: number;
10
+ windowSeconds: number;
11
+ };
12
+ export declare function clientFingerprint(headers: Record<string, unknown>, secret?: string): string | null;
13
+ export declare function assessLeadSpam(input: {
14
+ honeypotValue?: unknown;
15
+ formStartedAt?: unknown;
16
+ now?: number;
17
+ }): SpamAssessment;
18
+ export declare function checkLeadRateLimit(input: RateLimitInput): Promise<boolean>;
19
+ export declare function verifyTurnstile(input: {
20
+ token?: string | null;
21
+ secretKey?: string | null;
22
+ remoteIp?: string | null;
23
+ }): Promise<boolean>;
24
+ export {};
@@ -0,0 +1,114 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.clientFingerprint = clientFingerprint;
7
+ exports.assessLeadSpam = assessLeadSpam;
8
+ exports.checkLeadRateLimit = checkLeadRateLimit;
9
+ exports.verifyTurnstile = verifyTurnstile;
10
+ const node_crypto_1 = require("node:crypto");
11
+ const ioredis_1 = __importDefault(require("ioredis"));
12
+ const memoryCounters = new Map();
13
+ let redis;
14
+ function clientFingerprint(headers, secret = process.env.LEAD_SPAM_HASH_SECRET || process.env.COOKIE_SECRET || "hszrdm-lead") {
15
+ const raw = firstHeader(headers["cf-connecting-ip"]) || firstHeader(headers["x-forwarded-for"])?.split(",")[0]?.trim() || firstHeader(headers["x-real-ip"]);
16
+ if (!raw)
17
+ return null;
18
+ return (0, node_crypto_1.createHmac)("sha256", secret).update(raw).digest("hex");
19
+ }
20
+ function assessLeadSpam(input) {
21
+ const reasons = [];
22
+ let score = 0;
23
+ if (typeof input.honeypotValue === "string" && input.honeypotValue.trim()) {
24
+ score += 100;
25
+ reasons.push("honeypot");
26
+ }
27
+ const started = typeof input.formStartedAt === "string" || typeof input.formStartedAt === "number"
28
+ ? new Date(input.formStartedAt).getTime()
29
+ : NaN;
30
+ const now = input.now ?? Date.now();
31
+ if (Number.isFinite(started) && now - started >= 0 && now - started < 1500) {
32
+ score += 30;
33
+ reasons.push("too_fast");
34
+ }
35
+ return { score, reasons, spam: score >= 100 };
36
+ }
37
+ async function checkLeadRateLimit(input) {
38
+ const identities = [
39
+ input.fingerprint ? `ip:${input.fingerprint}` : null,
40
+ input.email ? `email:${(0, node_crypto_1.createHash)("sha256").update(input.email.trim().toLowerCase()).digest("hex")}` : null,
41
+ ].filter((value) => Boolean(value));
42
+ for (const identity of identities) {
43
+ const allowed = await increment(identity, input.max, input.windowSeconds);
44
+ if (!allowed)
45
+ return false;
46
+ }
47
+ return true;
48
+ }
49
+ async function verifyTurnstile(input) {
50
+ if (!input.secretKey)
51
+ return true;
52
+ if (!input.token)
53
+ return false;
54
+ const body = new URLSearchParams({ secret: input.secretKey, response: input.token });
55
+ if (input.remoteIp)
56
+ body.set("remoteip", input.remoteIp);
57
+ const response = await fetch("https://challenges.cloudflare.com/turnstile/v0/siteverify", {
58
+ method: "POST",
59
+ headers: { "content-type": "application/x-www-form-urlencoded" },
60
+ body,
61
+ signal: AbortSignal.timeout(8000),
62
+ });
63
+ if (!response.ok)
64
+ return false;
65
+ const payload = await response.json();
66
+ return payload.success === true;
67
+ }
68
+ function firstHeader(value) {
69
+ if (Array.isArray(value))
70
+ return value.length ? String(value[0]) : null;
71
+ if (typeof value === "string")
72
+ return value;
73
+ return null;
74
+ }
75
+ async function increment(identity, max, windowSeconds) {
76
+ const redisClient = getRedis();
77
+ const key = `hszrdm:lead-rate:${identity}`;
78
+ if (redisClient) {
79
+ try {
80
+ const count = await redisClient.incr(key);
81
+ if (count === 1)
82
+ await redisClient.expire(key, windowSeconds);
83
+ return count <= max;
84
+ }
85
+ catch {
86
+ // Fall back to the local process counter when Redis is unavailable.
87
+ }
88
+ }
89
+ const now = Date.now();
90
+ const current = memoryCounters.get(key);
91
+ if (!current || current.expiresAt <= now) {
92
+ memoryCounters.set(key, { count: 1, expiresAt: now + windowSeconds * 1000 });
93
+ return true;
94
+ }
95
+ current.count += 1;
96
+ return current.count <= max;
97
+ }
98
+ function getRedis() {
99
+ if (redis !== undefined)
100
+ return redis;
101
+ const url = process.env.REDIS_URL?.trim();
102
+ if (!url) {
103
+ redis = null;
104
+ return redis;
105
+ }
106
+ redis = new ioredis_1.default(url, {
107
+ lazyConnect: true,
108
+ maxRetriesPerRequest: 1,
109
+ enableOfflineQueue: false,
110
+ });
111
+ redis.connect().catch(() => undefined);
112
+ return redis;
113
+ }
114
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3BhbS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3NyYy9tb2R1bGVzL2xlYWQvc3BhbS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQW1CQSw4Q0FJQztBQUVELHdDQW9CQztBQUVELGdEQVdDO0FBRUQsMENBa0JDO0FBOUVELDZDQUFvRDtBQUNwRCxzREFBMkI7QUFlM0IsTUFBTSxjQUFjLEdBQUcsSUFBSSxHQUFHLEVBQWdELENBQUE7QUFDOUUsSUFBSSxLQUErQixDQUFBO0FBRW5DLFNBQWdCLGlCQUFpQixDQUFDLE9BQWdDLEVBQUUsTUFBTSxHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMscUJBQXFCLElBQUksT0FBTyxDQUFDLEdBQUcsQ0FBQyxhQUFhLElBQUksYUFBYTtJQUMxSixNQUFNLEdBQUcsR0FBRyxXQUFXLENBQUMsT0FBTyxDQUFDLGtCQUFrQixDQUFDLENBQUMsSUFBSSxXQUFXLENBQUMsT0FBTyxDQUFDLGlCQUFpQixDQUFDLENBQUMsRUFBRSxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsSUFBSSxFQUFFLElBQUksV0FBVyxDQUFDLE9BQU8sQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFBO0lBQzNKLElBQUksQ0FBQyxHQUFHO1FBQUUsT0FBTyxJQUFJLENBQUE7SUFDckIsT0FBTyxJQUFBLHdCQUFVLEVBQUMsUUFBUSxFQUFFLE1BQU0sQ0FBQyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUE7QUFDL0QsQ0FBQztBQUVELFNBQWdCLGNBQWMsQ0FBQyxLQUk5QjtJQUNDLE1BQU0sT0FBTyxHQUFhLEVBQUUsQ0FBQTtJQUM1QixJQUFJLEtBQUssR0FBRyxDQUFDLENBQUE7SUFDYixJQUFJLE9BQU8sS0FBSyxDQUFDLGFBQWEsS0FBSyxRQUFRLElBQUksS0FBSyxDQUFDLGFBQWEsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDO1FBQzFFLEtBQUssSUFBSSxHQUFHLENBQUE7UUFDWixPQUFPLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFBO0lBQzFCLENBQUM7SUFDRCxNQUFNLE9BQU8sR0FBRyxPQUFPLEtBQUssQ0FBQyxhQUFhLEtBQUssUUFBUSxJQUFJLE9BQU8sS0FBSyxDQUFDLGFBQWEsS0FBSyxRQUFRO1FBQ2hHLENBQUMsQ0FBQyxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsYUFBYSxDQUFDLENBQUMsT0FBTyxFQUFFO1FBQ3pDLENBQUMsQ0FBQyxHQUFHLENBQUE7SUFDUCxNQUFNLEdBQUcsR0FBRyxLQUFLLENBQUMsR0FBRyxJQUFJLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQTtJQUNuQyxJQUFJLE1BQU0sQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLElBQUksR0FBRyxHQUFHLE9BQU8sSUFBSSxDQUFDLElBQUksR0FBRyxHQUFHLE9BQU8sR0FBRyxJQUFJLEVBQUUsQ0FBQztRQUMzRSxLQUFLLElBQUksRUFBRSxDQUFBO1FBQ1gsT0FBTyxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQTtJQUMxQixDQUFDO0lBQ0QsT0FBTyxFQUFFLEtBQUssRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLEtBQUssSUFBSSxHQUFHLEVBQUUsQ0FBQTtBQUMvQyxDQUFDO0FBRU0sS0FBSyxVQUFVLGtCQUFrQixDQUFDLEtBQXFCO0lBQzVELE1BQU0sVUFBVSxHQUFHO1FBQ2pCLEtBQUssQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLE1BQU0sS0FBSyxDQUFDLFdBQVcsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJO1FBQ3BELEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLFNBQVMsSUFBQSx3QkFBVSxFQUFDLFFBQVEsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLElBQUksRUFBRSxDQUFDLFdBQVcsRUFBRSxDQUFDLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUk7S0FDNUcsQ0FBQyxNQUFNLENBQUMsQ0FBQyxLQUFLLEVBQW1CLEVBQUUsQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQTtJQUVwRCxLQUFLLE1BQU0sUUFBUSxJQUFJLFVBQVUsRUFBRSxDQUFDO1FBQ2xDLE1BQU0sT0FBTyxHQUFHLE1BQU0sU0FBUyxDQUFDLFFBQVEsRUFBRSxLQUFLLENBQUMsR0FBRyxFQUFFLEtBQUssQ0FBQyxhQUFhLENBQUMsQ0FBQTtRQUN6RSxJQUFJLENBQUMsT0FBTztZQUFFLE9BQU8sS0FBSyxDQUFBO0lBQzVCLENBQUM7SUFDRCxPQUFPLElBQUksQ0FBQTtBQUNiLENBQUM7QUFFTSxLQUFLLFVBQVUsZUFBZSxDQUFDLEtBSXJDO0lBQ0MsSUFBSSxDQUFDLEtBQUssQ0FBQyxTQUFTO1FBQUUsT0FBTyxJQUFJLENBQUE7SUFDakMsSUFBSSxDQUFDLEtBQUssQ0FBQyxLQUFLO1FBQUUsT0FBTyxLQUFLLENBQUE7SUFDOUIsTUFBTSxJQUFJLEdBQUcsSUFBSSxlQUFlLENBQUMsRUFBRSxNQUFNLEVBQUUsS0FBSyxDQUFDLFNBQVMsRUFBRSxRQUFRLEVBQUUsS0FBSyxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUE7SUFDcEYsSUFBSSxLQUFLLENBQUMsUUFBUTtRQUFFLElBQUksQ0FBQyxHQUFHLENBQUMsVUFBVSxFQUFFLEtBQUssQ0FBQyxRQUFRLENBQUMsQ0FBQTtJQUN4RCxNQUFNLFFBQVEsR0FBRyxNQUFNLEtBQUssQ0FBQywyREFBMkQsRUFBRTtRQUN4RixNQUFNLEVBQUUsTUFBTTtRQUNkLE9BQU8sRUFBRSxFQUFFLGNBQWMsRUFBRSxtQ0FBbUMsRUFBRTtRQUNoRSxJQUFJO1FBQ0osTUFBTSxFQUFFLFdBQVcsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDO0tBQ2xDLENBQUMsQ0FBQTtJQUNGLElBQUksQ0FBQyxRQUFRLENBQUMsRUFBRTtRQUFFLE9BQU8sS0FBSyxDQUFBO0lBQzlCLE1BQU0sT0FBTyxHQUFHLE1BQU0sUUFBUSxDQUFDLElBQUksRUFBMkIsQ0FBQTtJQUM5RCxPQUFPLE9BQU8sQ0FBQyxPQUFPLEtBQUssSUFBSSxDQUFBO0FBQ2pDLENBQUM7QUFFRCxTQUFTLFdBQVcsQ0FBQyxLQUFjO0lBQ2pDLElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUM7UUFBRSxPQUFPLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFBO0lBQ3ZFLElBQUksT0FBTyxLQUFLLEtBQUssUUFBUTtRQUFFLE9BQU8sS0FBSyxDQUFBO0lBQzNDLE9BQU8sSUFBSSxDQUFBO0FBQ2IsQ0FBQztBQUVELEtBQUssVUFBVSxTQUFTLENBQUMsUUFBZ0IsRUFBRSxHQUFXLEVBQUUsYUFBcUI7SUFDM0UsTUFBTSxXQUFXLEdBQUcsUUFBUSxFQUFFLENBQUE7SUFDOUIsTUFBTSxHQUFHLEdBQUcsb0JBQW9CLFFBQVEsRUFBRSxDQUFBO0lBQzFDLElBQUksV0FBVyxFQUFFLENBQUM7UUFDaEIsSUFBSSxDQUFDO1lBQ0gsTUFBTSxLQUFLLEdBQUcsTUFBTSxXQUFXLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFBO1lBQ3pDLElBQUksS0FBSyxLQUFLLENBQUM7Z0JBQUUsTUFBTSxXQUFXLENBQUMsTUFBTSxDQUFDLEdBQUcsRUFBRSxhQUFhLENBQUMsQ0FBQTtZQUM3RCxPQUFPLEtBQUssSUFBSSxHQUFHLENBQUE7UUFDckIsQ0FBQztRQUFDLE1BQU0sQ0FBQztZQUNQLG9FQUFvRTtRQUN0RSxDQUFDO0lBQ0gsQ0FBQztJQUVELE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQTtJQUN0QixNQUFNLE9BQU8sR0FBRyxjQUFjLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFBO0lBQ3ZDLElBQUksQ0FBQyxPQUFPLElBQUksT0FBTyxDQUFDLFNBQVMsSUFBSSxHQUFHLEVBQUUsQ0FBQztRQUN6QyxjQUFjLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxFQUFFLEtBQUssRUFBRSxDQUFDLEVBQUUsU0FBUyxFQUFFLEdBQUcsR0FBRyxhQUFhLEdBQUcsSUFBSSxFQUFFLENBQUMsQ0FBQTtRQUM1RSxPQUFPLElBQUksQ0FBQTtJQUNiLENBQUM7SUFDRCxPQUFPLENBQUMsS0FBSyxJQUFJLENBQUMsQ0FBQTtJQUNsQixPQUFPLE9BQU8sQ0FBQyxLQUFLLElBQUksR0FBRyxDQUFBO0FBQzdCLENBQUM7QUFFRCxTQUFTLFFBQVE7SUFDZixJQUFJLEtBQUssS0FBSyxTQUFTO1FBQUUsT0FBTyxLQUFLLENBQUE7SUFDckMsTUFBTSxHQUFHLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FBQyxTQUFTLEVBQUUsSUFBSSxFQUFFLENBQUE7SUFDekMsSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDO1FBQ1QsS0FBSyxHQUFHLElBQUksQ0FBQTtRQUNaLE9BQU8sS0FBSyxDQUFBO0lBQ2QsQ0FBQztJQUNELEtBQUssR0FBRyxJQUFJLGlCQUFLLENBQUMsR0FBRyxFQUFFO1FBQ3JCLFdBQVcsRUFBRSxJQUFJO1FBQ2pCLG9CQUFvQixFQUFFLENBQUM7UUFDdkIsa0JBQWtCLEVBQUUsS0FBSztLQUMxQixDQUFDLENBQUE7SUFDRixLQUFLLENBQUMsT0FBTyxFQUFFLENBQUMsS0FBSyxDQUFDLEdBQUcsRUFBRSxDQUFDLFNBQVMsQ0FBQyxDQUFBO0lBQ3RDLE9BQU8sS0FBSyxDQUFBO0FBQ2QsQ0FBQyJ9
@@ -0,0 +1,14 @@
1
+ export type QuoteExtraFieldDefinition = {
2
+ key: string;
3
+ label: string;
4
+ type: "text" | "textarea" | "number" | "boolean" | "select";
5
+ required: boolean;
6
+ options?: string[];
7
+ };
8
+ export type QuoteRequestConfig = {
9
+ enabled: boolean;
10
+ emailEnabled: boolean;
11
+ adminEmails: string[];
12
+ extraFields: QuoteExtraFieldDefinition[];
13
+ };
14
+ export declare function loadQuoteRequestConfig(env?: NodeJS.ProcessEnv): QuoteRequestConfig;
@@ -0,0 +1,52 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.loadQuoteRequestConfig = loadQuoteRequestConfig;
4
+ function loadQuoteRequestConfig(env = process.env) {
5
+ return {
6
+ enabled: env.QUOTE_REQUESTS_ENABLED !== "false",
7
+ emailEnabled: env.QUOTE_EMAIL_ENABLED !== "false",
8
+ adminEmails: splitEmails(env.QUOTE_ADMIN_EMAILS || env.QUOTE_ADMIN_EMAIL || ""),
9
+ extraFields: parseExtraFields(env.QUOTE_EXTRA_FIELDS_JSON),
10
+ };
11
+ }
12
+ function splitEmails(value) {
13
+ return [...new Set(value.split(/[;,]/).map((email) => email.trim()).filter(Boolean))];
14
+ }
15
+ function parseExtraFields(raw) {
16
+ if (!raw?.trim())
17
+ return [];
18
+ try {
19
+ const parsed = JSON.parse(raw);
20
+ if (!Array.isArray(parsed))
21
+ return [];
22
+ return parsed.flatMap((value) => {
23
+ if (!value || typeof value !== "object" || Array.isArray(value))
24
+ return [];
25
+ const row = value;
26
+ const key = text(row.key);
27
+ const label = text(row.label) || key;
28
+ const type = text(row.type);
29
+ if (!key || !/^[a-zA-Z0-9_.-]{1,80}$/.test(key))
30
+ return [];
31
+ if (!["text", "textarea", "number", "boolean", "select"].includes(type))
32
+ return [];
33
+ const options = Array.isArray(row.options)
34
+ ? row.options.map(text).filter(Boolean).slice(0, 100)
35
+ : undefined;
36
+ return [{
37
+ key,
38
+ label: label.slice(0, 160),
39
+ type: type,
40
+ required: row.required === true,
41
+ ...(options?.length ? { options } : {}),
42
+ }];
43
+ }).slice(0, 50);
44
+ }
45
+ catch {
46
+ return [];
47
+ }
48
+ }
49
+ function text(value) {
50
+ return typeof value === "string" ? value.trim() : "";
51
+ }
52
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uZmlnLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vc3JjL21vZHVsZXMvcXVvdGUtcmVxdWVzdC9jb25maWcudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFlQSx3REFTQztBQVRELFNBQWdCLHNCQUFzQixDQUNwQyxNQUF5QixPQUFPLENBQUMsR0FBRztJQUVwQyxPQUFPO1FBQ0wsT0FBTyxFQUFFLEdBQUcsQ0FBQyxzQkFBc0IsS0FBSyxPQUFPO1FBQy9DLFlBQVksRUFBRSxHQUFHLENBQUMsbUJBQW1CLEtBQUssT0FBTztRQUNqRCxXQUFXLEVBQUUsV0FBVyxDQUFDLEdBQUcsQ0FBQyxrQkFBa0IsSUFBSSxHQUFHLENBQUMsaUJBQWlCLElBQUksRUFBRSxDQUFDO1FBQy9FLFdBQVcsRUFBRSxnQkFBZ0IsQ0FBQyxHQUFHLENBQUMsdUJBQXVCLENBQUM7S0FDM0QsQ0FBQTtBQUNILENBQUM7QUFFRCxTQUFTLFdBQVcsQ0FBQyxLQUFhO0lBQ2hDLE9BQU8sQ0FBQyxHQUFHLElBQUksR0FBRyxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxLQUFLLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFBO0FBQ3ZGLENBQUM7QUFFRCxTQUFTLGdCQUFnQixDQUFDLEdBQXVCO0lBQy9DLElBQUksQ0FBQyxHQUFHLEVBQUUsSUFBSSxFQUFFO1FBQUUsT0FBTyxFQUFFLENBQUE7SUFDM0IsSUFBSSxDQUFDO1FBQ0gsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQTtRQUM5QixJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUM7WUFBRSxPQUFPLEVBQUUsQ0FBQTtRQUNyQyxPQUFPLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQyxLQUFLLEVBQStCLEVBQUU7WUFDM0QsSUFBSSxDQUFDLEtBQUssSUFBSSxPQUFPLEtBQUssS0FBSyxRQUFRLElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUM7Z0JBQUUsT0FBTyxFQUFFLENBQUE7WUFDMUUsTUFBTSxHQUFHLEdBQUcsS0FBZ0MsQ0FBQTtZQUM1QyxNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFBO1lBQ3pCLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLElBQUksR0FBRyxDQUFBO1lBQ3BDLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUE7WUFDM0IsSUFBSSxDQUFDLEdBQUcsSUFBSSxDQUFDLHdCQUF3QixDQUFDLElBQUksQ0FBQyxHQUFHLENBQUM7Z0JBQUUsT0FBTyxFQUFFLENBQUE7WUFDMUQsSUFBSSxDQUFDLENBQUMsTUFBTSxFQUFFLFVBQVUsRUFBRSxRQUFRLEVBQUUsU0FBUyxFQUFFLFFBQVEsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUM7Z0JBQUUsT0FBTyxFQUFFLENBQUE7WUFDbEYsTUFBTSxPQUFPLEdBQUcsS0FBSyxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDO2dCQUN4QyxDQUFDLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsR0FBRyxDQUFDO2dCQUNyRCxDQUFDLENBQUMsU0FBUyxDQUFBO1lBQ2IsT0FBTyxDQUFDO29CQUNOLEdBQUc7b0JBQ0gsS0FBSyxFQUFFLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLEdBQUcsQ0FBQztvQkFDMUIsSUFBSSxFQUFFLElBQXlDO29CQUMvQyxRQUFRLEVBQUUsR0FBRyxDQUFDLFFBQVEsS0FBSyxJQUFJO29CQUMvQixHQUFHLENBQUMsT0FBTyxFQUFFLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxPQUFPLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO2lCQUN4QyxDQUFDLENBQUE7UUFDSixDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFBO0lBQ2pCLENBQUM7SUFBQyxNQUFNLENBQUM7UUFDUCxPQUFPLEVBQUUsQ0FBQTtJQUNYLENBQUM7QUFDSCxDQUFDO0FBRUQsU0FBUyxJQUFJLENBQUMsS0FBYztJQUMxQixPQUFPLE9BQU8sS0FBSyxLQUFLLFFBQVEsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUE7QUFDdEQsQ0FBQyJ9
@@ -0,0 +1,17 @@
1
+ type QuoteLike = Record<string, any>;
2
+ export declare function quoteRequestCreatedEmail(quote: QuoteLike, brand?: string): {
3
+ subject: string;
4
+ text: string;
5
+ html: string;
6
+ };
7
+ export declare function quoteRequestAdminEmail(quote: QuoteLike, brand?: string): {
8
+ subject: string;
9
+ text: string;
10
+ html: string;
11
+ };
12
+ export declare function quoteRequestStatusEmail(quote: QuoteLike, brand?: string): {
13
+ subject: string;
14
+ text: string;
15
+ html: string;
16
+ };
17
+ export {};