@lodashventure/medusa-parcel-shipping 0.2.13 → 0.3.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 (128) hide show
  1. package/.medusa/server/src/admin/index.js +1787 -1278
  2. package/.medusa/server/src/admin/index.mjs +1790 -1279
  3. package/.medusa/server/src/api/admin/boxes/[id]/route.js +52 -0
  4. package/.medusa/server/src/api/admin/boxes/route.js +44 -0
  5. package/.medusa/server/src/api/admin/distance/route.js +75 -0
  6. package/.medusa/server/src/api/admin/documents/document-packing-slip-settings/route.js +65 -0
  7. package/.medusa/server/{api → src/api}/admin/documents/packing-slip/preview/route.js +1 -1
  8. package/.medusa/server/{api → src/api}/admin/documents/packing-slip/route.js +2 -2
  9. package/.medusa/server/src/api/admin/material-costs/[id]/route.js +51 -0
  10. package/.medusa/server/src/api/admin/material-costs/route.js +46 -0
  11. package/.medusa/server/src/api/admin/packaging-materials/[id]/route.js +50 -0
  12. package/.medusa/server/src/api/admin/packaging-materials/route.js +52 -0
  13. package/.medusa/server/src/api/admin/packing-policies/[id]/route.js +41 -0
  14. package/.medusa/server/src/api/admin/packing-policies/route.js +43 -0
  15. package/.medusa/server/src/api/admin/rates/[id]/route.js +8 -0
  16. package/.medusa/server/src/api/admin/rates/route.js +7 -0
  17. package/.medusa/server/src/api/admin/service-areas/[id]/route.js +36 -0
  18. package/.medusa/server/src/api/admin/service-areas/route.js +40 -0
  19. package/.medusa/server/src/api/admin/shipping-rates/[id]/route.js +48 -0
  20. package/.medusa/server/src/api/admin/shipping-rates/route.js +66 -0
  21. package/.medusa/server/src/api/store/distance/route.js +75 -0
  22. package/.medusa/server/src/api/store/quote/route.js +116 -0
  23. package/.medusa/server/{common → src/common}/types.js +1 -1
  24. package/.medusa/server/src/common/utils/distance-calculator.js +98 -0
  25. package/.medusa/server/src/common/utils/geocoding.js +125 -0
  26. package/.medusa/server/{common → src/common}/utils/osrm-client.js +1 -1
  27. package/.medusa/server/src/common/utils/packing.js +484 -0
  28. package/.medusa/server/src/index.js +38 -0
  29. package/.medusa/server/{links → src/links}/index.js +1 -1
  30. package/.medusa/server/{links → src/links}/packing-slip-order.js +1 -1
  31. package/.medusa/server/{modules → src/modules}/documents/index.js +1 -1
  32. package/.medusa/server/{modules → src/modules}/documents/models/document-invoice.js +1 -1
  33. package/.medusa/server/{modules → src/modules}/documents/models/document-packing-slip-settings.js +1 -1
  34. package/.medusa/server/{modules → src/modules}/documents/models/document-packing-slip.js +1 -1
  35. package/.medusa/server/{modules → src/modules}/documents/models/document-settings.js +1 -1
  36. package/.medusa/server/{modules → src/modules}/documents/models/index.js +1 -1
  37. package/.medusa/server/{modules → src/modules}/documents/service.js +1 -1
  38. package/.medusa/server/{modules → src/modules}/documents/services/generators/invoice-generator.js +1 -1
  39. package/.medusa/server/{modules → src/modules}/documents/services/generators/packing-slip-generator.js +1 -1
  40. package/.medusa/server/{modules → src/modules}/documents/services/templates/invoices/basic/basic-logo.js +1 -1
  41. package/.medusa/server/{modules → src/modules}/documents/services/templates/invoices/basic/basic.js +1 -1
  42. package/.medusa/server/src/modules/documents/services/templates/invoices/basic/parts/customer-info.js +69 -0
  43. package/.medusa/server/{modules → src/modules}/documents/services/templates/invoices/basic/parts/header-for-logo.js +1 -1
  44. package/.medusa/server/{modules → src/modules}/documents/services/templates/invoices/basic/parts/header-logo.js +1 -1
  45. package/.medusa/server/src/modules/documents/services/templates/invoices/basic/parts/header.js +35 -0
  46. package/.medusa/server/{modules → src/modules}/documents/services/templates/invoices/basic/parts/hr.js +1 -1
  47. package/.medusa/server/{modules → src/modules}/documents/services/templates/invoices/basic/parts/invoice-info.js +1 -1
  48. package/.medusa/server/src/modules/documents/services/templates/invoices/basic/parts/table.js +97 -0
  49. package/.medusa/server/{modules → src/modules}/documents/services/templates/packing-slips/basic/basic.js +1 -1
  50. package/.medusa/server/src/modules/documents/services/templates/packing-slips/basic/parts/customer-info-small.js +69 -0
  51. package/.medusa/server/src/modules/documents/services/templates/packing-slips/basic/parts/customer-info.js +65 -0
  52. package/.medusa/server/src/modules/documents/services/templates/packing-slips/basic/parts/header-small.js +37 -0
  53. package/.medusa/server/src/modules/documents/services/templates/packing-slips/basic/parts/header.js +37 -0
  54. package/.medusa/server/{modules → src/modules}/documents/services/templates/packing-slips/basic/parts/hr.js +1 -1
  55. package/.medusa/server/src/modules/documents/services/templates/packing-slips/basic/parts/table-items-small.js +44 -0
  56. package/.medusa/server/src/modules/documents/services/templates/packing-slips/basic/parts/table-items.js +44 -0
  57. package/.medusa/server/src/modules/documents/services/templates/packing-slips/basic/parts/table-order-info-small.js +35 -0
  58. package/.medusa/server/{modules → src/modules}/documents/services/templates/packing-slips/basic/parts/table-order-info.js +1 -1
  59. package/.medusa/server/{modules → src/modules}/documents/services/templates/packing-slips/basic/small.js +1 -1
  60. package/.medusa/server/{modules → src/modules}/documents/types/api.js +1 -1
  61. package/.medusa/server/{modules → src/modules}/documents/types/constants.js +1 -1
  62. package/.medusa/server/{modules → src/modules}/documents/types/dto.js +1 -1
  63. package/.medusa/server/{modules → src/modules}/documents/types/template-kind.js +1 -1
  64. package/.medusa/server/{modules → src/modules}/documents/utils/currency.js +1 -1
  65. package/.medusa/server/src/modules/parcel-shipping/index.js +13 -0
  66. package/.medusa/server/src/modules/parcel-shipping/migrations/Migration20251023000000.js +37 -0
  67. package/.medusa/server/src/modules/parcel-shipping/models/index.js +16 -0
  68. package/.medusa/server/src/modules/parcel-shipping/models/material-cost.js +24 -0
  69. package/.medusa/server/src/modules/parcel-shipping/models/packaging-material.js +41 -0
  70. package/.medusa/server/src/modules/parcel-shipping/models/packing-policy.js +37 -0
  71. package/.medusa/server/src/modules/parcel-shipping/models/parcel-box.js +25 -0
  72. package/.medusa/server/src/modules/parcel-shipping/models/service-area.js +30 -0
  73. package/.medusa/server/src/modules/parcel-shipping/models/shipping-rate.js +50 -0
  74. package/.medusa/server/src/modules/parcel-shipping/service.js +485 -0
  75. package/.medusa/server/{providers → src/providers}/company-truck/index.js +1 -1
  76. package/.medusa/server/src/providers/company-truck/models/company-truck-rate.js +23 -0
  77. package/.medusa/server/{providers → src/providers}/company-truck/models/index.js +3 -2
  78. package/.medusa/server/src/providers/company-truck/models/material-cost.js +24 -0
  79. package/.medusa/server/src/providers/company-truck/models/parcel-box.js +21 -0
  80. package/.medusa/server/src/providers/company-truck/models/service-area.js +20 -0
  81. package/.medusa/server/src/providers/company-truck/service.js +456 -0
  82. package/.medusa/server/{providers → src/providers}/company-truck/types.js +1 -1
  83. package/.medusa/server/src/providers/index.js +8 -0
  84. package/.medusa/server/src/providers/parcel-fulfillment.js +378 -0
  85. package/.medusa/server/{providers → src/providers}/private-carrier/index.js +1 -1
  86. package/.medusa/server/{providers → src/providers}/private-carrier/models/index.js +1 -1
  87. package/.medusa/server/src/providers/private-carrier/models/parcel-box.js +21 -0
  88. package/.medusa/server/src/providers/private-carrier/models/private-carrier-rate.js +23 -0
  89. package/.medusa/server/src/providers/private-carrier/models/service-area.js +20 -0
  90. package/.medusa/server/src/providers/private-carrier/service.js +392 -0
  91. package/.medusa/server/{providers → src/providers}/private-carrier/types.js +1 -1
  92. package/.medusa/server/src/types/index.js +11 -0
  93. package/.medusa/server/src/utils/packing.js +386 -0
  94. package/.medusa/server/src/workflows/assign-packing-slip.js +35 -0
  95. package/.medusa/server/{workflows → src/workflows}/index.js +1 -1
  96. package/package.json +21 -11
  97. package/.medusa/server/api/admin/documents/document-packing-slip-settings/route.js +0 -62
  98. package/.medusa/server/api/admin/parcel-boxes/[id]/route.js +0 -45
  99. package/.medusa/server/api/admin/parcel-boxes/route.js +0 -49
  100. package/.medusa/server/api/admin/shipping-config/areas/[id]/route.js +0 -42
  101. package/.medusa/server/api/admin/shipping-config/areas/route.js +0 -49
  102. package/.medusa/server/api/admin/shipping-config/rates/[id]/route.js +0 -82
  103. package/.medusa/server/api/admin/shipping-config/rates/route.js +0 -95
  104. package/.medusa/server/api/shipping/distance/route.js +0 -85
  105. package/.medusa/server/api/shipping/distance/utils/zodTransform.js +0 -20
  106. package/.medusa/server/api/store/parcel-box-selector/route.js +0 -55
  107. package/.medusa/server/api/webhooks/tracking/route.js +0 -48
  108. package/.medusa/server/common/utils/packing.js +0 -379
  109. package/.medusa/server/index.js +0 -28
  110. package/.medusa/server/modules/documents/services/templates/invoices/basic/parts/customer-info.js +0 -69
  111. package/.medusa/server/modules/documents/services/templates/invoices/basic/parts/header.js +0 -35
  112. package/.medusa/server/modules/documents/services/templates/invoices/basic/parts/table.js +0 -97
  113. package/.medusa/server/modules/documents/services/templates/packing-slips/basic/parts/customer-info-small.js +0 -69
  114. package/.medusa/server/modules/documents/services/templates/packing-slips/basic/parts/customer-info.js +0 -65
  115. package/.medusa/server/modules/documents/services/templates/packing-slips/basic/parts/header-small.js +0 -37
  116. package/.medusa/server/modules/documents/services/templates/packing-slips/basic/parts/header.js +0 -37
  117. package/.medusa/server/modules/documents/services/templates/packing-slips/basic/parts/table-items-small.js +0 -44
  118. package/.medusa/server/modules/documents/services/templates/packing-slips/basic/parts/table-items.js +0 -44
  119. package/.medusa/server/modules/documents/services/templates/packing-slips/basic/parts/table-order-info-small.js +0 -35
  120. package/.medusa/server/providers/company-truck/models/company-truck-rate.js +0 -23
  121. package/.medusa/server/providers/company-truck/models/parcel-box.js +0 -21
  122. package/.medusa/server/providers/company-truck/models/service-area.js +0 -20
  123. package/.medusa/server/providers/company-truck/service.js +0 -456
  124. package/.medusa/server/providers/private-carrier/models/parcel-box.js +0 -21
  125. package/.medusa/server/providers/private-carrier/models/private-carrier-rate.js +0 -23
  126. package/.medusa/server/providers/private-carrier/models/service-area.js +0 -20
  127. package/.medusa/server/providers/private-carrier/service.js +0 -392
  128. package/.medusa/server/workflows/assign-packing-slip.js +0 -31
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.GET = GET;
4
+ exports.PUT = PUT;
5
+ exports.DELETE = DELETE;
6
+ const framework_1 = require("@medusajs/framework");
7
+ const parcel_shipping_1 = require("../../../../modules/parcel-shipping");
8
+ const zod_1 = require("zod");
9
+ const UpdateServiceAreaSchema = zod_1.z.object({
10
+ kind: zod_1.z.enum(["PROVINCE", "POSTCODE_PREFIX"]).optional(),
11
+ value: zod_1.z.string().min(1).optional(),
12
+ active: zod_1.z.boolean().optional(),
13
+ });
14
+ async function GET(req, res) {
15
+ const parcelService = framework_1.container.resolve(parcel_shipping_1.PARCEL_SHIPPING_MODULE);
16
+ const { id } = req.params;
17
+ const areas = await parcelService.findServiceAreas({ id });
18
+ if (!areas || areas.length === 0) {
19
+ return res.status(404).json({ message: "Service area not found" });
20
+ }
21
+ res.json({ service_area: areas[0] });
22
+ }
23
+ async function PUT(req, res) {
24
+ const parcelService = framework_1.container.resolve(parcel_shipping_1.PARCEL_SHIPPING_MODULE);
25
+ const { id } = req.params;
26
+ const validated = UpdateServiceAreaSchema.parse(req.body);
27
+ const area = await parcelService.updateServiceArea(id, validated);
28
+ res.json({ service_area: area });
29
+ }
30
+ async function DELETE(req, res) {
31
+ const parcelService = framework_1.container.resolve(parcel_shipping_1.PARCEL_SHIPPING_MODULE);
32
+ const { id } = req.params;
33
+ await parcelService.deleteServiceArea(id);
34
+ res.status(204).send();
35
+ }
36
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBpL2FkbWluL3NlcnZpY2UtYXJlYXMvW2lkXS9yb3V0ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQVdBLGtCQVdDO0FBRUQsa0JBUUM7QUFFRCx3QkFPQztBQXhDRCxtREFBZ0Q7QUFDaEQseUVBQTZFO0FBQzdFLDZCQUF3QjtBQUV4QixNQUFNLHVCQUF1QixHQUFHLE9BQUMsQ0FBQyxNQUFNLENBQUM7SUFDdkMsSUFBSSxFQUFFLE9BQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxVQUFVLEVBQUUsaUJBQWlCLENBQUMsQ0FBQyxDQUFDLFFBQVEsRUFBRTtJQUN4RCxLQUFLLEVBQUUsT0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxRQUFRLEVBQUU7SUFDbkMsTUFBTSxFQUFFLE9BQUMsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxRQUFRLEVBQUU7Q0FDL0IsQ0FBQyxDQUFDO0FBRUksS0FBSyxVQUFVLEdBQUcsQ0FBQyxHQUFrQixFQUFFLEdBQW1CO0lBQy9ELE1BQU0sYUFBYSxHQUFRLHFCQUFTLENBQUMsT0FBTyxDQUFDLHdDQUFzQixDQUFDLENBQUM7SUFDckUsTUFBTSxFQUFFLEVBQUUsRUFBRSxHQUFHLEdBQUcsQ0FBQyxNQUFNLENBQUM7SUFFMUIsTUFBTSxLQUFLLEdBQUcsTUFBTSxhQUFhLENBQUMsZ0JBQWdCLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDO0lBRTNELElBQUksQ0FBQyxLQUFLLElBQUksS0FBSyxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUUsQ0FBQztRQUNqQyxPQUFPLEdBQUcsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxDQUFDLEVBQUUsT0FBTyxFQUFFLHdCQUF3QixFQUFFLENBQUMsQ0FBQztJQUNyRSxDQUFDO0lBRUQsR0FBRyxDQUFDLElBQUksQ0FBQyxFQUFFLFlBQVksRUFBRSxLQUFLLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDO0FBQ3ZDLENBQUM7QUFFTSxLQUFLLFVBQVUsR0FBRyxDQUFDLEdBQWtCLEVBQUUsR0FBbUI7SUFDL0QsTUFBTSxhQUFhLEdBQVEscUJBQVMsQ0FBQyxPQUFPLENBQUMsd0NBQXNCLENBQUMsQ0FBQztJQUNyRSxNQUFNLEVBQUUsRUFBRSxFQUFFLEdBQUcsR0FBRyxDQUFDLE1BQU0sQ0FBQztJQUUxQixNQUFNLFNBQVMsR0FBRyx1QkFBdUIsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQzFELE1BQU0sSUFBSSxHQUFHLE1BQU0sYUFBYSxDQUFDLGlCQUFpQixDQUFDLEVBQUUsRUFBRSxTQUFTLENBQUMsQ0FBQztJQUVsRSxHQUFHLENBQUMsSUFBSSxDQUFDLEVBQUUsWUFBWSxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7QUFDbkMsQ0FBQztBQUVNLEtBQUssVUFBVSxNQUFNLENBQUMsR0FBa0IsRUFBRSxHQUFtQjtJQUNsRSxNQUFNLGFBQWEsR0FBUSxxQkFBUyxDQUFDLE9BQU8sQ0FBQyx3Q0FBc0IsQ0FBQyxDQUFDO0lBQ3JFLE1BQU0sRUFBRSxFQUFFLEVBQUUsR0FBRyxHQUFHLENBQUMsTUFBTSxDQUFDO0lBRTFCLE1BQU0sYUFBYSxDQUFDLGlCQUFpQixDQUFDLEVBQUUsQ0FBQyxDQUFDO0lBRTFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUM7QUFDekIsQ0FBQyJ9
@@ -0,0 +1,40 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.GET = GET;
4
+ exports.POST = POST;
5
+ const framework_1 = require("@medusajs/framework");
6
+ const parcel_shipping_1 = require("../../../modules/parcel-shipping");
7
+ const zod_1 = require("zod");
8
+ const CreateServiceAreaSchema = zod_1.z.object({
9
+ kind: zod_1.z.enum(["PROVINCE", "POSTCODE_PREFIX"]),
10
+ value: zod_1.z.string().min(1),
11
+ active: zod_1.z.boolean().optional().default(true),
12
+ });
13
+ /**
14
+ * GET /admin/service-areas
15
+ * List all service areas with optional filters
16
+ */
17
+ async function GET(req, res) {
18
+ const parcelService = framework_1.container.resolve(parcel_shipping_1.PARCEL_SHIPPING_MODULE);
19
+ const { kind, active } = req.query;
20
+ const filters = {};
21
+ if (kind) {
22
+ filters.kind = kind;
23
+ }
24
+ if (active !== undefined) {
25
+ filters.active = active === "true";
26
+ }
27
+ const areas = await parcelService.findServiceAreas(filters);
28
+ res.json({ service_areas: areas });
29
+ }
30
+ /**
31
+ * POST /admin/service-areas
32
+ * Create a new service area
33
+ */
34
+ async function POST(req, res) {
35
+ const parcelService = framework_1.container.resolve(parcel_shipping_1.PARCEL_SHIPPING_MODULE);
36
+ const validated = CreateServiceAreaSchema.parse(req.body);
37
+ const area = await parcelService.createServiceArea(validated);
38
+ res.status(201).json({ service_area: area });
39
+ }
40
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBpL2FkbWluL3NlcnZpY2UtYXJlYXMvcm91dGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFlQSxrQkFnQkM7QUFNRCxvQkFPQztBQTNDRCxtREFBZ0Q7QUFDaEQsc0VBQTBFO0FBQzFFLDZCQUF3QjtBQUV4QixNQUFNLHVCQUF1QixHQUFHLE9BQUMsQ0FBQyxNQUFNLENBQUM7SUFDdkMsSUFBSSxFQUFFLE9BQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxVQUFVLEVBQUUsaUJBQWlCLENBQUMsQ0FBQztJQUM3QyxLQUFLLEVBQUUsT0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7SUFDeEIsTUFBTSxFQUFFLE9BQUMsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxRQUFRLEVBQUUsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDO0NBQzdDLENBQUMsQ0FBQztBQUVIOzs7R0FHRztBQUNJLEtBQUssVUFBVSxHQUFHLENBQUMsR0FBa0IsRUFBRSxHQUFtQjtJQUMvRCxNQUFNLGFBQWEsR0FBUSxxQkFBUyxDQUFDLE9BQU8sQ0FBQyx3Q0FBc0IsQ0FBQyxDQUFDO0lBRXJFLE1BQU0sRUFBRSxJQUFJLEVBQUUsTUFBTSxFQUFFLEdBQUcsR0FBRyxDQUFDLEtBQUssQ0FBQztJQUNuQyxNQUFNLE9BQU8sR0FBUSxFQUFFLENBQUM7SUFFeEIsSUFBSSxJQUFJLEVBQUUsQ0FBQztRQUNULE9BQU8sQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDO0lBQ3RCLENBQUM7SUFDRCxJQUFJLE1BQU0sS0FBSyxTQUFTLEVBQUUsQ0FBQztRQUN6QixPQUFPLENBQUMsTUFBTSxHQUFHLE1BQU0sS0FBSyxNQUFNLENBQUM7SUFDckMsQ0FBQztJQUVELE1BQU0sS0FBSyxHQUFHLE1BQU0sYUFBYSxDQUFDLGdCQUFnQixDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBRTVELEdBQUcsQ0FBQyxJQUFJLENBQUMsRUFBRSxhQUFhLEVBQUUsS0FBSyxFQUFFLENBQUMsQ0FBQztBQUNyQyxDQUFDO0FBRUQ7OztHQUdHO0FBQ0ksS0FBSyxVQUFVLElBQUksQ0FBQyxHQUFrQixFQUFFLEdBQW1CO0lBQ2hFLE1BQU0sYUFBYSxHQUFRLHFCQUFTLENBQUMsT0FBTyxDQUFDLHdDQUFzQixDQUFDLENBQUM7SUFFckUsTUFBTSxTQUFTLEdBQUcsdUJBQXVCLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUMxRCxNQUFNLElBQUksR0FBRyxNQUFNLGFBQWEsQ0FBQyxpQkFBaUIsQ0FBQyxTQUFTLENBQUMsQ0FBQztJQUU5RCxHQUFHLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQyxFQUFFLFlBQVksRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO0FBQy9DLENBQUMifQ==
@@ -0,0 +1,48 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.GET = GET;
4
+ exports.PUT = PUT;
5
+ exports.DELETE = DELETE;
6
+ const framework_1 = require("@medusajs/framework");
7
+ const parcel_shipping_1 = require("../../../../modules/parcel-shipping");
8
+ const zod_1 = require("zod");
9
+ const UpdateRateSchema = zod_1.z.object({
10
+ carrier_type: zod_1.z
11
+ .enum(["COMPANY_FLEET", "COMPANY_TRUCK", "PRIVATE_CARRIER"])
12
+ .optional(),
13
+ service_code: zod_1.z
14
+ .enum(["MESSENGER_3H", "SAME_DAY", "STANDARD_3_5D", "EXPRESS_1_2D"])
15
+ .optional(),
16
+ max_weight_kg: zod_1.z.number().positive().optional(),
17
+ price: zod_1.z.number().nonnegative().optional(),
18
+ currency: zod_1.z.string().optional(),
19
+ priority: zod_1.z.number().optional(),
20
+ active: zod_1.z.boolean().optional(),
21
+ eta_hours_min: zod_1.z.number().optional(),
22
+ eta_hours_max: zod_1.z.number().optional(),
23
+ eta_days_min: zod_1.z.number().optional(),
24
+ eta_days_max: zod_1.z.number().optional(),
25
+ });
26
+ async function GET(req, res) {
27
+ const parcelService = framework_1.container.resolve(parcel_shipping_1.PARCEL_SHIPPING_MODULE);
28
+ const { id } = req.params;
29
+ const rates = await parcelService.findRates({ id });
30
+ if (!rates || rates.length === 0) {
31
+ return res.status(404).json({ message: "Rate not found" });
32
+ }
33
+ res.json({ rate: rates[0] });
34
+ }
35
+ async function PUT(req, res) {
36
+ const parcelService = framework_1.container.resolve(parcel_shipping_1.PARCEL_SHIPPING_MODULE);
37
+ const { id } = req.params;
38
+ const validated = UpdateRateSchema.parse(req.body);
39
+ const rate = await parcelService.updateRate(id, validated);
40
+ res.json({ rate });
41
+ }
42
+ async function DELETE(req, res) {
43
+ const parcelService = framework_1.container.resolve(parcel_shipping_1.PARCEL_SHIPPING_MODULE);
44
+ const { id } = req.params;
45
+ await parcelService.deleteRate(id);
46
+ res.status(204).send();
47
+ }
48
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBpL2FkbWluL3NoaXBwaW5nLXJhdGVzL1tpZF0vcm91dGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUF1QkEsa0JBV0M7QUFFRCxrQkFRQztBQUVELHdCQU9DO0FBcERELG1EQUFnRDtBQUNoRCx5RUFBNkU7QUFDN0UsNkJBQXdCO0FBRXhCLE1BQU0sZ0JBQWdCLEdBQUcsT0FBQyxDQUFDLE1BQU0sQ0FBQztJQUNoQyxZQUFZLEVBQUUsT0FBQztTQUNaLElBQUksQ0FBQyxDQUFDLGVBQWUsRUFBRSxlQUFlLEVBQUUsaUJBQWlCLENBQUMsQ0FBQztTQUMzRCxRQUFRLEVBQUU7SUFDYixZQUFZLEVBQUUsT0FBQztTQUNaLElBQUksQ0FBQyxDQUFDLGNBQWMsRUFBRSxVQUFVLEVBQUUsZUFBZSxFQUFFLGNBQWMsQ0FBQyxDQUFDO1NBQ25FLFFBQVEsRUFBRTtJQUNiLGFBQWEsRUFBRSxPQUFDLENBQUMsTUFBTSxFQUFFLENBQUMsUUFBUSxFQUFFLENBQUMsUUFBUSxFQUFFO0lBQy9DLEtBQUssRUFBRSxPQUFDLENBQUMsTUFBTSxFQUFFLENBQUMsV0FBVyxFQUFFLENBQUMsUUFBUSxFQUFFO0lBQzFDLFFBQVEsRUFBRSxPQUFDLENBQUMsTUFBTSxFQUFFLENBQUMsUUFBUSxFQUFFO0lBQy9CLFFBQVEsRUFBRSxPQUFDLENBQUMsTUFBTSxFQUFFLENBQUMsUUFBUSxFQUFFO0lBQy9CLE1BQU0sRUFBRSxPQUFDLENBQUMsT0FBTyxFQUFFLENBQUMsUUFBUSxFQUFFO0lBQzlCLGFBQWEsRUFBRSxPQUFDLENBQUMsTUFBTSxFQUFFLENBQUMsUUFBUSxFQUFFO0lBQ3BDLGFBQWEsRUFBRSxPQUFDLENBQUMsTUFBTSxFQUFFLENBQUMsUUFBUSxFQUFFO0lBQ3BDLFlBQVksRUFBRSxPQUFDLENBQUMsTUFBTSxFQUFFLENBQUMsUUFBUSxFQUFFO0lBQ25DLFlBQVksRUFBRSxPQUFDLENBQUMsTUFBTSxFQUFFLENBQUMsUUFBUSxFQUFFO0NBQ3BDLENBQUMsQ0FBQztBQUVJLEtBQUssVUFBVSxHQUFHLENBQUMsR0FBa0IsRUFBRSxHQUFtQjtJQUMvRCxNQUFNLGFBQWEsR0FBUSxxQkFBUyxDQUFDLE9BQU8sQ0FBQyx3Q0FBc0IsQ0FBQyxDQUFDO0lBQ3JFLE1BQU0sRUFBRSxFQUFFLEVBQUUsR0FBRyxHQUFHLENBQUMsTUFBTSxDQUFDO0lBRTFCLE1BQU0sS0FBSyxHQUFHLE1BQU0sYUFBYSxDQUFDLFNBQVMsQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLENBQUM7SUFFcEQsSUFBSSxDQUFDLEtBQUssSUFBSSxLQUFLLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRSxDQUFDO1FBQ2pDLE9BQU8sR0FBRyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUMsRUFBRSxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsQ0FBQyxDQUFDO0lBQzdELENBQUM7SUFFRCxHQUFHLENBQUMsSUFBSSxDQUFDLEVBQUUsSUFBSSxFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUM7QUFDL0IsQ0FBQztBQUVNLEtBQUssVUFBVSxHQUFHLENBQUMsR0FBa0IsRUFBRSxHQUFtQjtJQUMvRCxNQUFNLGFBQWEsR0FBUSxxQkFBUyxDQUFDLE9BQU8sQ0FBQyx3Q0FBc0IsQ0FBQyxDQUFDO0lBQ3JFLE1BQU0sRUFBRSxFQUFFLEVBQUUsR0FBRyxHQUFHLENBQUMsTUFBTSxDQUFDO0lBRTFCLE1BQU0sU0FBUyxHQUFHLGdCQUFnQixDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDbkQsTUFBTSxJQUFJLEdBQUcsTUFBTSxhQUFhLENBQUMsVUFBVSxDQUFDLEVBQUUsRUFBRSxTQUFTLENBQUMsQ0FBQztJQUUzRCxHQUFHLENBQUMsSUFBSSxDQUFDLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztBQUNyQixDQUFDO0FBRU0sS0FBSyxVQUFVLE1BQU0sQ0FBQyxHQUFrQixFQUFFLEdBQW1CO0lBQ2xFLE1BQU0sYUFBYSxHQUFRLHFCQUFTLENBQUMsT0FBTyxDQUFDLHdDQUFzQixDQUFDLENBQUM7SUFDckUsTUFBTSxFQUFFLEVBQUUsRUFBRSxHQUFHLEdBQUcsQ0FBQyxNQUFNLENBQUM7SUFFMUIsTUFBTSxhQUFhLENBQUMsVUFBVSxDQUFDLEVBQUUsQ0FBQyxDQUFDO0lBRW5DLEdBQUcsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUM7QUFDekIsQ0FBQyJ9
@@ -0,0 +1,66 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.GET = GET;
4
+ exports.POST = POST;
5
+ const framework_1 = require("@medusajs/framework");
6
+ const parcel_shipping_1 = require("../../../modules/parcel-shipping");
7
+ const zod_1 = require("zod");
8
+ const CreateRateSchema = zod_1.z.object({
9
+ carrier_type: zod_1.z.enum(["COMPANY_FLEET", "COMPANY_TRUCK", "PRIVATE_CARRIER"]),
10
+ service_code: zod_1.z.enum([
11
+ "MESSENGER_3H",
12
+ "SAME_DAY",
13
+ "STANDARD_3_5D",
14
+ "EXPRESS_1_2D",
15
+ ]),
16
+ max_weight_kg: zod_1.z.number().positive(),
17
+ price: zod_1.z.number().nonnegative(),
18
+ currency: zod_1.z.string().optional().default("THB"),
19
+ priority: zod_1.z.number().optional().default(0),
20
+ active: zod_1.z.boolean().optional().default(true),
21
+ eta_hours_min: zod_1.z.number().optional(),
22
+ eta_hours_max: zod_1.z.number().optional(),
23
+ eta_days_min: zod_1.z.number().optional(),
24
+ eta_days_max: zod_1.z.number().optional(),
25
+ });
26
+ /**
27
+ * GET /admin/shipping-rates
28
+ * List all shipping rates with optional filters
29
+ */
30
+ async function GET(req, res) {
31
+ const parcelService = framework_1.container.resolve(parcel_shipping_1.PARCEL_SHIPPING_MODULE);
32
+ const { carrier_type, service_code, active } = req.query;
33
+ const filters = {};
34
+ if (carrier_type) {
35
+ filters.carrier_type = carrier_type;
36
+ }
37
+ if (service_code) {
38
+ filters.service_code = service_code;
39
+ }
40
+ if (active !== undefined) {
41
+ filters.active = active === "true";
42
+ }
43
+ const rates = await parcelService.findRates(filters);
44
+ // Sort by carrier_type, service_code, max_weight_kg
45
+ const sorted = rates.sort((a, b) => {
46
+ if (a.carrier_type !== b.carrier_type) {
47
+ return a.carrier_type.localeCompare(b.carrier_type);
48
+ }
49
+ if (a.service_code !== b.service_code) {
50
+ return a.service_code.localeCompare(b.service_code);
51
+ }
52
+ return a.max_weight_kg - b.max_weight_kg;
53
+ });
54
+ res.json({ rates: sorted });
55
+ }
56
+ /**
57
+ * POST /admin/shipping-rates
58
+ * Create a new shipping rate
59
+ */
60
+ async function POST(req, res) {
61
+ const parcelService = framework_1.container.resolve(parcel_shipping_1.PARCEL_SHIPPING_MODULE);
62
+ const validated = CreateRateSchema.parse(req.body);
63
+ const rate = await parcelService.createRate(validated);
64
+ res.status(201).json({ rate });
65
+ }
66
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBpL2FkbWluL3NoaXBwaW5nLXJhdGVzL3JvdXRlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBNEJBLGtCQThCQztBQU1ELG9CQU9DO0FBdEVELG1EQUFnRDtBQUNoRCxzRUFBMEU7QUFDMUUsNkJBQXdCO0FBRXhCLE1BQU0sZ0JBQWdCLEdBQUcsT0FBQyxDQUFDLE1BQU0sQ0FBQztJQUNoQyxZQUFZLEVBQUUsT0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLGVBQWUsRUFBRSxlQUFlLEVBQUUsaUJBQWlCLENBQUMsQ0FBQztJQUMzRSxZQUFZLEVBQUUsT0FBQyxDQUFDLElBQUksQ0FBQztRQUNuQixjQUFjO1FBQ2QsVUFBVTtRQUNWLGVBQWU7UUFDZixjQUFjO0tBQ2YsQ0FBQztJQUNGLGFBQWEsRUFBRSxPQUFDLENBQUMsTUFBTSxFQUFFLENBQUMsUUFBUSxFQUFFO0lBQ3BDLEtBQUssRUFBRSxPQUFDLENBQUMsTUFBTSxFQUFFLENBQUMsV0FBVyxFQUFFO0lBQy9CLFFBQVEsRUFBRSxPQUFDLENBQUMsTUFBTSxFQUFFLENBQUMsUUFBUSxFQUFFLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQztJQUM5QyxRQUFRLEVBQUUsT0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDLFFBQVEsRUFBRSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUM7SUFDMUMsTUFBTSxFQUFFLE9BQUMsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxRQUFRLEVBQUUsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDO0lBQzVDLGFBQWEsRUFBRSxPQUFDLENBQUMsTUFBTSxFQUFFLENBQUMsUUFBUSxFQUFFO0lBQ3BDLGFBQWEsRUFBRSxPQUFDLENBQUMsTUFBTSxFQUFFLENBQUMsUUFBUSxFQUFFO0lBQ3BDLFlBQVksRUFBRSxPQUFDLENBQUMsTUFBTSxFQUFFLENBQUMsUUFBUSxFQUFFO0lBQ25DLFlBQVksRUFBRSxPQUFDLENBQUMsTUFBTSxFQUFFLENBQUMsUUFBUSxFQUFFO0NBQ3BDLENBQUMsQ0FBQztBQUVIOzs7R0FHRztBQUNJLEtBQUssVUFBVSxHQUFHLENBQUMsR0FBa0IsRUFBRSxHQUFtQjtJQUMvRCxNQUFNLGFBQWEsR0FBUSxxQkFBUyxDQUFDLE9BQU8sQ0FBQyx3Q0FBc0IsQ0FBQyxDQUFDO0lBRXJFLE1BQU0sRUFBRSxZQUFZLEVBQUUsWUFBWSxFQUFFLE1BQU0sRUFBRSxHQUFHLEdBQUcsQ0FBQyxLQUFLLENBQUM7SUFDekQsTUFBTSxPQUFPLEdBQVEsRUFBRSxDQUFDO0lBRXhCLElBQUksWUFBWSxFQUFFLENBQUM7UUFDakIsT0FBTyxDQUFDLFlBQVksR0FBRyxZQUFZLENBQUM7SUFDdEMsQ0FBQztJQUNELElBQUksWUFBWSxFQUFFLENBQUM7UUFDakIsT0FBTyxDQUFDLFlBQVksR0FBRyxZQUFZLENBQUM7SUFDdEMsQ0FBQztJQUNELElBQUksTUFBTSxLQUFLLFNBQVMsRUFBRSxDQUFDO1FBQ3pCLE9BQU8sQ0FBQyxNQUFNLEdBQUcsTUFBTSxLQUFLLE1BQU0sQ0FBQztJQUNyQyxDQUFDO0lBRUQsTUFBTSxLQUFLLEdBQUcsTUFBTSxhQUFhLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBRXJELG9EQUFvRDtJQUNwRCxNQUFNLE1BQU0sR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBTSxFQUFFLENBQU0sRUFBRSxFQUFFO1FBQzNDLElBQUksQ0FBQyxDQUFDLFlBQVksS0FBSyxDQUFDLENBQUMsWUFBWSxFQUFFLENBQUM7WUFDdEMsT0FBTyxDQUFDLENBQUMsWUFBWSxDQUFDLGFBQWEsQ0FBQyxDQUFDLENBQUMsWUFBWSxDQUFDLENBQUM7UUFDdEQsQ0FBQztRQUNELElBQUksQ0FBQyxDQUFDLFlBQVksS0FBSyxDQUFDLENBQUMsWUFBWSxFQUFFLENBQUM7WUFDdEMsT0FBTyxDQUFDLENBQUMsWUFBWSxDQUFDLGFBQWEsQ0FBQyxDQUFDLENBQUMsWUFBWSxDQUFDLENBQUM7UUFDdEQsQ0FBQztRQUNELE9BQU8sQ0FBQyxDQUFDLGFBQWEsR0FBRyxDQUFDLENBQUMsYUFBYSxDQUFDO0lBQzNDLENBQUMsQ0FBQyxDQUFDO0lBRUgsR0FBRyxDQUFDLElBQUksQ0FBQyxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsQ0FBQyxDQUFDO0FBQzlCLENBQUM7QUFFRDs7O0dBR0c7QUFDSSxLQUFLLFVBQVUsSUFBSSxDQUFDLEdBQWtCLEVBQUUsR0FBbUI7SUFDaEUsTUFBTSxhQUFhLEdBQVEscUJBQVMsQ0FBQyxPQUFPLENBQUMsd0NBQXNCLENBQUMsQ0FBQztJQUVyRSxNQUFNLFNBQVMsR0FBRyxnQkFBZ0IsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ25ELE1BQU0sSUFBSSxHQUFHLE1BQU0sYUFBYSxDQUFDLFVBQVUsQ0FBQyxTQUFTLENBQUMsQ0FBQztJQUV2RCxHQUFHLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7QUFDakMsQ0FBQyJ9
@@ -0,0 +1,75 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.POST = POST;
4
+ const zod_1 = require("zod");
5
+ const distance_calculator_1 = require("../../../common/utils/distance-calculator");
6
+ const AddressSchema = zod_1.z.object({
7
+ address_line_1: zod_1.z.string().optional(), // House number, building, floor
8
+ address_line_2: zod_1.z.string().optional(), // Additional address info
9
+ street: zod_1.z.string().optional(), // Street name (ถนน)
10
+ sub_district: zod_1.z.string().optional(), // Sub-district (ตำบล/แขวง)
11
+ district: zod_1.z.string().optional(), // District (อำเภอ/เขต)
12
+ city: zod_1.z.string().optional(), // City
13
+ province: zod_1.z.string().optional(), // Province (จังหวัด)
14
+ postcode: zod_1.z.string().optional(), // Postal code
15
+ country: zod_1.z.string().optional(),
16
+ });
17
+ const DistanceRequestSchema = zod_1.z.object({
18
+ origin: AddressSchema,
19
+ destination: AddressSchema,
20
+ });
21
+ /**
22
+ * POST /store/distance
23
+ * Calculate distance between two addresses using OpenStreetMap
24
+ *
25
+ * Request Body:
26
+ * - origin: Origin address with optional components (street, city, province, postcode, country)
27
+ * - destination: Destination address with optional components
28
+ *
29
+ * Returns:
30
+ * - distance_km: Distance in kilometers
31
+ * - duration_minutes: Estimated driving duration in minutes
32
+ * - origin_coordinates: Geocoded coordinates of origin
33
+ * - destination_coordinates: Geocoded coordinates of destination
34
+ *
35
+ * Example:
36
+ * {
37
+ * "origin": {
38
+ * "city": "Bangkok",
39
+ * "province": "Bangkok",
40
+ * "country": "Thailand"
41
+ * },
42
+ * "destination": {
43
+ * "city": "Chiang Mai",
44
+ * "province": "Chiang Mai",
45
+ * "country": "Thailand"
46
+ * }
47
+ * }
48
+ */
49
+ async function POST(req, res) {
50
+ try {
51
+ const validated = DistanceRequestSchema.parse(req.body);
52
+ const calculator = new distance_calculator_1.DistanceCalculator();
53
+ const result = await calculator.calculateDistance(validated.origin, validated.destination);
54
+ res.json({
55
+ distance_km: result.distance_km,
56
+ duration_minutes: result.duration_minutes,
57
+ origin_coordinates: result.origin_coordinates,
58
+ destination_coordinates: result.destination_coordinates,
59
+ });
60
+ }
61
+ catch (error) {
62
+ if (error.name === "ZodError") {
63
+ return res.status(400).json({
64
+ code: "invalid_request",
65
+ message: "Invalid request data",
66
+ errors: error.errors,
67
+ });
68
+ }
69
+ return res.status(400).json({
70
+ code: error.code || "distance_calculation_failed",
71
+ message: error.message || "Failed to calculate distance",
72
+ });
73
+ }
74
+ }
75
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBpL3N0b3JlL2Rpc3RhbmNlL3JvdXRlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBaURBLG9CQStCQztBQS9FRCw2QkFBd0I7QUFDeEIsbUZBQStFO0FBRS9FLE1BQU0sYUFBYSxHQUFHLE9BQUMsQ0FBQyxNQUFNLENBQUM7SUFDN0IsY0FBYyxFQUFFLE9BQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxRQUFRLEVBQUUsRUFBRSxnQ0FBZ0M7SUFDdkUsY0FBYyxFQUFFLE9BQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxRQUFRLEVBQUUsRUFBRSwwQkFBMEI7SUFDakUsTUFBTSxFQUFFLE9BQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxRQUFRLEVBQUUsRUFBRSxvQkFBb0I7SUFDbkQsWUFBWSxFQUFFLE9BQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxRQUFRLEVBQUUsRUFBRSwyQkFBMkI7SUFDaEUsUUFBUSxFQUFFLE9BQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxRQUFRLEVBQUUsRUFBRSx1QkFBdUI7SUFDeEQsSUFBSSxFQUFFLE9BQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxRQUFRLEVBQUUsRUFBRSxPQUFPO0lBQ3BDLFFBQVEsRUFBRSxPQUFDLENBQUMsTUFBTSxFQUFFLENBQUMsUUFBUSxFQUFFLEVBQUUscUJBQXFCO0lBQ3RELFFBQVEsRUFBRSxPQUFDLENBQUMsTUFBTSxFQUFFLENBQUMsUUFBUSxFQUFFLEVBQUUsY0FBYztJQUMvQyxPQUFPLEVBQUUsT0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDLFFBQVEsRUFBRTtDQUMvQixDQUFDLENBQUM7QUFFSCxNQUFNLHFCQUFxQixHQUFHLE9BQUMsQ0FBQyxNQUFNLENBQUM7SUFDckMsTUFBTSxFQUFFLGFBQWE7SUFDckIsV0FBVyxFQUFFLGFBQWE7Q0FDM0IsQ0FBQyxDQUFDO0FBRUg7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQTJCRztBQUNJLEtBQUssVUFBVSxJQUFJLENBQUMsR0FBa0IsRUFBRSxHQUFtQjtJQUNoRSxJQUFJLENBQUM7UUFDSCxNQUFNLFNBQVMsR0FBRyxxQkFBcUIsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBRXhELE1BQU0sVUFBVSxHQUFHLElBQUksd0NBQWtCLEVBQUUsQ0FBQztRQUU1QyxNQUFNLE1BQU0sR0FBRyxNQUFNLFVBQVUsQ0FBQyxpQkFBaUIsQ0FDL0MsU0FBUyxDQUFDLE1BQU0sRUFDaEIsU0FBUyxDQUFDLFdBQVcsQ0FDdEIsQ0FBQztRQUVGLEdBQUcsQ0FBQyxJQUFJLENBQUM7WUFDUCxXQUFXLEVBQUUsTUFBTSxDQUFDLFdBQVc7WUFDL0IsZ0JBQWdCLEVBQUUsTUFBTSxDQUFDLGdCQUFnQjtZQUN6QyxrQkFBa0IsRUFBRSxNQUFNLENBQUMsa0JBQWtCO1lBQzdDLHVCQUF1QixFQUFFLE1BQU0sQ0FBQyx1QkFBdUI7U0FDeEQsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUFDLE9BQU8sS0FBVSxFQUFFLENBQUM7UUFDcEIsSUFBSSxLQUFLLENBQUMsSUFBSSxLQUFLLFVBQVUsRUFBRSxDQUFDO1lBQzlCLE9BQU8sR0FBRyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUM7Z0JBQzFCLElBQUksRUFBRSxpQkFBaUI7Z0JBQ3ZCLE9BQU8sRUFBRSxzQkFBc0I7Z0JBQy9CLE1BQU0sRUFBRSxLQUFLLENBQUMsTUFBTTthQUNyQixDQUFDLENBQUM7UUFDTCxDQUFDO1FBRUQsT0FBTyxHQUFHLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQztZQUMxQixJQUFJLEVBQUUsS0FBSyxDQUFDLElBQUksSUFBSSw2QkFBNkI7WUFDakQsT0FBTyxFQUFFLEtBQUssQ0FBQyxPQUFPLElBQUksOEJBQThCO1NBQ3pELENBQUMsQ0FBQztJQUNMLENBQUM7QUFDSCxDQUFDIn0=
@@ -0,0 +1,116 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.POST = POST;
4
+ const framework_1 = require("@medusajs/framework");
5
+ const parcel_shipping_1 = require("../../../modules/parcel-shipping");
6
+ const zod_1 = require("zod");
7
+ const QuoteItemSchema = zod_1.z.object({
8
+ sku: zod_1.z.string(),
9
+ width: zod_1.z.number().positive(),
10
+ length: zod_1.z.number().positive(),
11
+ height: zod_1.z.number().positive(),
12
+ weight: zod_1.z.number().positive(),
13
+ quantity: zod_1.z.number().int().positive(),
14
+ attributes: zod_1.z
15
+ .object({
16
+ noStack: zod_1.z.boolean().optional(),
17
+ fragile: zod_1.z.boolean().optional(),
18
+ stackable: zod_1.z.number().optional(),
19
+ })
20
+ .optional(),
21
+ });
22
+ const ShippingAddressSchema = zod_1.z.object({
23
+ address_line_1: zod_1.z.string().optional(), // House number, building, floor
24
+ address_line_2: zod_1.z.string().optional(), // Additional address info
25
+ street: zod_1.z.string().optional(), // Street name (ถนน)
26
+ sub_district: zod_1.z.string().optional(), // Sub-district (ตำบล/แขวง)
27
+ district: zod_1.z.string().optional(), // District (อำเภอ/เขต)
28
+ city: zod_1.z.string().optional(), // City
29
+ province: zod_1.z.string().optional(), // Province (จังหวัด)
30
+ postcode: zod_1.z.string().optional(), // Postal code
31
+ country: zod_1.z.string().default("TH"),
32
+ });
33
+ const PreferredServiceSchema = zod_1.z.object({
34
+ carrier_type: zod_1.z.enum(["COMPANY_FLEET", "COMPANY_TRUCK", "PRIVATE_CARRIER"]),
35
+ service_code: zod_1.z.enum([
36
+ "MESSENGER_3H",
37
+ "SAME_DAY",
38
+ "STANDARD_3_5D",
39
+ "EXPRESS_1_2D",
40
+ ]),
41
+ });
42
+ const QuoteRequestSchema = zod_1.z.object({
43
+ items: zod_1.z.array(QuoteItemSchema).min(1),
44
+ shipping_address: ShippingAddressSchema,
45
+ origin_address: ShippingAddressSchema.optional(),
46
+ preferred_service: PreferredServiceSchema.optional(),
47
+ allow_split_boxes: zod_1.z.boolean().optional().default(true),
48
+ });
49
+ /**
50
+ * POST /store/quote
51
+ * Get shipping quote with box selection and multiple service options
52
+ *
53
+ * Request Body:
54
+ * - items: Array of items to ship
55
+ * - shipping_address: Destination address
56
+ * - origin_address: Origin address (optional, for distance calculation)
57
+ * - preferred_service: Preferred carrier/service (optional)
58
+ * - allow_split_boxes: Allow splitting items across multiple boxes (default: true)
59
+ *
60
+ * Returns:
61
+ * - best_box: First box (for backward compatibility)
62
+ * - packing: First box packing details (for backward compatibility)
63
+ * - boxes: Array of all boxes with packing details
64
+ * - shipping_options: All available shipping options with cost breakdown
65
+ * - selected: Selected/preferred option
66
+ * - distance: Distance calculation result (if origin_address provided)
67
+ */
68
+ async function POST(req, res) {
69
+ const parcelService = framework_1.container.resolve(parcel_shipping_1.PARCEL_SHIPPING_MODULE);
70
+ try {
71
+ const validated = QuoteRequestSchema.parse(req.body);
72
+ console.log("Quote request validated:", {
73
+ items_count: validated.items.length,
74
+ shipping_address: validated.shipping_address,
75
+ preferred_service: validated.preferred_service,
76
+ });
77
+ const result = await parcelService.quote(validated);
78
+ res.json({
79
+ best_box: result.best_box,
80
+ packing: result.packing,
81
+ boxes: result.boxes,
82
+ shipping_options: result.shipping_options,
83
+ selected: result.selected,
84
+ distance: result.distance,
85
+ });
86
+ }
87
+ catch (error) {
88
+ if (error.name === "ZodError" && error.errors) {
89
+ console.error("Zod validation errors:", JSON.stringify(error.errors, null, 2));
90
+ return res.status(400).json({
91
+ code: "invalid_request",
92
+ message: "Invalid request data",
93
+ errors: error.errors,
94
+ details: error.errors.map((e) => ({
95
+ path: e.path.join("."),
96
+ message: e.message,
97
+ received: e.received,
98
+ })),
99
+ });
100
+ }
101
+ console.error("Quote API error:", {
102
+ name: error.name,
103
+ message: error.message,
104
+ stack: error.stack,
105
+ });
106
+ return res.status(400).json({
107
+ code: error.code || "quote_failed",
108
+ message: error.message || "Failed to generate quote",
109
+ error_details: {
110
+ name: error.name,
111
+ stack: error.stack?.split("\n").slice(0, 5).join("\n"),
112
+ },
113
+ });
114
+ }
115
+ }
116
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBpL3N0b3JlL3F1b3RlL3JvdXRlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBc0VBLG9CQXVEQztBQTVIRCxtREFBZ0Q7QUFDaEQsc0VBQTBFO0FBQzFFLDZCQUF3QjtBQUV4QixNQUFNLGVBQWUsR0FBRyxPQUFDLENBQUMsTUFBTSxDQUFDO0lBQy9CLEdBQUcsRUFBRSxPQUFDLENBQUMsTUFBTSxFQUFFO0lBQ2YsS0FBSyxFQUFFLE9BQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxRQUFRLEVBQUU7SUFDNUIsTUFBTSxFQUFFLE9BQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxRQUFRLEVBQUU7SUFDN0IsTUFBTSxFQUFFLE9BQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxRQUFRLEVBQUU7SUFDN0IsTUFBTSxFQUFFLE9BQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxRQUFRLEVBQUU7SUFDN0IsUUFBUSxFQUFFLE9BQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxRQUFRLEVBQUU7SUFDckMsVUFBVSxFQUFFLE9BQUM7U0FDVixNQUFNLENBQUM7UUFDTixPQUFPLEVBQUUsT0FBQyxDQUFDLE9BQU8sRUFBRSxDQUFDLFFBQVEsRUFBRTtRQUMvQixPQUFPLEVBQUUsT0FBQyxDQUFDLE9BQU8sRUFBRSxDQUFDLFFBQVEsRUFBRTtRQUMvQixTQUFTLEVBQUUsT0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDLFFBQVEsRUFBRTtLQUNqQyxDQUFDO1NBQ0QsUUFBUSxFQUFFO0NBQ2QsQ0FBQyxDQUFDO0FBRUgsTUFBTSxxQkFBcUIsR0FBRyxPQUFDLENBQUMsTUFBTSxDQUFDO0lBQ3JDLGNBQWMsRUFBRSxPQUFDLENBQUMsTUFBTSxFQUFFLENBQUMsUUFBUSxFQUFFLEVBQUUsZ0NBQWdDO0lBQ3ZFLGNBQWMsRUFBRSxPQUFDLENBQUMsTUFBTSxFQUFF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
@@ -1,4 +1,4 @@
1
1
  "use strict";
