@hartl-services/medusa-base 0.3.0 → 1.0.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 (323) hide show
  1. package/.medusa/server/src/admin/index.js +2164 -29
  2. package/.medusa/server/src/admin/index.mjs +2166 -31
  3. package/.medusa/server/src/api/admin/email/messages/[id]/resends/route.js +24 -0
  4. package/.medusa/server/src/api/admin/email/messages/[id]/route.js +12 -0
  5. package/.medusa/server/src/api/admin/email/messages/route.js +12 -0
  6. package/.medusa/server/src/api/admin/email/terms-versions/[id]/download/route.js +16 -0
  7. package/.medusa/server/src/api/admin/email/terms-versions/route.js +47 -0
  8. package/.medusa/server/src/api/admin/orders/[id]/documents/[document_id]/download/route.js +21 -0
  9. package/.medusa/server/src/api/admin/orders/[id]/documents/[document_id]/regenerate/route.js +38 -0
  10. package/.medusa/server/src/api/admin/orders/[id]/documents/regenerate/route.js +32 -0
  11. package/.medusa/server/src/api/admin/orders/[id]/documents/route.js +36 -0
  12. package/.medusa/server/src/api/admin/orders/[id]/packing-lists/[fulfillment_id]/download/route.js +24 -0
  13. package/.medusa/server/src/api/admin/orders/[id]/packing-lists/[fulfillment_id]/retry/route.js +44 -0
  14. package/.medusa/server/src/api/admin/orders/[id]/packing-lists/route.js +82 -0
  15. package/.medusa/server/src/api/admin/plugin-features/[plugin_key]/actions/[action_key]/route.js +31 -0
  16. package/.medusa/server/src/api/admin/plugin-features/[plugin_key]/actions/[action_key]/runs/route.js +16 -0
  17. package/.medusa/server/src/api/admin/plugin-features/[plugin_key]/route.js +14 -0
  18. package/.medusa/server/src/api/admin/plugin-features/[plugin_key]/settings/route.js +22 -0
  19. package/.medusa/server/src/api/admin/plugin-features/route.js +6 -4
  20. package/.medusa/server/src/api/document-download-response.js +16 -0
  21. package/.medusa/server/src/api/document-response.js +23 -0
  22. package/.medusa/server/src/api/files/[asset]/route.js +24 -0
  23. package/.medusa/server/src/api/files/file-response.js +43 -0
  24. package/.medusa/server/src/api/files/gateway-options.js +31 -0
  25. package/.medusa/server/src/api/files/private/[token]/route.js +29 -0
  26. package/.medusa/server/src/api/files/upload/[token]/route.js +66 -0
  27. package/.medusa/server/src/api/middlewares.js +186 -5
  28. package/.medusa/server/src/api/packing-list-response.js +22 -0
  29. package/.medusa/server/src/api/plugin-actions.js +221 -0
  30. package/.medusa/server/src/api/plugin-features-http.js +67 -8
  31. package/.medusa/server/src/api/route.js +27 -0
  32. package/.medusa/server/src/api/store/documents/[id]/download/route.js +21 -0
  33. package/.medusa/server/src/api/store/documents/[id]/route.js +15 -0
  34. package/.medusa/server/src/api/store/documents/route.js +11 -0
  35. package/.medusa/server/src/api/terms-download-response.js +12 -0
  36. package/.medusa/server/src/documents/config/index.js +18 -0
  37. package/.medusa/server/src/documents/paths/documents.js +6 -0
  38. package/.medusa/server/src/documents/paths/index.js +18 -0
  39. package/.medusa/server/src/documents/plugin-features.js +24 -0
  40. package/.medusa/server/src/documents/schemas/documents.js +18 -0
  41. package/.medusa/server/src/documents/schemas/index.js +18 -0
  42. package/.medusa/server/src/documents/scripts/verify-documents-file-storage.js +55 -0
  43. package/.medusa/server/src/documents/templates/financial-document.js +142 -0
  44. package/.medusa/server/src/documents/templates/format.js +31 -0
  45. package/.medusa/server/src/documents/templates/html-factory.js +40 -0
  46. package/.medusa/server/src/documents/templates/html-utils.js +13 -0
  47. package/.medusa/server/src/documents/templates/layout.js +97 -0
  48. package/.medusa/server/src/documents/templates/packing-list.js +50 -0
  49. package/.medusa/server/src/documents/types/admin-api.js +3 -0
  50. package/.medusa/server/src/documents/types/document-summary.js +3 -0
  51. package/.medusa/server/src/documents/types/documents.js +3 -0
  52. package/.medusa/server/src/documents/types/html-factory.js +6 -0
  53. package/.medusa/server/src/documents/types/index.js +22 -0
  54. package/.medusa/server/src/documents/types/store-api.js +3 -0
  55. package/.medusa/server/src/documents/utils/document-merchant.js +22 -0
  56. package/.medusa/server/src/documents/utils/html-to-pdf.js +61 -0
  57. package/.medusa/server/src/documents/utils/private-file-storage.js +64 -0
  58. package/.medusa/server/src/documents/utils/resolve-services.js +7 -0
  59. package/.medusa/server/src/email/application/handle-invite-event.js +312 -0
  60. package/.medusa/server/src/email/application/handle-password-reset-event.js +354 -0
  61. package/.medusa/server/src/email/config/index.js +84 -0
  62. package/.medusa/server/src/email/config/notification-module.js +20 -0
  63. package/.medusa/server/src/email/domain/business-keys.js +50 -0
  64. package/.medusa/server/src/email/domain/documents-fact-fingerprint.js +7 -0
  65. package/.medusa/server/src/email/domain/event-schemas.js +36 -0
  66. package/.medusa/server/src/email/domain/failure-classification.js +53 -0
  67. package/.medusa/server/src/email/plugin-features.js +31 -0
  68. package/.medusa/server/src/email/rendering/default-templates.js +91 -0
  69. package/.medusa/server/src/email/rendering/render-email.js +37 -0
  70. package/.medusa/server/src/email/rendering/resolve-shop-configuration.js +48 -0
  71. package/.medusa/server/src/email/types/email-kinds.js +18 -0
  72. package/.medusa/server/src/email/types/index.js +21 -0
  73. package/.medusa/server/src/email/types/shop-configuration.js +3 -0
  74. package/.medusa/server/src/email/types/smtp-configuration.js +3 -0
  75. package/.medusa/server/src/email/types/template-data.js +79 -0
  76. package/.medusa/server/src/files/config/index.js +256 -0
  77. package/.medusa/server/src/files/gateway/index.js +115 -0
  78. package/.medusa/server/src/files/types/index.js +6 -0
  79. package/.medusa/server/src/files/types/public.js +6 -0
  80. package/.medusa/server/src/jobs/document-fact-publication-reconciliation.js +18 -0
  81. package/.medusa/server/src/jobs/document-resolution-reconciliation.js +20 -0
  82. package/.medusa/server/src/jobs/packing-list-reconciliation.js +49 -0
  83. package/.medusa/server/src/jobs/reconcile-email-attempts.js +63 -0
  84. package/.medusa/server/src/jobs/reconcile-pending-email-messages.js +41 -0
  85. package/.medusa/server/src/jobs/retry-email-messages.js +27 -0
  86. package/.medusa/server/src/migration-scripts/dismiss-orphaned-cart-promotion-links.js +26 -0
  87. package/.medusa/server/src/modules/documents/domain/cancellation-snapshot.js +97 -0
  88. package/.medusa/server/src/modules/documents/domain/document-number.js +36 -0
  89. package/.medusa/server/src/modules/documents/domain/document-resolution.js +24 -0
  90. package/.medusa/server/src/modules/documents/domain/issuance-rules.js +37 -0
  91. package/.medusa/server/src/modules/documents/domain/merchant.js +86 -0
  92. package/.medusa/server/src/modules/documents/domain/options.js +40 -0
  93. package/.medusa/server/src/modules/documents/domain/packing-list.js +90 -0
  94. package/.medusa/server/src/modules/documents/domain/snapshot-normalization.js +17 -0
  95. package/.medusa/server/src/modules/documents/domain/tax-breakdown.js +66 -0
  96. package/.medusa/server/src/modules/documents/index.js +15 -0
  97. package/.medusa/server/src/modules/documents/loaders/assert-private-file-storage.js +20 -0
  98. package/.medusa/server/src/modules/documents/migrations/Migration20260827061749.js +75 -0
  99. package/.medusa/server/src/modules/documents/migrations/Migration20260830111207.js +28 -0
  100. package/.medusa/server/src/modules/documents/models/document-artifact.js +25 -0
  101. package/.medusa/server/src/modules/documents/models/document-number-sequence.js +29 -0
  102. package/.medusa/server/src/modules/documents/models/document.js +82 -0
  103. package/.medusa/server/src/modules/documents/models/order-cancellation-resolution.js +51 -0
  104. package/.medusa/server/src/modules/documents/models/packing-list-revision.js +36 -0
  105. package/.medusa/server/src/modules/documents/models/packing-list.js +27 -0
  106. package/.medusa/server/src/modules/documents/models/refund-document-resolution.js +66 -0
  107. package/.medusa/server/src/modules/documents/models/shipment-invoice-assignment.js +51 -0
  108. package/.medusa/server/src/modules/documents/models/shipment-invoice-coordinator.js +44 -0
  109. package/.medusa/server/src/modules/documents/service.js +1701 -0
  110. package/.medusa/server/src/modules/email/domain/attachment.js +25 -0
  111. package/.medusa/server/src/modules/email/domain/message-state.js +69 -0
  112. package/.medusa/server/src/modules/email/index.js +13 -0
  113. package/.medusa/server/src/modules/email/migrations/Migration20260826173422.js +32 -0
  114. package/.medusa/server/src/modules/email/migrations/Migration20260827172945.js +16 -0
  115. package/.medusa/server/src/modules/email/migrations/Migration20260827194804.js +22 -0
  116. package/.medusa/server/src/modules/email/migrations/Migration20260906195205.js +16 -0
  117. package/.medusa/server/src/modules/email/models/email-attempt.js +56 -0
  118. package/.medusa/server/src/modules/email/models/email-message.js +71 -0
  119. package/.medusa/server/src/modules/email/models/email-terms-version.js +37 -0
  120. package/.medusa/server/src/modules/email/service.js +1285 -0
  121. package/.medusa/server/src/modules/plugin-features/domain/plugin-action-runs.js +92 -0
  122. package/.medusa/server/src/modules/plugin-features/domain/plugin-settings.js +213 -0
  123. package/.medusa/server/src/modules/plugin-features/domain/secret-box.js +56 -0
  124. package/.medusa/server/src/modules/plugin-features/migrations/Migration20260928205031.js +16 -0
  125. package/.medusa/server/src/modules/plugin-features/migrations/Migration20260928215428.js +17 -0
  126. package/.medusa/server/src/modules/plugin-features/models/plugin-action-run.js +43 -0
  127. package/.medusa/server/src/modules/plugin-features/models/plugin-setting-state.js +32 -0
  128. package/.medusa/server/src/modules/plugin-features/service.js +419 -17
  129. package/.medusa/server/src/providers/s3-cache/cache/atomic-write.js +25 -0
  130. package/.medusa/server/src/providers/s3-cache/cache/cache-manager.js +115 -0
  131. package/.medusa/server/src/providers/s3-cache/cache/keyed-lock.js +28 -0
  132. package/.medusa/server/src/providers/s3-cache/index.js +8 -0
  133. package/.medusa/server/src/providers/s3-cache/object-key.js +53 -0
  134. package/.medusa/server/src/providers/s3-cache/s3-cache-file.js +229 -0
  135. package/.medusa/server/src/providers/s3-cache/s3-object-store.js +86 -0
  136. package/.medusa/server/src/providers/smtp/index.js +8 -0
  137. package/.medusa/server/src/providers/smtp/service.js +236 -0
  138. package/.medusa/server/src/providers/smtp/types.js +11 -0
  139. package/.medusa/server/src/public/action-progress.js +67 -0
  140. package/.medusa/server/src/public/config.js +186 -0
  141. package/.medusa/server/src/public/descriptor.js +199 -2
  142. package/.medusa/server/src/public/effective-features.js +9 -5
  143. package/.medusa/server/src/public/enforcement.js +18 -8
  144. package/.medusa/server/src/public/gateway.js +19 -0
  145. package/.medusa/server/src/public/index.js +10 -2
  146. package/.medusa/server/src/public/instrumentation.js +56 -0
  147. package/.medusa/server/src/public/module-access.js +14 -0
  148. package/.medusa/server/src/public/settings.js +17 -0
  149. package/.medusa/server/src/public/shop-config.js +12 -0
  150. package/.medusa/server/src/public/shop-master-data.js +95 -0
  151. package/.medusa/server/src/public/shop-types.js +24 -0
  152. package/.medusa/server/src/shop-config/build-food-shop-config.js +248 -0
  153. package/.medusa/server/src/shop-config/options.js +71 -0
  154. package/.medusa/server/src/subscribers/affiliate-consignment-reminder-due.js +26 -0
  155. package/.medusa/server/src/subscribers/documents-order-canceled.js +24 -0
  156. package/.medusa/server/src/subscribers/documents-order-cancellation-ready.js +26 -0
  157. package/.medusa/server/src/subscribers/documents-refund-ready.js +24 -0
  158. package/.medusa/server/src/subscribers/documents-shipment-created.js +36 -0
  159. package/.medusa/server/src/subscribers/documents-shipment-invoice-assignment-decided.js +26 -0
  160. package/.medusa/server/src/subscribers/email-order-canceled.js +28 -0
  161. package/.medusa/server/src/subscribers/email-shipment-created.js +32 -0
  162. package/.medusa/server/src/subscribers/order-placed.js +27 -0
  163. package/.medusa/server/src/subscribers/packing-list-allocation-revised.js +32 -0
  164. package/.medusa/server/src/subscribers/packing-list-fulfillment-canceled.js +54 -0
  165. package/.medusa/server/src/subscribers/packing-list-fulfillment-created.js +31 -0
  166. package/.medusa/server/src/subscribers/password-reset.js +23 -0
  167. package/.medusa/server/src/subscribers/payment-refunded.js +38 -0
  168. package/.medusa/server/src/subscribers/return-received.js +27 -0
  169. package/.medusa/server/src/subscribers/return-requested.js +27 -0
  170. package/.medusa/server/src/subscribers/user-invite.js +23 -0
  171. package/.medusa/server/src/utils/cart-promotion-links.js +101 -0
  172. package/.medusa/server/src/utils/discover-complete-cart-participants.js +9 -2
  173. package/.medusa/server/src/utils/discover-plugin-features.js +47 -9
  174. package/.medusa/server/src/workflows/documents/issue-cancellation-after-refund.js +246 -0
  175. package/.medusa/server/src/workflows/documents/issue-document.js +163 -0
  176. package/.medusa/server/src/workflows/documents/issue-invoice-after-shipment.js +521 -0
  177. package/.medusa/server/src/workflows/documents/issue-packing-list.js +384 -0
  178. package/.medusa/server/src/workflows/documents/publish-document-facts.js +53 -0
  179. package/.medusa/server/src/workflows/documents/reconcile-document-resolutions.js +48 -0
  180. package/.medusa/server/src/workflows/documents/reconcile-order-cancellation.js +92 -0
  181. package/.medusa/server/src/workflows/documents/regenerate-issued-document.js +61 -0
  182. package/.medusa/server/src/workflows/email/dispatch-email-message.js +299 -0
  183. package/.medusa/server/src/workflows/email/documents-required-facts.js +30 -0
  184. package/.medusa/server/src/workflows/email/prepare-affiliate-reminder-email.js +58 -0
  185. package/.medusa/server/src/workflows/email/prepare-order-canceled-email.js +64 -0
  186. package/.medusa/server/src/workflows/email/prepare-order-received-email.js +56 -0
  187. package/.medusa/server/src/workflows/email/prepare-refund-email.js +47 -0
  188. package/.medusa/server/src/workflows/email/prepare-return-email.js +75 -0
  189. package/.medusa/server/src/workflows/email/prepare-shipment-email.js +82 -0
  190. package/.medusa/server/src/workflows/email/retry-email-messages.js +31 -0
  191. package/.medusa/server/src/workflows/hooks/complete-cart-participants.js +28 -16
  192. package/.medusa/server/src/workflows/hooks/dismiss-deleted-promotion-cart-links.js +23 -0
  193. package/README.md +2004 -11
  194. package/dist/admin-components/features/plugin-features/components/PluginActionsSection.d.ts +6 -0
  195. package/dist/admin-components/features/plugin-features/components/PluginActionsSection.js +66 -0
  196. package/dist/admin-components/features/plugin-features/components/PluginDetailPage.d.ts +2 -0
  197. package/dist/admin-components/features/plugin-features/components/PluginDetailPage.js +9 -0
  198. package/dist/admin-components/features/plugin-features/components/PluginFeatureGate.d.ts +22 -0
  199. package/dist/admin-components/features/plugin-features/components/PluginFeatureGate.js +18 -0
  200. package/dist/admin-components/features/plugin-features/components/PluginFeatureSections.d.ts +11 -0
  201. package/dist/admin-components/features/plugin-features/components/PluginFeatureSections.js +19 -0
  202. package/dist/admin-components/features/plugin-features/components/PluginFeaturesCard.d.ts +12 -0
  203. package/dist/admin-components/features/plugin-features/components/PluginFeaturesCard.js +34 -0
  204. package/dist/admin-components/features/plugin-features/components/PluginFeaturesSettingsPage.d.ts +5 -0
  205. package/dist/admin-components/features/plugin-features/components/PluginFeaturesSettingsPage.js +16 -0
  206. package/dist/admin-components/features/plugin-features/components/PluginHubCard.d.ts +7 -0
  207. package/dist/admin-components/features/plugin-features/components/PluginHubCard.js +21 -0
  208. package/dist/admin-components/features/plugin-features/components/PluginPageShell.d.ts +13 -0
  209. package/dist/admin-components/features/plugin-features/components/PluginPageShell.js +20 -0
  210. package/dist/admin-components/features/plugin-features/components/PluginSettingsForm.d.ts +7 -0
  211. package/dist/admin-components/features/plugin-features/components/PluginSettingsForm.js +39 -0
  212. package/dist/admin-components/features/plugin-features/components/PluginStatusChips.d.ts +5 -0
  213. package/dist/admin-components/features/plugin-features/components/PluginStatusChips.js +8 -0
  214. package/dist/admin-components/features/plugin-features/hooks/usePluginFeatureEnabled.d.ts +114 -0
  215. package/dist/admin-components/features/plugin-features/hooks/usePluginFeatureEnabled.js +40 -0
  216. package/dist/admin-components/features/plugin-features/hooks/usePluginFeatures.d.ts +392 -0
  217. package/dist/admin-components/features/plugin-features/hooks/usePluginFeatures.js +128 -0
  218. package/dist/admin-components/features/plugin-features/hooks/usePluginSettingsForm.d.ts +93 -0
  219. package/dist/admin-components/features/plugin-features/hooks/usePluginSettingsForm.js +44 -0
  220. package/dist/admin-components/features/plugin-features/lib/action-runs.d.ts +19 -0
  221. package/dist/admin-components/features/plugin-features/lib/action-runs.js +74 -0
  222. package/dist/admin-components/features/plugin-features/lib/plugin-features-admin-client.d.ts +363 -0
  223. package/dist/admin-components/features/plugin-features/lib/plugin-features-admin-client.js +9 -0
  224. package/dist/admin-components/features/plugin-features/lib/plugin-paths.d.ts +4 -0
  225. package/dist/admin-components/features/plugin-features/lib/plugin-paths.js +4 -0
  226. package/dist/admin-components/features/plugin-features/lib/settings-draft.d.ts +28 -0
  227. package/dist/admin-components/features/plugin-features/lib/settings-draft.js +86 -0
  228. package/dist/admin-components/features/plugin-features/queries/pluginFeatureKeys.d.ts +7 -0
  229. package/dist/admin-components/features/plugin-features/queries/pluginFeatureKeys.js +7 -0
  230. package/dist/admin-components/i18n/texts.d.ts +90 -0
  231. package/dist/admin-components/i18n/texts.js +90 -0
  232. package/dist/admin-components/index.d.ts +14 -0
  233. package/dist/admin-components/index.js +14 -0
  234. package/dist/admin-components/lib/errors.d.ts +6 -0
  235. package/dist/admin-components/lib/errors.js +27 -0
  236. package/dist/admin-components/lib/sdk.d.ts +2 -0
  237. package/dist/admin-components/lib/sdk.js +13 -0
  238. package/dist/documents/config/index.d.ts +11 -0
  239. package/dist/documents/config/index.js +17 -0
  240. package/dist/documents/templates/financial-document.d.ts +3 -0
  241. package/dist/documents/templates/financial-document.js +141 -0
  242. package/dist/documents/templates/format.d.ts +16 -0
  243. package/dist/documents/templates/format.js +30 -0
  244. package/dist/documents/templates/html-factory.d.ts +11 -0
  245. package/dist/documents/templates/html-factory.js +39 -0
  246. package/dist/documents/templates/html-utils.d.ts +2 -0
  247. package/dist/documents/templates/html-utils.js +12 -0
  248. package/dist/documents/templates/layout.d.ts +17 -0
  249. package/dist/documents/templates/layout.js +96 -0
  250. package/dist/documents/templates/packing-list.d.ts +3 -0
  251. package/dist/documents/templates/packing-list.js +49 -0
  252. package/dist/documents/types/admin-api.d.ts +1 -0
  253. package/dist/documents/types/admin-api.js +2 -0
  254. package/dist/documents/types/document-summary.d.ts +1 -0
  255. package/dist/documents/types/document-summary.js +2 -0
  256. package/dist/documents/types/documents.d.ts +174 -0
  257. package/dist/documents/types/documents.js +2 -0
  258. package/dist/documents/types/html-factory.d.ts +7 -0
  259. package/dist/documents/types/html-factory.js +5 -0
  260. package/dist/documents/types/index.d.ts +5 -0
  261. package/dist/documents/types/index.js +21 -0
  262. package/dist/documents/types/store-api.d.ts +1 -0
  263. package/dist/documents/types/store-api.js +2 -0
  264. package/dist/email/config/index.d.ts +17 -0
  265. package/dist/email/config/index.js +83 -0
  266. package/dist/email/config/notification-module.d.ts +22 -0
  267. package/dist/email/config/notification-module.js +19 -0
  268. package/dist/email/types/email-kinds.d.ts +15 -0
  269. package/dist/email/types/email-kinds.js +17 -0
  270. package/dist/email/types/index.d.ts +4 -0
  271. package/dist/email/types/index.js +20 -0
  272. package/dist/email/types/shop-configuration.d.ts +43 -0
  273. package/dist/email/types/shop-configuration.js +2 -0
  274. package/dist/email/types/smtp-configuration.d.ts +9 -0
  275. package/dist/email/types/smtp-configuration.js +2 -0
  276. package/dist/email/types/template-data.d.ts +100 -0
  277. package/dist/email/types/template-data.js +78 -0
  278. package/dist/files/config/index.d.ts +32 -0
  279. package/dist/files/config/index.js +255 -0
  280. package/dist/files/gateway/index.d.ts +30 -0
  281. package/dist/files/gateway/index.js +114 -0
  282. package/dist/files/types/index.d.ts +2 -0
  283. package/dist/files/types/index.js +5 -0
  284. package/dist/files/types/public.d.ts +90 -0
  285. package/dist/files/types/public.js +5 -0
  286. package/dist/modules/documents/domain/merchant.d.ts +22 -0
  287. package/dist/modules/documents/domain/merchant.js +85 -0
  288. package/dist/modules/documents/domain/options.d.ts +34 -0
  289. package/dist/modules/documents/domain/options.js +39 -0
  290. package/dist/public/action-progress.d.ts +25 -0
  291. package/dist/public/action-progress.js +66 -0
  292. package/dist/public/config.d.ts +59 -0
  293. package/dist/public/config.js +185 -0
  294. package/dist/public/descriptor.d.ts +3 -2
  295. package/dist/public/descriptor.js +198 -1
  296. package/dist/public/effective-features.d.ts +2 -1
  297. package/dist/public/effective-features.js +8 -4
  298. package/dist/public/enforcement.d.ts +7 -0
  299. package/dist/public/enforcement.js +17 -7
  300. package/dist/public/gateway.d.ts +2 -0
  301. package/dist/public/gateway.js +18 -0
  302. package/dist/public/index.d.ts +5 -2
  303. package/dist/public/index.js +9 -1
  304. package/dist/public/instrumentation.d.ts +12 -0
  305. package/dist/public/instrumentation.js +55 -0
  306. package/dist/public/module-access.d.ts +3 -0
  307. package/dist/public/module-access.js +13 -0
  308. package/dist/public/settings.d.ts +11 -0
  309. package/dist/public/settings.js +16 -0
  310. package/dist/public/shop-config.d.ts +8 -0
  311. package/dist/public/shop-config.js +11 -0
  312. package/dist/public/shop-master-data.d.ts +25 -0
  313. package/dist/public/shop-master-data.js +94 -0
  314. package/dist/public/shop-types.d.ts +7 -0
  315. package/dist/public/shop-types.js +23 -0
  316. package/dist/public/types.d.ts +113 -1
  317. package/dist/shop-config/build-food-shop-config.d.ts +44 -0
  318. package/dist/shop-config/build-food-shop-config.js +247 -0
  319. package/dist/shop-config/options.d.ts +41 -0
  320. package/dist/shop-config/options.js +70 -0
  321. package/dist/utils/discover-plugin-features.d.ts +28 -0
  322. package/dist/utils/discover-plugin-features.js +96 -0
  323. package/package.json +53 -6