2
2
  // Common types shared between providers
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvY29tbW9uL3R5cGVzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSx3Q0FBd0MifQ==
4
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvY29tbW9uL3R5cGVzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSx3Q0FBd0MifQ==
@@ -0,0 +1,98 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DistanceCalculator = void 0;
4
+ const utils_1 = require("@medusajs/framework/utils");
5
+ const geocoding_1 = require("./geocoding");
6
+ const osrm_client_1 = require("./osrm-client");
7
+ /**
8
+ * Service for calculating distances between addresses using OpenStreetMap
9
+ * Combines Nominatim geocoding with OSRM routing
10
+ */
11
+ class DistanceCalculator {
12
+ constructor(geocodingBaseUrl, osrmBaseUrl, userAgent) {
13
+ this.geocodingClient = new geocoding_1.GeocodingClient(geocodingBaseUrl, userAgent);
14
+ this.osrmClient = new osrm_client_1.OSRMClient(osrmBaseUrl);
15
+ }
16
+ /**
17
+ * Calculate distance between two addresses
18
+ * @param origin - Origin address
19
+ * @param destination - Destination address
20
+ * @returns Distance and duration information
21
+ */
22
+ async calculateDistance(origin, destination) {
23
+ try {
24
+ // Geocode both addresses in parallel
25
+ const [originCoords, destCoords] = await Promise.all([
26
+ this.geocodingClient.geocode(origin),
27
+ this.geocodingClient.geocode(destination),
28
+ ]);
29
+ // Calculate route using OSRM
30
+ const route = await this.osrmClient.calculateRoute([originCoords.latitude, originCoords.longitude], [destCoords.latitude, destCoords.longitude]);
31
+ return {
32
+ distance_km: route.distance_km,
33
+ duration_minutes: route.duration_minutes,
34
+ origin_coordinates: originCoords,
35
+ destination_coordinates: destCoords,
36
+ };
37
+ }
38
+ catch (error) {
39
+ if (error instanceof utils_1.MedusaError) {
40
+ throw error;
41
+ }
42
+ throw new utils_1.MedusaError(utils_1.MedusaError.Types.UNEXPECTED_STATE, `Failed to calculate distance between addresses: ${error.message}`);
43
+ }
44
+ }
45
+ /**
46
+ * Calculate distance from coordinates to address
47
+ * @param originCoords - Origin coordinates
48
+ * @param destination - Destination address
49
+ * @returns Distance and duration information
50
+ */
51
+ async calculateDistanceFromCoordinates(originCoords, destination) {
52
+ try {
53
+ // Geocode destination address
54
+ const destCoords = await this.geocodingClient.geocode(destination);
55
+ // Calculate route using OSRM
56
+ const route = await this.osrmClient.calculateRoute([originCoords.latitude, originCoords.longitude], [destCoords.latitude, destCoords.longitude]);
57
+ return {
58
+ distance_km: route.distance_km,
59
+ duration_minutes: route.duration_minutes,
60
+ origin_coordinates: originCoords,
61
+ destination_coordinates: destCoords,
62
+ };
63
+ }
64
+ catch (error) {
65
+ if (error instanceof utils_1.MedusaError) {
66
+ throw error;
67
+ }
68
+ throw new utils_1.MedusaError(utils_1.MedusaError.Types.UNEXPECTED_STATE, `Failed to calculate distance from coordinates: ${error.message}`);
69
+ }
70
+ }
71
+ /**
72
+ * Calculate straight-line distance (Haversine formula)
73
+ * Useful as a fallback when routing is not available
74
+ * @param coord1 - First coordinate
75
+ * @param coord2 - Second coordinate
76
+ * @returns Distance in kilometers
77
+ */
78
+ calculateStraightLineDistance(coord1, coord2) {
79
+ const R = 6371; // Earth's radius in kilometers
80
+ const lat1 = this.toRadians(coord1.latitude);
81
+ const lat2 = this.toRadians(coord2.latitude);
82
+ const deltaLat = this.toRadians(coord2.latitude - coord1.latitude);
83
+ const deltaLon = this.toRadians(coord2.longitude - coord1.longitude);
84
+ const a = Math.sin(deltaLat / 2) * Math.sin(deltaLat / 2) +
85
+ Math.cos(lat1) *
86
+ Math.cos(lat2) *
87
+ Math.sin(deltaLon / 2) *
88
+ Math.sin(deltaLon / 2);
89
+ const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
90
+ const distance = R * c;
91
+ return Number(distance.toFixed(2));
92
+ }
93
+ toRadians(degrees) {
94
+ return degrees * (Math.PI / 180);
95
+ }
96
+ }
97
+ exports.DistanceCalculator = DistanceCalculator;
98
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGlzdGFuY2UtY2FsY3VsYXRvci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3NyYy9jb21tb24vdXRpbHMvZGlzdGFuY2UtY2FsY3VsYXRvci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSxxREFBd0Q7QUFDeEQsMkNBQTZFO0FBQzdFLCtDQUEyQztBQVMzQzs7O0dBR0c7QUFDSCxNQUFhLGtCQUFrQjtJQUk3QixZQUNFLGdCQUF5QixFQUN6QixXQUFvQixFQUNwQixTQUFrQjtRQUVsQixJQUFJLENBQUMsZUFBZSxHQUFHLElBQUksMkJBQWUsQ0FBQyxnQkFBZ0IsRUFBRSxTQUFTLENBQUMsQ0FBQztRQUN4RSxJQUFJLENBQUMsVUFBVSxHQUFHLElBQUksd0JBQVUsQ0FBQyxXQUFXLENBQUMsQ0FBQztJQUNoRCxDQUFDO0lBRUQ7Ozs7O09BS0c7SUFDSCxLQUFLLENBQUMsaUJBQWlCLENBQ3JCLE1BQXdCLEVBQ3hCLFdBQTZCO1FBRTdCLElBQUksQ0FBQztZQUNILHFDQUFxQztZQUNyQyxNQUFNLENBQUMsWUFBWSxFQUFFLFVBQVUsQ0FBQyxHQUFHLE1BQU0sT0FBTyxDQUFDLEdBQUcsQ0FBQztnQkFDbkQsSUFBSSxDQUFDLGVBQWUsQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDO2dCQUNwQyxJQUFJLENBQUMsZUFBZSxDQUFDLE9BQU8sQ0FBQyxXQUFXLENBQUM7YUFDMUMsQ0FBQyxDQUFDO1lBRUgsNkJBQTZCO1lBQzdCLE1BQU0sS0FBSyxHQUFHLE1BQU0sSUFBSSxDQUFDLFVBQVUsQ0FBQyxjQUFjLENBQ2hELENBQUMsWUFBWSxDQUFDLFFBQVEsRUFBRSxZQUFZLENBQUMsU0FBUyxDQUFDLEVBQy9DLENBQUMsVUFBVSxDQUFDLFFBQVEsRUFBRSxVQUFVLENBQUMsU0FBUyxDQUFDLENBQzVDLENBQUM7WUFFRixPQUFPO2dCQUNMLFdBQVcsRUFBRSxLQUFLLENBQUMsV0FBVztnQkFDOUIsZ0JBQWdCLEVB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
@@ -0,0 +1,125 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.GeocodingClient = void 0;
4
+ const utils_1 = require("@medusajs/framework/utils");
5
+ /**
6
+ * Client for OpenStreetMap Nominatim geocoding service
7
+ * Converts addresses to geographic coordinates (latitude, longitude)
8
+ */
9
+ class GeocodingClient {
10
+ constructor(baseUrl = "https://nominatim.openstreetmap.org", userAgent = "MedusaParcelShipping/1.0") {
11
+ this.baseUrl = baseUrl;
12
+ this.userAgent = userAgent;
13
+ }
14
+ /**
15
+ * Geocode an address to coordinates
16
+ * @param address - Address components
17
+ * @returns Coordinates (latitude, longitude)
18
+ */
19
+ async geocode(address) {
20
+ const query = this.buildQuery(address);
21
+ const url = new URL(`${this.baseUrl}/search`);
22
+ url.searchParams.set("q", query);
23
+ url.searchParams.set("format", "json");
24
+ url.searchParams.set("limit", "1");
25
+ url.searchParams.set("addressdetails", "1");
26
+ try {
27
+ const response = await fetch(url.toString(), {
28
+ headers: {
29
+ "User-Agent": this.userAgent,
30
+ },
31
+ });
32
+ if (!response.ok) {
33
+ throw new utils_1.MedusaError(utils_1.MedusaError.Types.UNEXPECTED_STATE, `Nominatim API returned status ${response.status}: ${response.statusText}`);
34
+ }
35
+ const data = await response.json();
36
+ if (!data || data.length === 0) {
37
+ throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, `No geocoding results found for address: ${query}`);
38
+ }
39
+ const result = data[0];
40
+ return {
41
+ latitude: parseFloat(result.lat),
42
+ longitude: parseFloat(result.lon),
43
+ };
44
+ }
45
+ catch (error) {
46
+ if (error instanceof utils_1.MedusaError) {
47
+ throw error;
48
+ }
49
+ throw new utils_1.MedusaError(utils_1.MedusaError.Types.UNEXPECTED_STATE, `Failed to geocode address: ${error.message}`);
50
+ }
51
+ }
52
+ /**
53
+ * Build query string from address components
54
+ * Supports full Thai address format: house number, street, sub-district, district, province, postcode
55
+ */
56
+ buildQuery(address) {
57
+ const parts = [];
58
+ // Add address lines (house number, building)
59
+ if (address.address_line_1)
60
+ parts.push(address.address_line_1);
61
+ if (address.address_line_2)
62
+ parts.push(address.address_line_2);
63
+ // Add street
64
+ if (address.street)
65
+ parts.push(address.street);
66
+ // Add sub-district (ตำบล/แขวง)
67
+ if (address.sub_district)
68
+ parts.push(address.sub_district);
69
+ // Add district (อำเภอ/เขต)
70
+ if (address.district)
71
+ parts.push(address.district);
72
+ // Add city
73
+ if (address.city)
74
+ parts.push(address.city);
75
+ // Add province (จังหวัด)
76
+ if (address.province)
77
+ parts.push(address.province);
78
+ // Add postcode
79
+ if (address.postcode)
80
+ parts.push(address.postcode);
81
+ // Add country
82
+ if (address.country)
83
+ parts.push(address.country);
84
+ if (parts.length === 0) {
85
+ throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, "Address must contain at least one component");
86
+ }
87
+ return parts.join(", ");
88
+ }
89
+ /**
90
+ * Reverse geocode coordinates to address
91
+ * @param latitude - Latitude
92
+ * @param longitude - Longitude
93
+ * @returns Address information
94
+ */
95
+ async reverseGeocode(latitude, longitude) {
96
+ const url = new URL(`${this.baseUrl}/reverse`);
97
+ url.searchParams.set("lat", latitude.toString());
98
+ url.searchParams.set("lon", longitude.toString());
99
+ url.searchParams.set("format", "json");
100
+ url.searchParams.set("addressdetails", "1");
101
+ try {
102
+ const response = await fetch(url.toString(), {
103
+ headers: {
104
+ "User-Agent": this.userAgent,
105
+ },
106
+ });
107
+ if (!response.ok) {
108
+ throw new utils_1.MedusaError(utils_1.MedusaError.Types.UNEXPECTED_STATE, `Nominatim API returned status ${response.status}`);
109
+ }
110
+ const data = await response.json();
111
+ return {
112
+ display_name: data.display_name || "",
113
+ address: data.address || {},
114
+ };
115
+ }
116
+ catch (error) {
117
+ if (error instanceof utils_1.MedusaError) {
118
+ throw error;
119
+ }
120
+ throw new utils_1.MedusaError(utils_1.MedusaError.Types.UNEXPECTED_STATE, `Failed to reverse geocode: ${error.message}`);
121
+ }
122
+ }
123
+ }
124
+ exports.GeocodingClient = GeocodingClient;
125
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2VvY29kaW5nLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vc3JjL2NvbW1vbi91dGlscy9nZW9jb2RpbmcudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEscURBQXdEO0FBMEJ4RDs7O0dBR0c7QUFDSCxNQUFhLGVBQWU7SUFJMUIsWUFDRSxVQUFrQixxQ0FBcUMsRUFDdkQsWUFBb0IsMEJBQTBCO1FBRTlDLElBQUksQ0FBQyxPQUFPLEdBQUcsT0FBTyxDQUFDO1FBQ3ZCLElBQUksQ0FBQyxTQUFTLEdBQUcsU0FBUyxDQUFDO0lBQzdCLENBQUM7SUFFRDs7OztPQUlHO0lBQ0gsS0FBSyxDQUFDLE9BQU8sQ0FBQyxPQUF5QjtRQUNyQyxNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBRXZDLE1BQU0sR0FBRyxHQUFHLElBQUksR0FBRyxDQUFDLEdBQUcsSUFBSSxDQUFDLE9BQU8sU0FBUyxDQUFDLENBQUM7UUFDOUMsR0FBRyxDQUFDLFlBQVksQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLEtBQUssQ0FBQyxDQUFDO1FBQ2pDLEdBQUcsQ0FBQyxZQUFZLENBQUMsR0FBRyxDQUFDLFFBQVEsRUFBRSxNQUFNLENBQUMsQ0FBQztRQUN2QyxHQUFHLENBQUMsWUFBWSxDQUFDLEdBQUcsQ0FBQyxPQUFPLEVBQUUsR0FBRyxDQUFDLENBQUM7UUFDbkMsR0FBRyxDQUFDLFlBQVksQ0FBQyxHQUFHLENBQUMsZ0JBQWdCLEVBQUUsR0FBRyxDQUFDLENBQUM7UUFFNUMsSUFBSSxDQUFDO1lBQ0gsTUFBTSxRQUFRLEdBQUcsTUFBTSxLQUFLLENBQUMsR0FBRyxDQUFDLFFBQVEsRUFBRSxFQUFFO2dCQUMzQyxPQUFPLEVBQUU7b0JBQ1AsWUFBWSxFQUFFLElBQUksQ0FBQyxTQUFTO2lCQUM3QjthQUNGLENBQUMsQ0FBQztZQUVILElBQUksQ0FBQyxRQUFRLENBQUMsRUFBRSxFQUFF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