@@ -0,0 +1,90 @@
1
+ export const texts = {
2
+ menu: {
3
+ label: "Hartl Services Plugins",
4
+ },
5
+ page: {
6
+ title: "Hartl Services Plugins",
7
+ description: "Plugins ein- oder ausschalten und öffnen, um Funktionen, Einstellungen und Aktionen zu verwalten. Änderungen gelten sofort; abgeschaltete Funktionen sind im Shop nicht erreichbar.",
8
+ },
9
+ states: {
10
+ loading: "Plugins werden geladen…",
11
+ error: "Plugins konnten nicht geladen werden.",
12
+ empty: "Keine Plugins mit Funktionsschaltern installiert.",
13
+ retry: "Erneut laden",
14
+ notFound: "Dieses Plugin ist nicht installiert.",
15
+ },
16
+ plugin: {
17
+ switchLabel: (label) => `${label} aktiv`,
18
+ open: "Öffnen",
19
+ openLabel: (label) => `${label} öffnen`,
20
+ },
21
+ chips: {
22
+ enabled: "aktiv",
23
+ disabled: "aus",
24
+ configured: "konfiguriert",
25
+ notConfigured: (labels) => `nicht konfiguriert: ${labels}`,
26
+ },
27
+ detail: {
28
+ back: "Zurück zu Hartl Services Plugins",
29
+ },
30
+ sections: {
31
+ features: "Funktionen",
32
+ settings: "Einstellungen",
33
+ actions: "Aktionen",
34
+ },
35
+ hints: {
36
+ pluginDisabled: "Das Plugin ist ausgeschaltet. Alle Funktionen sind inaktiv, ihre Einstellungen bleiben erhalten.",
37
+ parentDisabled: (parentLabel) => `Inaktiv, solange „${parentLabel}“ ausgeschaltet ist.`,
38
+ saving: "Wird gespeichert…",
39
+ },
40
+ gate: {
41
+ disabled: "Diese Funktion ist unter Einstellungen → Hartl Services Plugins ausgeschaltet.",
42
+ disabledNamed: (label) => `„${label}“ ist unter Einstellungen → Hartl Services Plugins ausgeschaltet.`,
43
+ openHub: "Zu Hartl Services Plugins",
44
+ },
45
+ settings: {
46
+ missing: (labels) => `Nicht konfiguriert: ${labels}`,
47
+ save: "Einstellungen speichern",
48
+ secretPlaceholder: "gesetzt",
49
+ secretClear: "Löschen",
50
+ secretClearPending: "Wird beim Speichern gelöscht; danach gilt der Wert aus der Konfiguration, falls vorhanden.",
51
+ secretClearUndo: "Nicht löschen",
52
+ secretClearLabel: (label) => `${label} löschen`,
53
+ secretClearUndoLabel: (label) => `${label} nicht löschen`,
54
+ invalidates: (labels) => `Beim Ändern muss ${labels} neu eingegeben werden.`,
55
+ required: "Pflichtfeld",
56
+ invalidNumber: "Bitte eine gültige Zahl eingeben.",
57
+ outOfRange: "Der Wert liegt außerhalb des erlaubten Bereichs.",
58
+ numberMin: (min) => `Mindestens ${min}.`,
59
+ numberMax: (max) => `Höchstens ${max}.`,
60
+ numberRange: (min, max) => `Zwischen ${min} und ${max}.`,
61
+ selectPlaceholder: "Bitte auswählen",
62
+ clearHint: "Ein leeres Feld speichern entfernt den gespeicherten Wert (dann gilt Konfiguration oder Standard).",
63
+ source: {
64
+ stored: "gespeichert",
65
+ config: "aus Konfiguration",
66
+ default: "Standard",
67
+ none: "nicht gesetzt",
68
+ },
69
+ },
70
+ actions: {
71
+ confirmTitle: (label) => `${label}?`,
72
+ confirm: "Ausführen",
73
+ cancel: "Abbrechen",
74
+ runningSince: (time) => `läuft seit ${time}`,
75
+ lastCompleted: (time) => `Zuletzt erfolgreich: ${time}`,
76
+ lastFailed: (time) => `Zuletzt fehlgeschlagen: ${time}`,
77
+ },
78
+ toasts: {
79
+ saved: "Einstellung wurde gespeichert.",
80
+ saveFailed: "Einstellung konnte nicht gespeichert werden.",
81
+ conflict: "Die Einstellungen wurden zwischenzeitlich geändert und neu geladen.",
82
+ actionCompleted: (label) => `„${label}“ wurde ausgeführt.`,
83
+ actionStarted: (label) => `„${label}“ wurde gestartet und läuft im Hintergrund.`,
84
+ actionFailed: (label) => `„${label}“ ist fehlgeschlagen.`,
85
+ actionAlreadyRunning: (label) => `„${label}“ läuft bereits; der Fortschritt wird angezeigt.`,
86
+ },
87
+ errors: {
88
+ unknown: "Unbekannter Fehler",
89
+ },
90
+ };
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Entry of `@hartl-services/medusa-base/admin-components` (built by
3
+ * `tsconfig.admin-components.json` into `dist/admin-components`). Not an
4
+ * Admin extension: routes and widgets live in `routes/`.
5
+ *
6
+ * Other plugins compose these into their own Admin page. Everything here
7
+ * uses the host Admin's React, React Query, React Router and `@medusajs/ui`.
8
+ */
9
+ export { PluginPageShell } from "./features/plugin-features/components/PluginPageShell";
10
+ export { PluginFeatureSections } from "./features/plugin-features/components/PluginFeatureSections";
11
+ export { PluginFeatureDisabledNotice, PluginFeatureGate, } from "./features/plugin-features/components/PluginFeatureGate";
12
+ export { usePluginFeature } from "./features/plugin-features/hooks/usePluginFeatures";
13
+ export { usePluginFeatureEnabled, type PluginFeatureEnabledState, } from "./features/plugin-features/hooks/usePluginFeatureEnabled";
14
+ export { pluginFeatureKeys } from "./features/plugin-features/queries/pluginFeatureKeys";
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Entry of `@hartl-services/medusa-base/admin-components` (built by
3
+ * `tsconfig.admin-components.json` into `dist/admin-components`). Not an
4
+ * Admin extension: routes and widgets live in `routes/`.
5
+ *
6
+ * Other plugins compose these into their own Admin page. Everything here
7
+ * uses the host Admin's React, React Query, React Router and `@medusajs/ui`.
8
+ */
9
+ export { PluginPageShell } from "./features/plugin-features/components/PluginPageShell";
10
+ export { PluginFeatureSections } from "./features/plugin-features/components/PluginFeatureSections";
11
+ export { PluginFeatureDisabledNotice, PluginFeatureGate, } from "./features/plugin-features/components/PluginFeatureGate";
12
+ export { usePluginFeature } from "./features/plugin-features/hooks/usePluginFeatures";
13
+ export { usePluginFeatureEnabled, } from "./features/plugin-features/hooks/usePluginFeatureEnabled";
14
+ export { pluginFeatureKeys } from "./features/plugin-features/queries/pluginFeatureKeys";
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Extracts a human-readable message from an unknown thrown value / failed
3
+ * response. Returns `undefined` when nothing usable is found so callers can
4
+ * fall back to a localized "unknown error" string instead of a hard-coded one.
5
+ */
6
+ export declare const getErrorMessage: (error: unknown) => string | undefined;
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Extracts a human-readable message from an unknown thrown value / failed
3
+ * response. Returns `undefined` when nothing usable is found so callers can
4
+ * fall back to a localized "unknown error" string instead of a hard-coded one.
5
+ */
6
+ export const getErrorMessage = (error) => {
7
+ if (error instanceof Error && error.message) {
8
+ return error.message;
9
+ }
10
+ if (typeof error !== "object" || error === null) {
11
+ return undefined;
12
+ }
13
+ const candidate = error;
14
+ for (const value of [
15
+ candidate.response?.data?.message,
16
+ candidate.response?.data?.error,
17
+ candidate.body?.message,
18
+ candidate.body?.error,
19
+ candidate.message,
20
+ candidate.statusText,
21
+ ]) {
22
+ if (typeof value === "string" && value.trim()) {
23
+ return value;
24
+ }
25
+ }
26
+ return undefined;
27
+ };
@@ -0,0 +1,2 @@
1
+ import Medusa from "@medusajs/js-sdk";
2
+ export declare const sdk: Medusa;
@@ -0,0 +1,13 @@
1
+ import Medusa from "@medusajs/js-sdk";
2
+ // The Admin's vite build defines these globals; `typeof` keeps the module
3
+ // loadable where they are not defined (e.g. unit tests).
4
+ export const sdk = new Medusa({
5
+ baseUrl: (typeof __BACKEND_URL__ === "undefined" ? undefined : __BACKEND_URL__) ?? "/",
6
+ auth: {
7
+ type: (typeof __AUTH_TYPE__ === "undefined" ? undefined : __AUTH_TYPE__) ??
8
+ "session",
9
+ jwtTokenStorageKey: (typeof __JWT_TOKEN_STORAGE_KEY__ === "undefined"
10
+ ? undefined
11
+ : __JWT_TOKEN_STORAGE_KEY__) || undefined,
12
+ },
13
+ });
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Documents part of the `@hartl-services/medusa-base/config` entry point: values a shop
3
+ * needs in `medusa-config.ts` or in a test, without loading the plugin itself.
4
+ */
5
+ export { createDefaultDocumentHtmlFactory } from "../templates/html-factory";
6
+ /**
7
+ * Placeholder environment values for `medusa build`. `medusa-config.ts` is
8
+ * evaluated at build time, where the runtime-only Documents PDF executable
9
+ * is not set; spread these under the real environment during the build.
10
+ */
11
+ export declare const DOCUMENTS_BUILD_PLACEHOLDERS: Readonly<Record<string, string>>;
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DOCUMENTS_BUILD_PLACEHOLDERS = exports.createDefaultDocumentHtmlFactory = void 0;
4
+ /**
5
+ * Documents part of the `@hartl-services/medusa-base/config` entry point: values a shop
6
+ * needs in `medusa-config.ts` or in a test, without loading the plugin itself.
7
+ */
8
+ var html_factory_1 = require("../templates/html-factory");
9
+ Object.defineProperty(exports, "createDefaultDocumentHtmlFactory", { enumerable: true, get: function () { return html_factory_1.createDefaultDocumentHtmlFactory; } });
10
+ /**
11
+ * Placeholder environment values for `medusa build`. `medusa-config.ts` is
12
+ * evaluated at build time, where the runtime-only Documents PDF executable
13
+ * is not set; spread these under the real environment during the build.
14
+ */
15
+ exports.DOCUMENTS_BUILD_PLACEHOLDERS = {
16
+ DOCUMENT_PDF_EXECUTABLE: "google-chrome",
17
+ };
@@ -0,0 +1,3 @@
1
+ import type { DocumentTemplateInput } from "../types";
2
+ import type { DocumentLayout } from "./layout";
3
+ export declare const renderFinancialDocument: (input: DocumentTemplateInput, layout: DocumentLayout, timeZone: string) => string;
@@ -0,0 +1,141 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.renderFinancialDocument = void 0;
4
+ const format_1 = require("./format");
5
+ const html_utils_1 = require("./html-utils");
6
+ const labelsByKind = {
7
+ cancellation: {
8
+ date: "Stornodatum",
9
+ recipient: "Stornorechnung an",
10
+ title: "Stornorechnung",
11
+ },
12
+ credit_note: {
13
+ date: "Gutschriftsdatum",
14
+ recipient: "Gutschrift an",
15
+ title: "Gutschrift",
16
+ },
17
+ invoice: {
18
+ date: "Rechnungsdatum",
19
+ recipient: "Rechnung an",
20
+ title: "Rechnung",
21
+ },
22
+ };
23
+ const renderAddress = (input) => {
24
+ const address = input.order.billing_address;
25
+ if (!address) {
26
+ return (0, html_utils_1.escapeHtml)(input.order.email);
27
+ }
28
+ return [
29
+ [address.company, address.first_name, address.last_name]
30
+ .filter((part) => Boolean(part))
31
+ .join(" "),
32
+ address.address_1,
33
+ address.address_2,
34
+ [address.postal_code, address.city]
35
+ .filter((part) => Boolean(part))
36
+ .join(" "),
37
+ address.country_code?.toUpperCase(),
38
+ ]
39
+ .filter((part) => Boolean(part))
40
+ .map(html_utils_1.escapeHtml)
41
+ .join("<br />");
42
+ };
43
+ const renderLines = (input, timeZone) => input.lines
44
+ .map((line) => {
45
+ const batchDetails = line.batch_allocations
46
+ .map((allocation) => `<div class="batch">Charge: ${(0, html_utils_1.escapeHtml)(allocation.lot_number)} · MHD: ${(0, html_utils_1.escapeHtml)((0, format_1.formatDate)(allocation.expiry_date, { timeZone }))} · ${(0, html_utils_1.escapeHtml)(allocation.quantity)}</div>`)
47
+ .join("");
48
+ return `<tr>
49
+ <td>
50
+ <strong>${(0, html_utils_1.escapeHtml)(line.title)}</strong>
51
+ ${line.sku ? `<div class="sku">SKU: ${(0, html_utils_1.escapeHtml)(line.sku)}</div>` : ""}
52
+ ${batchDetails}
53
+ </td>
54
+ <td class="number">${(0, html_utils_1.escapeHtml)(line.quantity)}</td>
55
+ <td class="number">${(0, html_utils_1.escapeHtml)((0, format_1.formatMoney)({ amount: line.unit_price.amount, currencyCode: line.unit_price.currency_code }))}</td>
56
+ <td class="number">${(0, html_utils_1.escapeHtml)((0, format_1.formatMoney)({ amount: line.total.amount, currencyCode: line.total.currency_code }))}</td>
57
+ </tr>`;
58
+ })
59
+ .join("");
60
+ const renderTaxCompliance = (input) => {
61
+ const evidence = input.order.tax_compliance;
62
+ if (!evidence ||
63
+ evidence.exemption_wording !==
64
+ "steuerfreie_innergemeinschaftliche_lieferung") {
65
+ return "";
66
+ }
67
+ return `<section class="tax-compliance">
68
+ <h2>Steuerliche Angaben</h2>
69
+ <strong>${(0, html_utils_1.escapeHtml)(evidence.customer_company_name)}</strong><br />
70
+ UID des Kunden: ${(0, html_utils_1.escapeHtml)(evidence.customer_vat_number)}<br />
71
+ Steuerfreie innergemeinschaftliche Lieferung
72
+ </section>`;
73
+ };
74
+ const renderDiscountTotal = (input) => {
75
+ const { amount, currency_code: currencyCode } = input.totals.discount_total;
76
+ const displayAmount = input.document.kind === "invoice" && Number(amount) > 0
77
+ ? `-${amount}`
78
+ : amount;
79
+ return (0, html_utils_1.escapeHtml)((0, format_1.formatMoney)({ amount: displayAmount, currencyCode }));
80
+ };
81
+ const formatTaxRate = (rate) => new Intl.NumberFormat(format_1.DEFAULT_FORMAT_LOCALE, {
82
+ maximumFractionDigits: 2,
83
+ style: "percent",
84
+ }).format(rate / 100);
85
+ const renderTaxRows = (input) => {
86
+ const { tax_breakdown: breakdown, tax_total: taxTotal } = input.totals;
87
+ const rows = breakdown.length > 0
88
+ ? breakdown.map((entry) => ({
89
+ label: `${entry.name} ${formatTaxRate(entry.rate)}`,
90
+ money: entry.tax_total,
91
+ }))
92
+ : [{ label: "Umsatzsteuer", money: taxTotal }];
93
+ return rows
94
+ .map(({ label, money }) => `<tr><td>${(0, html_utils_1.escapeHtml)(label)}</td><td class="number">${(0, html_utils_1.escapeHtml)((0, format_1.formatMoney)({ amount: money.amount, currencyCode: money.currency_code }))}</td></tr>`)
95
+ .join("");
96
+ };
97
+ const renderFinancialDocument = (input, layout, timeZone) => {
98
+ const labels = labelsByKind[input.document.kind];
99
+ const metadata = [
100
+ {
101
+ label: labels.date,
102
+ value: (0, format_1.formatDate)(input.document.issued_at, { timeZone }),
103
+ },
104
+ {
105
+ label: "Bestellung",
106
+ value: (0, html_utils_1.formatOrderReference)(input.order.display_id),
107
+ },
108
+ ];
109
+ if (input.document.kind !== "invoice") {
110
+ metadata.push({
111
+ label: "Ursprungsrechnung",
112
+ value: input.document.source_document_number ?? "-",
113
+ });
114
+ }
115
+ const body = `<section class="recipient">
116
+ <h2>${labels.recipient}</h2>
117
+ ${renderAddress(input)}
118
+ </section>
119
+ ${renderTaxCompliance(input)}
120
+ <table>
121
+ <thead><tr><th>Artikel</th><th class="number">Menge</th><th class="number">Einzelpreis</th><th class="number">Summe</th></tr></thead>
122
+ <tbody>${renderLines(input, timeZone)}</tbody>
123
+ </table>
124
+ <table class="totals">
125
+ <tbody>
126
+ <tr><td>Zwischensumme</td><td class="number">${(0, html_utils_1.escapeHtml)((0, format_1.formatMoney)({ amount: input.totals.subtotal.amount, currencyCode: input.totals.subtotal.currency_code }))}</td></tr>
127
+ <tr><td>Versand</td><td class="number">${(0, html_utils_1.escapeHtml)((0, format_1.formatMoney)({ amount: input.totals.shipping_total.amount, currencyCode: input.totals.shipping_total.currency_code }))}</td></tr>
128
+ <tr><td>Rabatt</td><td class="number">${renderDiscountTotal(input)}</td></tr>
129
+ ${renderTaxRows(input)}
130
+ <tr><td>Gesamt</td><td class="number">${(0, html_utils_1.escapeHtml)((0, format_1.formatMoney)({ amount: input.totals.total.amount, currencyCode: input.totals.total.currency_code }))}</td></tr>
131
+ </tbody>
132
+ </table>`;
133
+ return layout({
134
+ body,
135
+ documentTitle: labels.title,
136
+ metadata,
137
+ number: input.document.number,
138
+ pageTitle: labels.title,
139
+ });
140
+ };
141
+ exports.renderFinancialDocument = renderFinancialDocument;
@@ -0,0 +1,16 @@
1
+ export declare const DEFAULT_FORMAT_LOCALE = "de-AT";
2
+ export type FormatMoneyInput = {
3
+ readonly amount: number | string;
4
+ readonly currencyCode: string;
5
+ };
6
+ export type FormatMoneyOptions = {
7
+ readonly locale?: Intl.LocalesArgument;
8
+ };
9
+ export declare const formatMoney: ({ amount, currencyCode }: FormatMoneyInput, { locale }?: FormatMoneyOptions) => string;
10
+ export type FormatDateOptions = {
11
+ readonly locale?: Intl.LocalesArgument;
12
+ /** IANA time zone the date is shown in; there is deliberately no default. */
13
+ readonly timeZone: string;
14
+ readonly options?: Omit<Intl.DateTimeFormatOptions, "timeZone">;
15
+ };
16
+ export declare const formatDate: (value: string | Date, { locale, options, timeZone }: FormatDateOptions) => string;
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.formatDate = exports.formatMoney = exports.DEFAULT_FORMAT_LOCALE = void 0;
4
+ exports.DEFAULT_FORMAT_LOCALE = "de-AT";
5
+ const formatMoney = ({ amount, currencyCode }, { locale = exports.DEFAULT_FORMAT_LOCALE } = {}) => {
6
+ const numericAmount = Number(amount);
7
+ const normalizedCurrencyCode = currencyCode.toUpperCase();
8
+ const fallback = `${String(amount)} ${normalizedCurrencyCode}`;
9
+ if (!Number.isFinite(numericAmount)) {
10
+ return fallback;
11
+ }
12
+ try {
13
+ return new Intl.NumberFormat(locale, {
14
+ currency: normalizedCurrencyCode,
15
+ style: "currency",
16
+ }).format(numericAmount);
17
+ }
18
+ catch {
19
+ return fallback;
20
+ }
21
+ };
22
+ exports.formatMoney = formatMoney;
23
+ const formatDate = (value, { locale = exports.DEFAULT_FORMAT_LOCALE, options, timeZone }) => {
24
+ const date = value instanceof Date ? value : new Date(value);
25
+ if (Number.isNaN(date.getTime())) {
26
+ return String(value);
27
+ }
28
+ return new Intl.DateTimeFormat(locale, { timeZone, ...options }).format(date);
29
+ };
30
+ exports.formatDate = formatDate;
@@ -0,0 +1,11 @@
1
+ import type { DocumentHtmlFactory } from "../types";
2
+ /**
3
+ * The plugin's default document markup (German, locale de-AT). The legal
4
+ * sender comes with every render input (`input.merchant`, the base plugin's
5
+ * shop master data). `timeZone` is the IANA time zone in which printed dates
6
+ * are shown; the plugin passes its resolved `numbering.timeZone` so the date
7
+ * on a document matches the period its number was allocated in.
8
+ */
9
+ export declare const createDefaultDocumentHtmlFactory: ({ timeZone, }: {
10
+ timeZone: string;
11
+ }) => DocumentHtmlFactory;
@@ -0,0 +1,39 @@
1
+ "use strict";
2
+ /* eslint-disable @medusajs/use-medusa-error-not-generic-error -- Invalid render inputs are programmer errors, not HTTP responses. */
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.createDefaultDocumentHtmlFactory = void 0;
5
+ const layout_1 = require("./layout");
6
+ const financial_document_1 = require("./financial-document");
7
+ const packing_list_1 = require("./packing-list");
8
+ /**
9
+ * The plugin's default document markup (German, locale de-AT). The legal
10
+ * sender comes with every render input (`input.merchant`, the base plugin's
11
+ * shop master data). `timeZone` is the IANA time zone in which printed dates
12
+ * are shown; the plugin passes its resolved `numbering.timeZone` so the date
13
+ * on a document matches the period its number was allocated in.
14
+ */
15
+ const createDefaultDocumentHtmlFactory = ({ timeZone, }) => {
16
+ return (input) => {
17
+ const kind = input.document.kind;
18
+ switch (kind) {
19
+ case "invoice":
20
+ case "cancellation":
21
+ case "credit_note":
22
+ if ("totals" in input) {
23
+ return (0, financial_document_1.renderFinancialDocument)(input, (0, layout_1.createDocumentLayout)(input.merchant, true), timeZone);
24
+ }
25
+ break;
26
+ case "packing_list":
27
+ if ("fulfillment" in input) {
28
+ return (0, packing_list_1.renderPackingList)(input, (0, layout_1.createDocumentLayout)(input.merchant, false), timeZone);
29
+ }
30
+ break;
31
+ default: {
32
+ const unsupportedKind = kind;
33
+ throw new TypeError(`Unsupported document kind: ${unsupportedKind}`);
34
+ }
35
+ }
36
+ throw new TypeError(`Invalid input for document kind: ${kind}`);
37
+ };
38
+ };
39
+ exports.createDefaultDocumentHtmlFactory = createDefaultDocumentHtmlFactory;
@@ -0,0 +1,2 @@
1
+ export declare const escapeHtml: (value: string | number | null | undefined) => string;
2
+ export declare const formatOrderReference: (displayId: number | null) => string;
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.formatOrderReference = exports.escapeHtml = void 0;
4
+ const escapeHtml = (value) => String(value ?? "")
5
+ .replaceAll("&", "&amp;")
6
+ .replaceAll("<", "&lt;")
7
+ .replaceAll(">", "&gt;")
8
+ .replaceAll('"', "&quot;")
9
+ .replaceAll("'", "&#039;");
10
+ exports.escapeHtml = escapeHtml;
11
+ const formatOrderReference = (displayId) => displayId === null ? "-" : `#${displayId}`;
12
+ exports.formatOrderReference = formatOrderReference;
@@ -0,0 +1,17 @@
1
+ import type { DocumentMerchant } from "../types";
2
+ export type DocumentLayoutInput = {
3
+ readonly body: string;
4
+ readonly documentTitle: string;
5
+ readonly metadata: readonly {
6
+ readonly label: string;
7
+ readonly value: string;
8
+ }[];
9
+ readonly number: string;
10
+ readonly pageTitle: string;
11
+ };
12
+ export type DocumentLayout = (input: DocumentLayoutInput) => string;
13
+ /**
14
+ * `includeLegalDetails` adds UID, company register, contact and bank details
15
+ * to the footer (financial documents); packing lists show only the name.
16
+ */
17
+ export declare const createDocumentLayout: (merchant: DocumentMerchant, includeLegalDetails: boolean) => DocumentLayout;
@@ -0,0 +1,96 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createDocumentLayout = void 0;
4
+ const html_utils_1 = require("./html-utils");
5
+ const formatCountryName = (countryCode) => new Intl.DisplayNames("de", { type: "region" }).of(countryCode.toUpperCase()) ?? countryCode.toUpperCase();
6
+ const renderMerchantAddress = (merchant) => [
7
+ merchant.address_line1,
8
+ merchant.address_line2,
9
+ [merchant.postal_code, merchant.city].join(" "),
10
+ formatCountryName(merchant.country_code),
11
+ ]
12
+ .filter((part) => Boolean(part))
13
+ .map(html_utils_1.escapeHtml)
14
+ .join("<br />");
15
+ /** Legal footer: name, UID, company register, contact and bank details that are set. */
16
+ const renderMerchantFooter = (merchant, includeLegalDetails) => {
17
+ if (!includeLegalDetails) {
18
+ return (0, html_utils_1.escapeHtml)(merchant.legal_name);
19
+ }
20
+ const register = [
21
+ merchant.company_register_number
22
+ ? `Firmenbuchnummer: ${merchant.company_register_number}`
23
+ : null,
24
+ merchant.company_register_court
25
+ ? `Firmenbuchgericht: ${merchant.company_register_court}`
26
+ : null,
27
+ ];
28
+ const lines = [
29
+ [
30
+ merchant.legal_name,
31
+ merchant.vat_number ? `UID: ${merchant.vat_number}` : null,
32
+ ...register,
33
+ ],
34
+ [merchant.email, merchant.phone, merchant.website],
35
+ [
36
+ merchant.iban ? `IBAN: ${merchant.iban}` : null,
37
+ merchant.bic ? `BIC: ${merchant.bic}` : null,
38
+ ],
39
+ ];
40
+ return lines
41
+ .map((parts) => parts
42
+ .filter((part) => Boolean(part))
43
+ .map(html_utils_1.escapeHtml)
44
+ .join(" · "))
45
+ .filter(Boolean)
46
+ .join("<br />");
47
+ };
48
+ const renderMetadata = (metadata) => metadata
49
+ .map(({ label, value }) => `<div><strong>${(0, html_utils_1.escapeHtml)(label)}:</strong> ${(0, html_utils_1.escapeHtml)(value)}</div>`)
50
+ .join("");
51
+ /**
52
+ * `includeLegalDetails` adds UID, company register, contact and bank details
53
+ * to the footer (financial documents); packing lists show only the name.
54
+ */
55
+ const createDocumentLayout = (merchant, includeLegalDetails) => ({ body, documentTitle, metadata, number, pageTitle }) => `<!doctype html>
56
+ <html lang="de">
57
+ <head>
58
+ <meta charset="utf-8" />
59
+ <title>${(0, html_utils_1.escapeHtml)(pageTitle)} ${(0, html_utils_1.escapeHtml)(number)}</title>
60
+ <style>
61
+ @page { margin: 18mm; }
62
+ body { color: #1f2937; font-family: Arial, sans-serif; font-size: 11px; line-height: 1.45; }
63
+ h1 { font-size: 24px; margin: 0 0 6px; }
64
+ h2 { break-after: avoid; font-size: 12px; margin: 22px 0 6px; page-break-after: avoid; text-transform: uppercase; }
65
+ .header { border-bottom: 2px solid #111827; display: flex; gap: 32px; justify-content: space-between; padding-bottom: 16px; }
66
+ .document-metadata { display: flex; flex-wrap: wrap; gap: 6px 28px; margin: 18px 0 22px; }
67
+ .document-metadata div { min-width: 180px; }
68
+ .muted, .sku, .batch { color: #6b7280; }
69
+ .batch, .packing-batch { font-size: 10px; margin-top: 2px; }
70
+ .packing-batch { display: flex; gap: 12px; justify-content: space-between; }
71
+ table { border-collapse: collapse; page-break-inside: auto; width: 100%; }
72
+ thead { display: table-header-group; }
73
+ tfoot { display: table-footer-group; }
74
+ tbody { page-break-inside: auto; }
75
+ tr { break-inside: avoid; page-break-inside: avoid; }
76
+ th { background: #f3f4f6; font-size: 10px; text-align: left; text-transform: uppercase; }
77
+ th, td { border-bottom: 1px solid #d1d5db; padding: 8px 6px; vertical-align: top; }
78
+ .number { text-align: right; white-space: nowrap; }
79
+ .recipient, .tax-compliance, .totals { break-inside: avoid; page-break-inside: avoid; }
80
+ .totals { margin-left: auto; margin-top: 16px; width: 260px; }
81
+ .totals td { border: 0; padding: 3px 0; }
82
+ .totals tr:last-child td { border-top: 2px solid #111827; font-size: 14px; font-weight: 700; padding-top: 7px; }
83
+ footer { border-top: 1px solid #d1d5db; break-inside: avoid; color: #6b7280; font-size: 9px; margin-top: 28px; page-break-inside: avoid; padding-top: 10px; }
84
+ </style>
85
+ </head>
86
+ <body>
87
+ <section class="header">
88
+ <div><h1>${(0, html_utils_1.escapeHtml)(documentTitle)}</h1><div class="muted">${(0, html_utils_1.escapeHtml)(number)}</div></div>
89
+ <div><strong>${(0, html_utils_1.escapeHtml)(merchant.legal_name)}</strong><br />${renderMerchantAddress(merchant)}</div>
90
+ </section>
91
+ <section class="document-metadata">${renderMetadata(metadata)}</section>
92
+ ${body}
93
+ <footer>${renderMerchantFooter(merchant, includeLegalDetails)}</footer>
94
+ </body>
95
+ </html>`;
96
+ exports.createDocumentLayout = createDocumentLayout;
@@ -0,0 +1,3 @@
1
+ import type { PackingListTemplateInput } from "../types";
2
+ import type { DocumentLayout } from "./layout";
3
+ export declare const renderPackingList: (input: PackingListTemplateInput, layout: DocumentLayout, timeZone: string) => string;
@@ -0,0 +1,49 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.renderPackingList = void 0;
4
+ const format_1 = require("./format");
5
+ const html_utils_1 = require("./html-utils");
6
+ const renderBatchAllocations = (line, timeZone) => {
7
+ if (line.batch_allocations.length === 0) {
8
+ return '<span class="muted">-</span>';
9
+ }
10
+ return line.batch_allocations
11
+ .map((allocation) => `<div class="packing-batch">
12
+ <strong>${(0, html_utils_1.escapeHtml)(allocation.lot_number)}</strong>
13
+ <span>MHD: ${(0, format_1.formatDate)(allocation.expiry_date, { timeZone })}</span>
14
+ <span>Menge: ${(0, html_utils_1.escapeHtml)(allocation.quantity)}</span>
15
+ </div>`)
16
+ .join("");
17
+ };
18
+ const renderLines = (input, timeZone) => input.lines
19
+ .map((line) => `<tr>
20
+ <td>
21
+ <strong>${(0, html_utils_1.escapeHtml)(line.title)}</strong>
22
+ ${line.sku ? `<div class="sku">SKU: ${(0, html_utils_1.escapeHtml)(line.sku)}</div>` : ""}
23
+ </td>
24
+ <td>${renderBatchAllocations(line, timeZone)}</td>
25
+ <td class="number">${(0, html_utils_1.escapeHtml)(line.quantity)}</td>
26
+ </tr>`)
27
+ .join("");
28
+ const renderPackingList = (input, layout, timeZone) => layout({
29
+ body: `<table>
30
+ <thead><tr><th>Bezeichnung</th><th>Charge</th><th class="number">Benötigte Menge</th></tr></thead>
31
+ <tbody>${renderLines(input, timeZone)}</tbody>
32
+ </table>`,
33
+ documentTitle: "Packliste",
34
+ metadata: [
35
+ {
36
+ label: "Bestellung",
37
+ value: (0, html_utils_1.formatOrderReference)(input.order.display_id),
38
+ },
39
+ { label: "Fulfillment", value: input.fulfillment.id },
40
+ {
41
+ label: "Erstellungsdatum",
42
+ value: (0, format_1.formatDate)(input.document.generated_at, { timeZone }),
43
+ },
44
+ { label: "Lagerplatz", value: input.fulfillment.location_name },
45
+ ],
46
+ number: input.document.number,
47
+ pageTitle: "Packliste",
48
+ });
49
+ exports.renderPackingList = renderPackingList;
@@ -0,0 +1 @@
1
+ export type * from "@hartl-services/medusa-food-supplements-contracts/types/documents-admin";
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1 @@
1
+ export type { StoreDocument as DocumentSummary } from "@hartl-services/medusa-food-supplements-contracts/types/documents-store";