@hartl-services/medusa-base 2.5.0 → 2.6.1

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 (287) hide show
  1. package/.medusa/server/src/admin/admin-components/features/plugin-features/components/ImageSettingInput.js +48 -0
  2. package/{dist → .medusa/server/src/admin}/admin-components/features/plugin-features/components/PluginActionsSection.js +3 -2
  3. package/.medusa/server/src/admin/admin-components/features/plugin-features/components/PluginFeaturesSettingsPage.js +17 -0
  4. package/.medusa/server/src/admin/admin-components/features/plugin-features/components/PluginPageShell.js +20 -0
  5. package/{dist → .medusa/server/src/admin}/admin-components/features/plugin-features/components/PluginSettingsForm.js +16 -3
  6. package/{dist → .medusa/server/src/admin}/admin-components/features/plugin-features/hooks/usePluginFeatureEnabled.d.ts +5 -1
  7. package/{dist → .medusa/server/src/admin}/admin-components/features/plugin-features/hooks/usePluginFeatures.d.ts +20 -4
  8. package/{dist → .medusa/server/src/admin}/admin-components/features/plugin-features/hooks/usePluginFeatures.js +1 -1
  9. package/{dist → .medusa/server/src/admin}/admin-components/features/plugin-features/hooks/usePluginSettingsForm.d.ts +5 -1
  10. package/{dist → .medusa/server/src/admin}/admin-components/features/plugin-features/lib/action-runs.d.ts +1 -1
  11. package/{dist → .medusa/server/src/admin}/admin-components/features/plugin-features/lib/action-runs.js +3 -2
  12. package/{dist → .medusa/server/src/admin}/admin-components/features/plugin-features/lib/plugin-features-admin-client.d.ts +20 -4
  13. package/{dist → .medusa/server/src/admin}/admin-components/features/plugin-features/lib/plugin-features-admin-client.js +1 -1
  14. package/{dist → .medusa/server/src/admin}/admin-components/features/plugin-features/lib/settings-draft.d.ts +17 -2
  15. package/{dist → .medusa/server/src/admin}/admin-components/features/plugin-features/lib/settings-draft.js +33 -1
  16. package/{dist → .medusa/server/src/admin}/admin-components/i18n/texts.d.ts +3 -0
  17. package/{dist → .medusa/server/src/admin}/admin-components/i18n/texts.js +3 -0
  18. package/.medusa/server/src/admin/admin-components/index.d.ts +36 -0
  19. package/.medusa/server/src/admin/admin-components/index.js +37 -0
  20. package/.medusa/server/src/admin/admin-components/shared/lib/date-input.d.ts +8 -0
  21. package/.medusa/server/src/admin/admin-components/shared/lib/date-input.js +43 -0
  22. package/.medusa/server/src/admin/admin-components/shared/lib/errors.d.ts +9 -0
  23. package/{dist/admin-components → .medusa/server/src/admin/admin-components/shared}/lib/errors.js +4 -6
  24. package/.medusa/server/src/admin/admin-components/shared/lib/file-validation.d.ts +24 -0
  25. package/.medusa/server/src/admin/admin-components/shared/lib/file-validation.js +18 -0
  26. package/.medusa/server/src/admin/admin-components/shared/lib/format.d.ts +32 -0
  27. package/.medusa/server/src/admin/admin-components/shared/lib/format.js +77 -0
  28. package/.medusa/server/src/admin/admin-components/shared/lib/pdf-preview.d.ts +16 -0
  29. package/.medusa/server/src/admin/admin-components/shared/lib/pdf-preview.js +31 -0
  30. package/.medusa/server/src/admin/admin-components/shared/lib/pdf.d.ts +6 -0
  31. package/.medusa/server/src/admin/admin-components/shared/lib/pdf.js +13 -0
  32. package/.medusa/server/src/admin/admin-components/shared/lib/use-debounced-value.d.ts +2 -0
  33. package/.medusa/server/src/admin/admin-components/shared/lib/use-debounced-value.js +10 -0
  34. package/.medusa/server/src/admin/admin-components/shared/lib/use-pdf-preview.d.ts +24 -0
  35. package/.medusa/server/src/admin/admin-components/shared/lib/use-pdf-preview.js +47 -0
  36. package/.medusa/server/src/admin/admin-components/shared/ui/AdminDatePicker.d.ts +8 -0
  37. package/.medusa/server/src/admin/admin-components/shared/ui/AdminDatePicker.js +9 -0
  38. package/.medusa/server/src/admin/admin-components/shared/ui/BackLink.d.ts +8 -0
  39. package/.medusa/server/src/admin/admin-components/shared/ui/BackLink.js +5 -0
  40. package/.medusa/server/src/admin/admin-components/shared/ui/DateRangeFilter.d.ts +20 -0
  41. package/.medusa/server/src/admin/admin-components/shared/ui/DateRangeFilter.js +17 -0
  42. package/.medusa/server/src/admin/admin-components/shared/ui/FilePickerButton.d.ts +14 -0
  43. package/.medusa/server/src/admin/admin-components/shared/ui/FilePickerButton.js +14 -0
  44. package/.medusa/server/src/admin/admin-components/shared/ui/MappedStatusBadge.d.ts +17 -0
  45. package/.medusa/server/src/admin/admin-components/shared/ui/MappedStatusBadge.js +12 -0
  46. package/.medusa/server/src/admin/admin-components/shared/ui/OffsetTablePagination.d.ts +15 -0
  47. package/.medusa/server/src/admin/admin-components/shared/ui/OffsetTablePagination.js +19 -0
  48. package/.medusa/server/src/admin/admin-components/shared/ui/PdfPreviewModal.d.ts +20 -0
  49. package/.medusa/server/src/admin/admin-components/shared/ui/PdfPreviewModal.js +7 -0
  50. package/.medusa/server/src/admin/admin-components/shared/ui/PluginFeatureRoute.d.ts +19 -0
  51. package/.medusa/server/src/admin/admin-components/shared/ui/PluginFeatureRoute.js +16 -0
  52. package/.medusa/server/src/admin/admin-components/shared/ui/QueryState.d.ts +24 -0
  53. package/.medusa/server/src/admin/admin-components/shared/ui/QueryState.js +23 -0
  54. package/.medusa/server/src/admin/admin-components/shared/ui/SearchableReferenceField.d.ts +63 -0
  55. package/.medusa/server/src/admin/admin-components/shared/ui/SearchableReferenceField.js +84 -0
  56. package/.medusa/server/src/admin/admin-components/shared/ui/SectionHeader.d.ts +15 -0
  57. package/.medusa/server/src/admin/admin-components/shared/ui/SectionHeader.js +13 -0
  58. package/.medusa/server/src/admin/admin-components/shared/ui/mapped-status.d.ts +6 -0
  59. package/.medusa/server/src/admin/admin-components/shared/ui/mapped-status.js +10 -0
  60. package/.medusa/server/src/admin/admin-components/shared/ui/offset-pagination.d.ts +17 -0
  61. package/.medusa/server/src/admin/admin-components/shared/ui/offset-pagination.js +15 -0
  62. package/.medusa/server/src/admin/admin-components/shared/ui/reference-results-state.d.ts +16 -0
  63. package/.medusa/server/src/admin/admin-components/shared/ui/reference-results-state.js +13 -0
  64. package/.medusa/server/src/admin/admin-components/shared/ui/rich-text-editor/InsertMenu.d.ts +8 -0
  65. package/.medusa/server/src/admin/admin-components/shared/ui/rich-text-editor/InsertMenu.js +10 -0
  66. package/.medusa/server/src/admin/admin-components/shared/ui/rich-text-editor/LinkPrompt.d.ts +14 -0
  67. package/.medusa/server/src/admin/admin-components/shared/ui/rich-text-editor/LinkPrompt.js +26 -0
  68. package/.medusa/server/src/admin/admin-components/shared/ui/rich-text-editor/RichTextEditor.d.ts +15 -0
  69. package/.medusa/server/src/admin/admin-components/shared/ui/rich-text-editor/RichTextEditor.js +8 -0
  70. package/.medusa/server/src/admin/admin-components/shared/ui/rich-text-editor/RichTextToolbar.d.ts +10 -0
  71. package/.medusa/server/src/admin/admin-components/shared/ui/rich-text-editor/RichTextToolbar.js +49 -0
  72. package/.medusa/server/src/admin/admin-components/shared/ui/rich-text-editor/SlashMenu.d.ts +11 -0
  73. package/.medusa/server/src/admin/admin-components/shared/ui/rich-text-editor/SlashMenu.js +44 -0
  74. package/.medusa/server/src/admin/admin-components/shared/ui/rich-text-editor/build-extensions.d.ts +8 -0
  75. package/.medusa/server/src/admin/admin-components/shared/ui/rich-text-editor/build-extensions.js +43 -0
  76. package/.medusa/server/src/admin/admin-components/shared/ui/rich-text-editor/drag-handle.d.ts +15 -0
  77. package/.medusa/server/src/admin/admin-components/shared/ui/rich-text-editor/drag-handle.js +161 -0
  78. package/.medusa/server/src/admin/admin-components/shared/ui/rich-text-editor/drag-target.d.ts +30 -0
  79. package/.medusa/server/src/admin/admin-components/shared/ui/rich-text-editor/drag-target.js +47 -0
  80. package/.medusa/server/src/admin/admin-components/shared/ui/rich-text-editor/editor-styles.d.ts +6 -0
  81. package/.medusa/server/src/admin/admin-components/shared/ui/rich-text-editor/editor-styles.js +46 -0
  82. package/.medusa/server/src/admin/admin-components/shared/ui/rich-text-editor/index.d.ts +9 -0
  83. package/.medusa/server/src/admin/admin-components/shared/ui/rich-text-editor/index.js +6 -0
  84. package/.medusa/server/src/admin/admin-components/shared/ui/rich-text-editor/link-href.d.ts +8 -0
  85. package/.medusa/server/src/admin/admin-components/shared/ui/rich-text-editor/link-href.js +21 -0
  86. package/.medusa/server/src/admin/admin-components/shared/ui/rich-text-editor/link-policy.d.ts +13 -0
  87. package/.medusa/server/src/admin/admin-components/shared/ui/rich-text-editor/link-policy.js +20 -0
  88. package/.medusa/server/src/admin/admin-components/shared/ui/rich-text-editor/slash-command.d.ts +13 -0
  89. package/.medusa/server/src/admin/admin-components/shared/ui/rich-text-editor/slash-command.js +60 -0
  90. package/.medusa/server/src/admin/admin-components/shared/ui/rich-text-editor/slash-items.d.ts +25 -0
  91. package/.medusa/server/src/admin/admin-components/shared/ui/rich-text-editor/slash-items.js +10 -0
  92. package/.medusa/server/src/admin/admin-components/shared/ui/rich-text-editor/tiptap.d.ts +7 -0
  93. package/.medusa/server/src/admin/admin-components/shared/ui/rich-text-editor/tiptap.js +7 -0
  94. package/.medusa/server/src/admin/admin-components/shared/ui/rich-text-editor/use-rich-text-editor.d.ts +44 -0
  95. package/.medusa/server/src/admin/admin-components/shared/ui/rich-text-editor/use-rich-text-editor.js +37 -0
  96. package/.medusa/server/src/admin/index.js +4519 -1447
  97. package/.medusa/server/src/admin/index.mjs +4521 -1452
  98. package/.medusa/server/src/api/admin/email/attachments/[id]/mail-kinds/route.js +16 -0
  99. package/.medusa/server/src/api/admin/email/attachments/[id]/route.js +15 -0
  100. package/.medusa/server/src/api/admin/email/attachments/[id]/versions/[version_id]/download/route.js +16 -0
  101. package/.medusa/server/src/api/admin/email/attachments/[id]/versions/route.js +41 -0
  102. package/.medusa/server/src/api/admin/email/attachments/route.js +21 -0
  103. package/.medusa/server/src/api/admin/email/templates/[kind]/preview/route.js +31 -0
  104. package/.medusa/server/src/api/admin/email/templates/[kind]/route.js +28 -0
  105. package/.medusa/server/src/api/admin/email/templates/[kind]/send-test/route.js +179 -0
  106. package/.medusa/server/src/api/admin/email/templates/[kind]/test-sources/route.js +19 -0
  107. package/.medusa/server/src/api/admin/email/templates/route.js +15 -0
  108. package/.medusa/server/src/api/admin/plugin-features/[plugin_key]/actions/[action_key]/route.js +2 -2
  109. package/.medusa/server/src/api/admin/plugin-features/[plugin_key]/actions/[action_key]/runs/route.js +2 -2
  110. package/.medusa/server/src/api/admin/plugin-features/[plugin_key]/route.js +2 -2
  111. package/.medusa/server/src/api/admin/plugin-features/[plugin_key]/settings/route.js +2 -2
  112. package/.medusa/server/src/api/admin/plugin-features/route.js +2 -2
  113. package/.medusa/server/src/api/attachment-download-response.js +12 -0
  114. package/.medusa/server/src/api/email-template-response.js +43 -0
  115. package/.medusa/server/src/api/middlewares.js +75 -17
  116. package/.medusa/server/src/api/plugin-actions.js +6 -5
  117. package/.medusa/server/src/api/plugin-features-http.js +4 -9
  118. package/.medusa/server/src/api/store/carts/[id]/completion-check/route.js +2 -2
  119. package/.medusa/server/src/api/store/plugin-features/[plugin_key]/route.js +2 -2
  120. package/.medusa/server/src/api/store/plugin-features/route.js +2 -2
  121. package/.medusa/server/src/documents/plugin-features.js +1 -7
  122. package/.medusa/server/src/documents/templates/financial-document.js +12 -11
  123. package/.medusa/server/src/documents/templates/html-factory.js +1 -1
  124. package/.medusa/server/src/documents/templates/html-utils.js +4 -10
  125. package/.medusa/server/src/documents/templates/layout.js +30 -11
  126. package/.medusa/server/src/documents/templates/packing-list.js +8 -7
  127. package/.medusa/server/src/documents/utils/document-render-settings.js +9 -6
  128. package/.medusa/server/src/email/application/handle-customer-verification-event.js +8 -3
  129. package/.medusa/server/src/email/application/handle-invite-event.js +8 -3
  130. package/.medusa/server/src/email/application/handle-password-reset-event.js +8 -3
  131. package/.medusa/server/src/email/application/notification-attachments.js +86 -0
  132. package/.medusa/server/src/email/application/template-data-from-order.js +339 -0
  133. package/.medusa/server/src/email/config/index.js +5 -29
  134. package/.medusa/server/src/email/domain/business-keys.js +5 -5
  135. package/.medusa/server/src/email/domain/documents-fact-fingerprint.js +3 -3
  136. package/.medusa/server/src/email/domain/order-summary.js +21 -27
  137. package/.medusa/server/src/email/domain/refund-summary.js +7 -12
  138. package/.medusa/server/src/email/domain/return-summary.js +32 -38
  139. package/.medusa/server/src/email/domain/shipment-summary.js +22 -28
  140. package/.medusa/server/src/email/plugin-features.js +2 -10
  141. package/.medusa/server/src/email/rendering/calendar-dates.js +19 -0
  142. package/.medusa/server/src/email/rendering/default-templates.js +99 -682
  143. package/.medusa/server/src/email/rendering/email-html.js +189 -0
  144. package/.medusa/server/src/email/rendering/load-email-shop-details.js +14 -12
  145. package/.medusa/server/src/email/rendering/render-email.js +46 -13
  146. package/.medusa/server/src/email/rendering/resolve-shop-configuration.js +3 -14
  147. package/.medusa/server/src/email/templates/blocks/dynamic-blocks.js +427 -0
  148. package/.medusa/server/src/email/templates/blocks/placeholders.js +71 -0
  149. package/.medusa/server/src/email/templates/blocks/render-document.js +137 -0
  150. package/.medusa/server/src/email/templates/code-override.js +18 -0
  151. package/.medusa/server/src/email/templates/defaults/documents.js +129 -0
  152. package/.medusa/server/src/email/templates/defaults/subjects.js +62 -0
  153. package/.medusa/server/src/email/templates/defaults/texts.js +42 -0
  154. package/.medusa/server/src/email/templates/index.js +22 -0
  155. package/.medusa/server/src/email/templates/load-template.js +39 -0
  156. package/.medusa/server/src/email/templates/preview.js +33 -0
  157. package/.medusa/server/src/email/templates/render.js +70 -0
  158. package/.medusa/server/src/email/templates/sample-data.js +165 -0
  159. package/.medusa/server/src/email/templates/types.js +3 -0
  160. package/.medusa/server/src/email/templates/validate.js +113 -0
  161. package/.medusa/server/src/files/config/index.js +6 -9
  162. package/.medusa/server/src/migration-scripts/move-logo-to-shop-appearance.js +53 -0
  163. package/.medusa/server/src/modules/documents/domain/cancellation-snapshot.js +4 -3
  164. package/.medusa/server/src/modules/documents/domain/merchant.js +4 -3
  165. package/.medusa/server/src/modules/documents/domain/options.js +3 -5
  166. package/.medusa/server/src/modules/documents/domain/tax-breakdown.js +4 -7
  167. package/.medusa/server/src/modules/documents/service.js +12 -33
  168. package/.medusa/server/src/modules/email/domain/attachment.js +22 -8
  169. package/.medusa/server/src/modules/email/migrations/Migration20261009083539.js +80 -0
  170. package/.medusa/server/src/modules/email/migrations/Migration20261009100654.js +17 -0
  171. package/.medusa/server/src/modules/email/models/email-attachment-document-version.js +39 -0
  172. package/.medusa/server/src/modules/email/models/email-attachment-document.js +27 -0
  173. package/.medusa/server/src/modules/email/models/email-template.js +25 -0
  174. package/.medusa/server/src/modules/email/service.js +370 -93
  175. package/.medusa/server/src/modules/plugin-features/domain/plugin-settings.js +9 -11
  176. package/.medusa/server/src/modules/plugin-features/service.js +2 -1
  177. package/.medusa/server/src/providers/s3-cache/cache/cache-manager.js +3 -3
  178. package/.medusa/server/src/providers/s3-cache/s3-object-store.js +3 -9
  179. package/.medusa/server/src/providers/smtp/service.js +13 -13
  180. package/.medusa/server/src/public/descriptor.js +16 -18
  181. package/.medusa/server/src/public/enforcement.js +29 -1
  182. package/.medusa/server/src/public/index.js +8 -2
  183. package/.medusa/server/src/public/module-access.js +9 -2
  184. package/.medusa/server/src/public/shop-master-data.js +109 -18
  185. package/.medusa/server/src/shared/lib/coerce.js +26 -0
  186. package/.medusa/server/src/shared/lib/collections.js +19 -0
  187. package/.medusa/server/src/shared/lib/dates.js +43 -0
  188. package/.medusa/server/src/shared/lib/errors.js +11 -0
  189. package/.medusa/server/src/shared/lib/hash.js +8 -0
  190. package/.medusa/server/src/shared/lib/index.js +29 -0
  191. package/.medusa/server/src/shared/lib/logging.js +61 -0
  192. package/.medusa/server/src/shared/lib/money.js +47 -0
  193. package/.medusa/server/src/shared/lib/text.js +53 -0
  194. package/.medusa/server/src/shared/lib/transaction.js +58 -0
  195. package/.medusa/server/src/{api → shared/lib}/wire-response.js +1 -1
  196. package/.medusa/server/src/shop-config/options.js +3 -5
  197. package/.medusa/server/src/subscribers/packing-list-fulfillment-canceled.js +4 -6
  198. package/.medusa/server/src/workflows/documents/issue-invoice-after-shipment.js +10 -12
  199. package/.medusa/server/src/workflows/documents/issue-packing-list.js +5 -6
  200. package/.medusa/server/src/workflows/documents/reconcile-order-cancellation.js +6 -8
  201. package/.medusa/server/src/workflows/email/dispatch-email-message.js +11 -41
  202. package/.medusa/server/src/workflows/email/prepare-order-received-email.js +2 -2
  203. package/.medusa/server/src/workflows/hooks/complete-cart-participants.js +4 -8
  204. package/README.md +427 -54
  205. package/dist/documents/templates/financial-document.js +11 -10
  206. package/dist/documents/templates/html-factory.d.ts +1 -1
  207. package/dist/documents/templates/html-factory.js +1 -1
  208. package/dist/documents/templates/html-utils.d.ts +0 -1
  209. package/dist/documents/templates/html-utils.js +3 -9
  210. package/dist/documents/templates/layout.js +29 -10
  211. package/dist/documents/templates/packing-list.js +7 -6
  212. package/dist/documents/types/documents.d.ts +7 -1
  213. package/dist/email/config/index.js +4 -28
  214. package/dist/email/types/shop-configuration.d.ts +6 -5
  215. package/dist/files/config/index.js +5 -8
  216. package/dist/modules/documents/domain/options.js +2 -4
  217. package/dist/public/descriptor.js +15 -17
  218. package/dist/public/enforcement.d.ts +21 -1
  219. package/dist/public/enforcement.js +28 -0
  220. package/dist/public/index.d.ts +3 -2
  221. package/dist/public/index.js +7 -1
  222. package/dist/public/module-access.d.ts +8 -0
  223. package/dist/public/module-access.js +8 -1
  224. package/dist/public/shop-master-data.d.ts +22 -5
  225. package/dist/public/shop-master-data.js +108 -17
  226. package/dist/public/types.d.ts +10 -2
  227. package/dist/shared/lib/coerce.d.ts +19 -0
  228. package/dist/shared/lib/coerce.js +25 -0
  229. package/dist/shared/lib/collections.d.ts +3 -0
  230. package/dist/shared/lib/collections.js +18 -0
  231. package/dist/shared/lib/dates.d.ts +12 -0
  232. package/dist/shared/lib/dates.js +42 -0
  233. package/dist/shared/lib/errors.d.ts +2 -0
  234. package/dist/shared/lib/errors.js +10 -0
  235. package/dist/shared/lib/hash.d.ts +2 -0
  236. package/dist/shared/lib/hash.js +7 -0
  237. package/dist/shared/lib/index.d.ts +10 -0
  238. package/dist/shared/lib/index.js +28 -0
  239. package/dist/shared/lib/logging.d.ts +26 -0
  240. package/dist/shared/lib/logging.js +60 -0
  241. package/dist/shared/lib/money.d.ts +13 -0
  242. package/dist/shared/lib/money.js +46 -0
  243. package/dist/shared/lib/text.d.ts +19 -0
  244. package/dist/shared/lib/text.js +52 -0
  245. package/dist/shared/lib/transaction.d.ts +26 -0
  246. package/dist/shared/lib/transaction.js +57 -0
  247. package/dist/shared/lib/wire-response.d.ts +6 -0
  248. package/dist/shared/lib/wire-response.js +9 -0
  249. package/dist/shop-config/options.js +2 -4
  250. package/package.json +19 -4
  251. package/.medusa/server/src/api/admin/email/terms-versions/[id]/download/route.js +0 -16
  252. package/.medusa/server/src/api/admin/email/terms-versions/route.js +0 -47
  253. package/.medusa/server/src/api/terms-download-response.js +0 -12
  254. package/.medusa/server/src/modules/email/models/email-terms-version.js +0 -37
  255. package/dist/admin-components/features/plugin-features/components/ImageSettingInput.js +0 -42
  256. package/dist/admin-components/features/plugin-features/components/PluginFeaturesSettingsPage.js +0 -16
  257. package/dist/admin-components/features/plugin-features/components/PluginPageShell.js +0 -20
  258. package/dist/admin-components/features/plugin-features/lib/image-upload.d.ts +0 -6
  259. package/dist/admin-components/features/plugin-features/lib/image-upload.js +0 -17
  260. package/dist/admin-components/index.d.ts +0 -14
  261. package/dist/admin-components/index.js +0 -14
  262. package/dist/admin-components/lib/errors.d.ts +0 -6
  263. /package/{dist → .medusa/server/src/admin}/admin-components/features/plugin-features/components/ImageSettingInput.d.ts +0 -0
  264. /package/{dist → .medusa/server/src/admin}/admin-components/features/plugin-features/components/PluginActionsSection.d.ts +0 -0
  265. /package/{dist → .medusa/server/src/admin}/admin-components/features/plugin-features/components/PluginDetailPage.d.ts +0 -0
  266. /package/{dist → .medusa/server/src/admin}/admin-components/features/plugin-features/components/PluginDetailPage.js +0 -0
  267. /package/{dist → .medusa/server/src/admin}/admin-components/features/plugin-features/components/PluginFeatureGate.d.ts +0 -0
  268. /package/{dist → .medusa/server/src/admin}/admin-components/features/plugin-features/components/PluginFeatureGate.js +0 -0
  269. /package/{dist → .medusa/server/src/admin}/admin-components/features/plugin-features/components/PluginFeatureSections.d.ts +0 -0
  270. /package/{dist → .medusa/server/src/admin}/admin-components/features/plugin-features/components/PluginFeatureSections.js +0 -0
  271. /package/{dist → .medusa/server/src/admin}/admin-components/features/plugin-features/components/PluginFeaturesCard.d.ts +0 -0
  272. /package/{dist → .medusa/server/src/admin}/admin-components/features/plugin-features/components/PluginFeaturesCard.js +0 -0
  273. /package/{dist → .medusa/server/src/admin}/admin-components/features/plugin-features/components/PluginFeaturesSettingsPage.d.ts +0 -0
  274. /package/{dist → .medusa/server/src/admin}/admin-components/features/plugin-features/components/PluginHubCard.d.ts +0 -0
  275. /package/{dist → .medusa/server/src/admin}/admin-components/features/plugin-features/components/PluginHubCard.js +0 -0
  276. /package/{dist → .medusa/server/src/admin}/admin-components/features/plugin-features/components/PluginPageShell.d.ts +0 -0
  277. /package/{dist → .medusa/server/src/admin}/admin-components/features/plugin-features/components/PluginSettingsForm.d.ts +0 -0
  278. /package/{dist → .medusa/server/src/admin}/admin-components/features/plugin-features/components/PluginStatusChips.d.ts +0 -0
  279. /package/{dist → .medusa/server/src/admin}/admin-components/features/plugin-features/components/PluginStatusChips.js +0 -0
  280. /package/{dist → .medusa/server/src/admin}/admin-components/features/plugin-features/hooks/usePluginFeatureEnabled.js +0 -0
  281. /package/{dist → .medusa/server/src/admin}/admin-components/features/plugin-features/hooks/usePluginSettingsForm.js +0 -0
  282. /package/{dist → .medusa/server/src/admin}/admin-components/features/plugin-features/lib/plugin-paths.d.ts +0 -0
  283. /package/{dist → .medusa/server/src/admin}/admin-components/features/plugin-features/lib/plugin-paths.js +0 -0
  284. /package/{dist → .medusa/server/src/admin}/admin-components/features/plugin-features/queries/pluginFeatureKeys.d.ts +0 -0
  285. /package/{dist → .medusa/server/src/admin}/admin-components/features/plugin-features/queries/pluginFeatureKeys.js +0 -0
  286. /package/{dist/admin-components → .medusa/server/src/admin/admin-components/shared}/lib/sdk.d.ts +0 -0
  287. /package/{dist/admin-components → .medusa/server/src/admin/admin-components/shared}/lib/sdk.js +0 -0
@@ -0,0 +1,48 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Button, Hint, Text } from "@medusajs/ui";
3
+ import { useMutation } from "@tanstack/react-query";
4
+ import { useState } from "react";
5
+ import { texts } from "../../../i18n/texts";
6
+ import { validateFile } from "../../../shared/lib/file-validation";
7
+ import { sdk } from "../../../shared/lib/sdk";
8
+ import { FilePickerButton } from "../../../shared/ui/FilePickerButton";
9
+ /** Largest image an `image` setting accepts in the Admin. */
10
+ const SETTING_IMAGE_MAX_BYTES = 2 * 1024 * 1024;
11
+ const SETTING_IMAGE_OPTIONS = {
12
+ maxBytes: SETTING_IMAGE_MAX_BYTES,
13
+ // Gmail and Outlook do not display SVG or WebP in e-mails.
14
+ types: ["image/png", "image/jpeg"],
15
+ messages: {
16
+ wrongType: "Bitte eine PNG- oder JPG-Datei auswählen.",
17
+ empty: "Die Bilddatei ist leer.",
18
+ tooLarge: "Die Bilddatei darf maximal 2 MiB groß sein.",
19
+ },
20
+ };
21
+ /**
22
+ * Uploads an image to the public File Module storage and hands its URL to
23
+ * the settings draft; the form stores it on save like any other value.
24
+ */
25
+ export const ImageSettingInput = ({ id, hintId, label, value, disabled, onChange, }) => {
26
+ const [error, setError] = useState(null);
27
+ const upload = useMutation({
28
+ mutationFn: async (file) => {
29
+ const { files } = await sdk.admin.upload.create({ files: [file] });
30
+ const url = files[0]?.url;
31
+ if (!url) {
32
+ throw new Error("upload returned no file");
33
+ }
34
+ return url;
35
+ },
36
+ onSuccess: (url) => onChange(url),
37
+ onError: () => setError(texts.settings.imageUploadFailed),
38
+ });
39
+ const busy = disabled || upload.isPending;
40
+ const selectFile = (file) => {
41
+ const invalid = validateFile(file, SETTING_IMAGE_OPTIONS);
42
+ setError(invalid);
43
+ if (!invalid) {
44
+ upload.mutate(file);
45
+ }
46
+ };
47
+ return (_jsxs("div", { className: "grid gap-2", children: [value && (_jsx("div", { className: "bg-ui-bg-subtle flex items-center justify-center rounded-md border p-4", children: _jsx("img", { src: value, alt: texts.settings.imagePreviewAlt(label), className: "max-h-24 max-w-full object-contain" }) })), _jsxs("div", { className: "flex items-center gap-2", children: [_jsx(FilePickerButton, { id: id, "aria-describedby": hintId, accept: "image/png,image/jpeg", label: value ? texts.settings.imageReplace : texts.settings.imageUpload, isLoading: upload.isPending, disabled: busy, onFileSelected: selectFile }), value && (_jsx(Button, { type: "button", size: "small", variant: "transparent", disabled: busy, onClick: () => onChange(""), children: texts.settings.imageRemove })), !value && (_jsx(Text, { size: "small", className: "text-ui-fg-muted", children: texts.settings.imageNone }))] }), error && _jsx(Hint, { variant: "error", children: error })] }));
48
+ };
@@ -1,7 +1,8 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { Button, Container, Heading, Text, toast, usePrompt } from "@medusajs/ui";
2
+ import { Button, Container, Text, toast, usePrompt } from "@medusajs/ui";
3
3
  import { useEffect, useRef } from "react";
4
4
  import { texts } from "../../../i18n/texts";
5
+ import { SectionHeader } from "../../../shared/ui/SectionHeader";
5
6
  import { useLatestPluginActionRun, useRunPluginAction, } from "../hooks/usePluginFeatures";
6
7
  import { formatRunTime, progressCount, progressPercent, runTransition, summarizeActionResult, } from "../lib/action-runs";
7
8
  /** Progress of a running run: label, "current / total", bar and start time. */
@@ -62,5 +63,5 @@ export const PluginActionsSection = ({ plugin }) => {
62
63
  }
63
64
  mutation.mutate(action);
64
65
  };
65
- return (_jsxs(Container, { className: "divide-y p-0", children: [_jsx("div", { className: "px-6 py-4", children: _jsx(Heading, { level: "h2", children: texts.sections.actions }) }), plugin.actions.map((action) => (_jsx(PluginActionRow, { pluginKey: plugin.plugin_key, action: action, starting: startingKey === action.key, blocked: mutation.isPending && startingKey !== action.key, onRun: (entry) => void run(entry) }, action.key)))] }));
66
+ return (_jsxs(Container, { className: "divide-y p-0", children: [_jsx(SectionHeader, { title: texts.sections.actions }), plugin.actions.map((action) => (_jsx(PluginActionRow, { pluginKey: plugin.plugin_key, action: action, starting: startingKey === action.key, blocked: mutation.isPending && startingKey !== action.key, onRun: (entry) => void run(entry) }, action.key)))] }));
66
67
  };
@@ -0,0 +1,17 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Button, Container, Text } from "@medusajs/ui";
3
+ import { texts } from "../../../i18n/texts";
4
+ import { SectionHeader } from "../../../shared/ui/SectionHeader";
5
+ import { usePluginFeatures } from "../hooks/usePluginFeatures";
6
+ import { PluginHubCard } from "./PluginHubCard";
7
+ /**
8
+ * Hub: one card per installed plugin. Plugins that cannot be switched off
9
+ * (the shop master data) come first; the rest keep the server's order.
10
+ */
11
+ export const PluginFeaturesSettingsPage = () => {
12
+ const query = usePluginFeatures();
13
+ return (_jsxs("div", { className: "flex flex-col gap-y-3", children: [_jsx(Container, { className: "p-0", children: _jsx(SectionHeader, { description: texts.page.description, level: "h1", title: texts.page.title }) }), query.isPending ? (_jsx(Container, { children: _jsx(Text, { className: "text-ui-fg-subtle", children: texts.states.loading }) })) : query.isError ? (_jsxs(Container, { className: "flex flex-wrap items-center justify-between gap-3", children: [_jsx(Text, { className: "text-ui-fg-error", children: texts.states.error }), _jsx(Button, { size: "small", variant: "secondary", isLoading: query.isFetching, onClick: () => void query.refetch(), children: texts.states.retry })] })) : query.data.plugins.length === 0 ? (_jsx(Container, { children: _jsx(Text, { className: "text-ui-fg-subtle", children: texts.states.empty }) })) : ([
14
+ ...query.data.plugins.filter((plugin) => !plugin.switchable),
15
+ ...query.data.plugins.filter((plugin) => plugin.switchable),
16
+ ].map((plugin) => (_jsx(PluginHubCard, { plugin: plugin }, plugin.plugin_key))))] }));
17
+ };
@@ -0,0 +1,20 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { Button, Container, Heading, Text } from "@medusajs/ui";
3
+ import { texts } from "../../../i18n/texts";
4
+ import { BackLink } from "../../../shared/ui/BackLink";
5
+ import { usePluginFeature } from "../hooks/usePluginFeatures";
6
+ import { PLUGIN_HUB_PATH } from "../lib/plugin-paths";
7
+ import { PluginStatusChips } from "./PluginStatusChips";
8
+ const isNotFound = (error) => typeof error === "object" &&
9
+ error !== null &&
10
+ error.status === 404;
11
+ /**
12
+ * Frame of a plugin's page: back link to the hub, the plugin's label,
13
+ * description and status, then `children`. Shows loading, not-installed and
14
+ * error states instead of `children`.
15
+ */
16
+ export const PluginPageShell = ({ pluginKey, children }) => {
17
+ const query = usePluginFeature(pluginKey);
18
+ const plugin = query.data?.plugin;
19
+ return (_jsxs("div", { className: "flex flex-col gap-y-3", children: [_jsx(BackLink, { label: texts.detail.back, to: PLUGIN_HUB_PATH }), plugin ? (_jsxs(_Fragment, { children: [_jsxs(Container, { className: "px-6 py-4", children: [_jsx(Heading, { level: "h1", children: plugin.label }), plugin.description && (_jsx(Text, { className: "text-ui-fg-subtle", children: plugin.description })), _jsx(PluginStatusChips, { plugin: plugin })] }), children] })) : query.isPending ? (_jsx(Container, { children: _jsx(Text, { className: "text-ui-fg-subtle", children: texts.states.loading }) })) : isNotFound(query.error) ? (_jsx(Container, { children: _jsx(Text, { className: "text-ui-fg-subtle", children: texts.states.notFound }) })) : (_jsxs(Container, { className: "flex flex-wrap items-center justify-between gap-3", children: [_jsx(Text, { className: "text-ui-fg-error", children: texts.states.error }), _jsx(Button, { size: "small", variant: "secondary", isLoading: query.isFetching, onClick: () => void query.refetch(), children: texts.states.retry })] }))] }));
20
+ };
@@ -1,6 +1,7 @@
1
- import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { Alert, Button, Container, Heading, Hint, Input, Label, Select, Switch, Text, } from "@medusajs/ui";
3
3
  import { texts } from "../../../i18n/texts";
4
+ import { groupSettings, isHexColor, normalizeColorInput, } from "../lib/settings-draft";
4
5
  import { usePluginSettingsForm } from "../hooks/usePluginSettingsForm";
5
6
  import { ImageSettingInput } from "./ImageSettingInput";
6
7
  const fieldId = (pluginKey, key) => `plugin-setting-${pluginKey}-${key}`;
@@ -19,6 +20,13 @@ const boundsText = (setting) => setting.min !== null && setting.max !== null
19
20
  : setting.max !== null
20
21
  ? texts.settings.numberMax(setting.max)
21
22
  : undefined;
23
+ const ColorSettingInput = ({ id, hintId, label, value, invalid, disabled, onChange, }) => {
24
+ const hasColor = isHexColor(value.trim());
25
+ return (_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Input, { id: id, "aria-describedby": hintId, "aria-invalid": invalid, className: "flex-1 font-mono", type: "text", autoComplete: "off", spellCheck: false, placeholder: texts.settings.colorPlaceholder, value: value, disabled: disabled, onChange: (event) => onChange(normalizeColorInput(event.target.value)) }), _jsx("input", { type: "color", "aria-label": texts.settings.colorPickLabel(label),
26
+ // An empty value shows the browser's black; dim it so it does not
27
+ // read as a chosen color.
28
+ className: `h-8 w-10 shrink-0 cursor-pointer rounded-md border border-ui-border-base bg-ui-bg-field p-1 disabled:cursor-not-allowed ${hasColor ? "" : "opacity-30"}`, value: hasColor ? value.trim() : "#000000", disabled: disabled, onChange: (event) => onChange(normalizeColorInput(event.target.value)) })] }));
29
+ };
22
30
  const SettingField = ({ pluginKey, setting, invalidatesLabels, value, invalid, disabled, onChange, }) => {
23
31
  const id = fieldId(pluginKey, setting.key);
24
32
  const hintId = `${id}-hint`;
@@ -28,14 +36,19 @@ const SettingField = ({ pluginKey, setting, invalidatesLabels, value, invalid, d
28
36
  ? texts.settings.secretClearUndoLabel(setting.label)
29
37
  : texts.settings.secretClearLabel(setting.label), onClick: () => onChange(clearPending ? "" : null), children: clearPending
30
38
  ? texts.settings.secretClearUndo
31
- : texts.settings.secretClear }))] })) : setting.type === "select" ? (_jsxs(Select, { value: typeof value === "string" ? value : "", disabled: disabled, onValueChange: (next) => onChange(next), children: [_jsx(Select.Trigger, { id: id, "aria-describedby": hintId, children: _jsx(Select.Value, { placeholder: texts.settings.selectPlaceholder }) }), _jsx(Select.Content, { children: setting.options.map((option) => (_jsx(Select.Item, { value: option.value, children: option.label }, option.value))) })] })) : setting.type === "image" ? (_jsx(ImageSettingInput, { id: id, hintId: hintId, label: setting.label, value: typeof value === "string" ? value : "", disabled: disabled, onChange: (url) => onChange(url) })) : setting.type === "number" ? (_jsx(Input, { id: id, "aria-describedby": hintId, "aria-invalid": invalid, type: "number", step: "any", min: setting.min ?? undefined, max: setting.max ?? undefined, value: typeof value === "string" ? value : "", disabled: disabled, onChange: (event) => onChange(event.target.value, event.target.validity.badInput) })) : (_jsx(Input, { id: id, "aria-describedby": hintId, "aria-invalid": invalid, type: setting.type === "url" ? "url" : "text", value: typeof value === "string" ? value : "", disabled: disabled, onChange: (event) => onChange(event.target.value) })), _jsxs("div", { id: hintId, className: "grid gap-1", children: [setting.description && (_jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: setting.description })), clearPending && (_jsx(Hint, { variant: "info", children: texts.settings.secretClearPending })), invalidatesLabels && (_jsx(Text, { size: "small", className: "text-ui-fg-muted", children: texts.settings.invalidates(invalidatesLabels) })), bounds && !invalid && (_jsx(Text, { size: "small", className: "text-ui-fg-muted", children: bounds })), invalid && (_jsx(Hint, { variant: "error", children: bounds ?? texts.settings.invalidNumber }))] })] }));
39
+ : texts.settings.secretClear }))] })) : setting.type === "select" ? (_jsxs(Select, { value: typeof value === "string" ? value : "", disabled: disabled, onValueChange: (next) => onChange(next), children: [_jsx(Select.Trigger, { id: id, "aria-describedby": hintId, children: _jsx(Select.Value, { placeholder: texts.settings.selectPlaceholder }) }), _jsx(Select.Content, { children: setting.options.map((option) => (_jsx(Select.Item, { value: option.value, children: option.label }, option.value))) })] })) : setting.type === "image" ? (_jsx(ImageSettingInput, { id: id, hintId: hintId, label: setting.label, value: typeof value === "string" ? value : "", disabled: disabled, onChange: (url) => onChange(url) })) : setting.type === "color" ? (_jsx(ColorSettingInput, { id: id, hintId: hintId, label: setting.label, value: typeof value === "string" ? value : "", invalid: invalid, disabled: disabled, onChange: (next) => onChange(next) })) : setting.type === "number" ? (_jsx(Input, { id: id, "aria-describedby": hintId, "aria-invalid": invalid, type: "number", step: "any", min: setting.min ?? undefined, max: setting.max ?? undefined, value: typeof value === "string" ? value : "", disabled: disabled, onChange: (event) => onChange(event.target.value, event.target.validity.badInput) })) : (_jsx(Input, { id: id, "aria-describedby": hintId, "aria-invalid": invalid, type: setting.type === "url" ? "url" : "text", value: typeof value === "string" ? value : "", disabled: disabled, onChange: (event) => onChange(event.target.value) })), _jsxs("div", { id: hintId, className: "grid gap-1", children: [setting.description && (_jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: setting.description })), clearPending && (_jsx(Hint, { variant: "info", children: texts.settings.secretClearPending })), invalidatesLabels && (_jsx(Text, { size: "small", className: "text-ui-fg-muted", children: texts.settings.invalidates(invalidatesLabels) })), bounds && !invalid && (_jsx(Text, { size: "small", className: "text-ui-fg-muted", children: bounds })), invalid && (_jsx(Hint, { variant: "error", children: setting.type === "color"
40
+ ? texts.settings.invalidColor
41
+ : (bounds ?? texts.settings.invalidNumber) }))] })] }));
32
42
  };
33
43
  export const PluginSettingsForm = ({ plugin }) => {
34
44
  const form = usePluginSettingsForm(plugin);
35
45
  const pending = form.mutation.isPending;
46
+ const sections = groupSettings(plugin.settings);
36
47
  const hasTextFields = plugin.settings.some((setting) => setting.type !== "boolean" &&
37
48
  setting.type !== "secret" &&
38
49
  setting.type !== "select" &&
39
50
  setting.type !== "image");
40
- return (_jsxs(Container, { className: "divide-y p-0", "aria-busy": pending, children: [_jsxs("div", { className: "px-6 py-4", children: [_jsx(Heading, { level: "h2", children: texts.sections.settings }), hasTextFields && (_jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: texts.settings.clearHint }))] }), _jsxs("form", { onSubmit: form.submit, className: "grid gap-5 px-6 py-5", children: [!plugin.configured && (_jsx(Alert, { variant: "warning", children: texts.settings.missing(missingLabels(plugin)) })), plugin.settings.map((setting) => (_jsx(SettingField, { pluginKey: plugin.plugin_key, setting: setting, invalidatesLabels: invalidatesLabels(plugin, setting), value: form.draft[setting.key], invalid: form.invalid.includes(setting.key), disabled: pending, onChange: (value, badInput) => form.setValue(setting.key, value, badInput) }, setting.key))), _jsx("div", { className: "flex justify-end", children: _jsx(Button, { type: "submit", size: "small", isLoading: pending, disabled: !form.dirty || form.invalid.length > 0 || pending, children: texts.settings.save }) })] })] }));
51
+ return (_jsxs(Container, { className: "divide-y p-0", "aria-busy": pending, children: [_jsxs("div", { className: "px-6 py-4", children: [_jsx(Heading, { level: "h2", children: texts.sections.settings }), hasTextFields && (_jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: texts.settings.clearHint }))] }), _jsxs("form", { onSubmit: form.submit, className: "grid gap-5 px-6 py-5", children: [!plugin.configured && (_jsx(Alert, { variant: "warning", children: texts.settings.missing(missingLabels(plugin)) })), sections.map((section, index) => (_jsxs("div", { className: section.group !== null && index > 0
52
+ ? "grid gap-5 border-t border-ui-border-base pt-5"
53
+ : "grid gap-5", children: [section.group !== null && (_jsx(Heading, { level: "h3", children: section.group })), section.settings.map((setting) => (_jsx(SettingField, { pluginKey: plugin.plugin_key, setting: setting, invalidatesLabels: invalidatesLabels(plugin, setting), value: form.draft[setting.key], invalid: form.invalid.includes(setting.key), disabled: pending, onChange: (value, badInput) => form.setValue(setting.key, value, badInput) }, setting.key)))] }, section.settings[0].key))), _jsx("div", { className: "flex justify-end", children: _jsx(Button, { type: "submit", size: "small", isLoading: pending, disabled: !form.dirty || form.invalid.length > 0 || pending, children: texts.settings.save }) })] })] }));
41
54
  };
@@ -41,6 +41,7 @@ export declare const pluginFeatureEnabledQueryOptions: (pluginKey: string, featu
41
41
  key: string;
42
42
  label: string;
43
43
  description: string | null;
44
+ group: string | null;
44
45
  required: boolean;
45
46
  is_set: boolean;
46
47
  source: "default" | "stored" | "config" | "none";
@@ -56,6 +57,7 @@ export declare const pluginFeatureEnabledQueryOptions: (pluginKey: string, featu
56
57
  key: string;
57
58
  label: string;
58
59
  description: string | null;
60
+ group: string | null;
59
61
  required: boolean;
60
62
  is_set: boolean;
61
63
  source: "default" | "stored" | "config" | "none";
@@ -69,17 +71,19 @@ export declare const pluginFeatureEnabledQueryOptions: (pluginKey: string, featu
69
71
  key: string;
70
72
  label: string;
71
73
  description: string | null;
74
+ group: string | null;
72
75
  required: boolean;
73
76
  is_set: boolean;
74
77
  source: "default" | "stored" | "config" | "none";
75
78
  invalidates: string[];
76
79
  } | {
77
- type: "string" | "boolean" | "url" | "image";
80
+ type: "string" | "boolean" | "color" | "url" | "image";
78
81
  default: string | number | boolean | null;
79
82
  value: string | number | boolean | null;
80
83
  key: string;
81
84
  label: string;
82
85
  description: string | null;
86
+ group: string | null;
83
87
  required: boolean;
84
88
  is_set: boolean;
85
89
  source: "default" | "stored" | "config" | "none";
@@ -21,6 +21,7 @@ export declare function usePluginFeatures(): import("@tanstack/react-query").Use
21
21
  key: string;
22
22
  label: string;
23
23
  description: string | null;
24
+ group: string | null;
24
25
  required: boolean;
25
26
  is_set: boolean;
26
27
  source: "default" | "stored" | "config" | "none";
@@ -36,6 +37,7 @@ export declare function usePluginFeatures(): import("@tanstack/react-query").Use
36
37
  key: string;
37
38
  label: string;
38
39
  description: string | null;
40
+ group: string | null;
39
41
  required: boolean;
40
42
  is_set: boolean;
41
43
  source: "default" | "stored" | "config" | "none";
@@ -49,17 +51,19 @@ export declare function usePluginFeatures(): import("@tanstack/react-query").Use
49
51
  key: string;
50
52
  label: string;
51
53
  description: string | null;
54
+ group: string | null;
52
55
  required: boolean;
53
56
  is_set: boolean;
54
57
  source: "default" | "stored" | "config" | "none";
55
58
  invalidates: string[];
56
59
  } | {
57
- type: "string" | "boolean" | "url" | "image";
60
+ type: "string" | "boolean" | "color" | "url" | "image";
58
61
  default: string | number | boolean | null;
59
62
  value: string | number | boolean | null;
60
63
  key: string;
61
64
  label: string;
62
65
  description: string | null;
66
+ group: string | null;
63
67
  required: boolean;
64
68
  is_set: boolean;
65
69
  source: "default" | "stored" | "config" | "none";
@@ -108,6 +112,7 @@ export declare function usePluginFeature(pluginKey: string | undefined): import(
108
112
  key: string;
109
113
  label: string;
110
114
  description: string | null;
115
+ group: string | null;
111
116
  required: boolean;
112
117
  is_set: boolean;
113
118
  source: "default" | "stored" | "config" | "none";
@@ -123,6 +128,7 @@ export declare function usePluginFeature(pluginKey: string | undefined): import(
123
128
  key: string;
124
129
  label: string;
125
130
  description: string | null;
131
+ group: string | null;
126
132
  required: boolean;
127
133
  is_set: boolean;
128
134
  source: "default" | "stored" | "config" | "none";
@@ -136,17 +142,19 @@ export declare function usePluginFeature(pluginKey: string | undefined): import(
136
142
  key: string;
137
143
  label: string;
138
144
  description: string | null;
145
+ group: string | null;
139
146
  required: boolean;
140
147
  is_set: boolean;
141
148
  source: "default" | "stored" | "config" | "none";
142
149
  invalidates: string[];
143
150
  } | {
144
- type: "string" | "boolean" | "url" | "image";
151
+ type: "string" | "boolean" | "color" | "url" | "image";
145
152
  default: string | number | boolean | null;
146
153
  value: string | number | boolean | null;
147
154
  key: string;
148
155
  label: string;
149
156
  description: string | null;
157
+ group: string | null;
150
158
  required: boolean;
151
159
  is_set: boolean;
152
160
  source: "default" | "stored" | "config" | "none";
@@ -189,6 +197,7 @@ export declare function useUpdatePluginFeatures(): import("@tanstack/react-query
189
197
  key: string;
190
198
  label: string;
191
199
  description: string | null;
200
+ group: string | null;
192
201
  required: boolean;
193
202
  is_set: boolean;
194
203
  source: "default" | "stored" | "config" | "none";
@@ -204,6 +213,7 @@ export declare function useUpdatePluginFeatures(): import("@tanstack/react-query
204
213
  key: string;
205
214
  label: string;
206
215
  description: string | null;
216
+ group: string | null;
207
217
  required: boolean;
208
218
  is_set: boolean;
209
219
  source: "default" | "stored" | "config" | "none";
@@ -217,17 +227,19 @@ export declare function useUpdatePluginFeatures(): import("@tanstack/react-query
217
227
  key: string;
218
228
  label: string;
219
229
  description: string | null;
230
+ group: string | null;
220
231
  required: boolean;
221
232
  is_set: boolean;
222
233
  source: "default" | "stored" | "config" | "none";
223
234
  invalidates: string[];
224
235
  } | {
225
- type: "string" | "boolean" | "url" | "image";
236
+ type: "string" | "boolean" | "color" | "url" | "image";
226
237
  default: string | number | boolean | null;
227
238
  value: string | number | boolean | null;
228
239
  key: string;
229
240
  label: string;
230
241
  description: string | null;
242
+ group: string | null;
231
243
  required: boolean;
232
244
  is_set: boolean;
233
245
  source: "default" | "stored" | "config" | "none";
@@ -274,6 +286,7 @@ export declare function useUpdatePluginSettings(pluginKey: string): import("@tan
274
286
  key: string;
275
287
  label: string;
276
288
  description: string | null;
289
+ group: string | null;
277
290
  required: boolean;
278
291
  is_set: boolean;
279
292
  source: "default" | "stored" | "config" | "none";
@@ -289,6 +302,7 @@ export declare function useUpdatePluginSettings(pluginKey: string): import("@tan
289
302
  key: string;
290
303
  label: string;
291
304
  description: string | null;
305
+ group: string | null;
292
306
  required: boolean;
293
307
  is_set: boolean;
294
308
  source: "default" | "stored" | "config" | "none";
@@ -302,17 +316,19 @@ export declare function useUpdatePluginSettings(pluginKey: string): import("@tan
302
316
  key: string;
303
317
  label: string;
304
318
  description: string | null;
319
+ group: string | null;
305
320
  required: boolean;
306
321
  is_set: boolean;
307
322
  source: "default" | "stored" | "config" | "none";
308
323
  invalidates: string[];
309
324
  } | {
310
- type: "string" | "boolean" | "url" | "image";
325
+ type: "string" | "boolean" | "color" | "url" | "image";
311
326
  default: string | number | boolean | null;
312
327
  value: string | number | boolean | null;
313
328
  key: string;
314
329
  label: string;
315
330
  description: string | null;
331
+ group: string | null;
316
332
  required: boolean;
317
333
  is_set: boolean;
318
334
  source: "default" | "stored" | "config" | "none";
@@ -1,7 +1,7 @@
1
1
  import { toast } from "@medusajs/ui";
2
2
  import { useMutation, useQuery, useQueryClient, } from "@tanstack/react-query";
3
3
  import { texts } from "../../../i18n/texts";
4
- import { getErrorMessage } from "../../../lib/errors";
4
+ import { getErrorMessage } from "../../../shared/lib/errors";
5
5
  import { listPluginActionRuns, listPluginFeatures, retrievePluginFeatures, runPluginAction, updatePluginFeatures, updatePluginSettings, } from "../lib/plugin-features-admin-client";
6
6
  import { pluginFeatureKeys } from "../queries/pluginFeatureKeys";
7
7
  const isConflict = (error) => typeof error === "object" &&
@@ -30,6 +30,7 @@ export declare function usePluginSettingsForm(plugin: AdminPluginFeatures): {
30
30
  key: string;
31
31
  label: string;
32
32
  description: string | null;
33
+ group: string | null;
33
34
  required: boolean;
34
35
  is_set: boolean;
35
36
  source: "default" | "stored" | "config" | "none";
@@ -45,6 +46,7 @@ export declare function usePluginSettingsForm(plugin: AdminPluginFeatures): {
45
46
  key: string;
46
47
  label: string;
47
48
  description: string | null;
49
+ group: string | null;
48
50
  required: boolean;
49
51
  is_set: boolean;
50
52
  source: "default" | "stored" | "config" | "none";
@@ -58,17 +60,19 @@ export declare function usePluginSettingsForm(plugin: AdminPluginFeatures): {
58
60
  key: string;
59
61
  label: string;
60
62
  description: string | null;
63
+ group: string | null;
61
64
  required: boolean;
62
65
  is_set: boolean;
63
66
  source: "default" | "stored" | "config" | "none";
64
67
  invalidates: string[];
65
68
  } | {
66
- type: "string" | "boolean" | "url" | "image";
69
+ type: "string" | "boolean" | "color" | "url" | "image";
67
70
  default: string | number | boolean | null;
68
71
  value: string | number | boolean | null;
69
72
  key: string;
70
73
  label: string;
71
74
  description: string | null;
75
+ group: string | null;
72
76
  required: boolean;
73
77
  is_set: boolean;
74
78
  source: "default" | "stored" | "config" | "none";
@@ -9,7 +9,7 @@ export declare const summarizeActionResult: (result: unknown) => string | null;
9
9
  export declare const progressPercent: (progress: PluginActionRunProgress | null) => number | null;
10
10
  /** "3 / 10" or "3" (unknown total); `null` without progress. */
11
11
  export declare const progressCount: (progress: PluginActionRunProgress | null) => string | null;
12
- /** Short German date and time. */
12
+ /** German date and time. */
13
13
  export declare const formatRunTime: (iso: string | null) => string;
14
14
  export type RunTransition = "completed" | "failed" | null;
15
15
  /**
@@ -1,3 +1,4 @@
1
+ import { formatDateTime } from "../../../shared/lib/format";
1
2
  const SUMMARY_MAX_LENGTH = 200;
2
3
  const cut = (text) => text.length > SUMMARY_MAX_LENGTH
3
4
  ? `${text.slice(0, SUMMARY_MAX_LENGTH - 1)}…`
@@ -48,7 +49,7 @@ export const progressCount = (progress) => {
48
49
  ? String(progress.current)
49
50
  : `${progress.current} / ${progress.total}`;
50
51
  };
51
- /** Short German date and time. */
52
+ /** German date and time. */
52
53
  export const formatRunTime = (iso) => {
53
54
  if (!iso) {
54
55
  return "";
@@ -56,7 +57,7 @@ export const formatRunTime = (iso) => {
56
57
  const date = new Date(iso);
57
58
  return Number.isNaN(date.getTime())
58
59
  ? iso
59
- : date.toLocaleString("de-AT", { dateStyle: "short", timeStyle: "short" });
60
+ : formatDateTime(date);
60
61
  };
61
62
  /**
62
63
  * Whether the latest run just finished while this page watched it: the same
@@ -22,6 +22,7 @@ export declare const listPluginFeatures: () => Promise<{
22
22
  key: string;
23
23
  label: string;
24
24
  description: string | null;
25
+ group: string | null;
25
26
  required: boolean;
26
27
  is_set: boolean;
27
28
  source: "default" | "stored" | "config" | "none";
@@ -37,6 +38,7 @@ export declare const listPluginFeatures: () => Promise<{
37
38
  key: string;
38
39
  label: string;
39
40
  description: string | null;
41
+ group: string | null;
40
42
  required: boolean;
41
43
  is_set: boolean;
42
44
  source: "default" | "stored" | "config" | "none";
@@ -50,17 +52,19 @@ export declare const listPluginFeatures: () => Promise<{
50
52
  key: string;
51
53
  label: string;
52
54
  description: string | null;
55
+ group: string | null;
53
56
  required: boolean;
54
57
  is_set: boolean;
55
58
  source: "default" | "stored" | "config" | "none";
56
59
  invalidates: string[];
57
60
  } | {
58
- type: "string" | "boolean" | "url" | "image";
61
+ type: "string" | "boolean" | "color" | "url" | "image";
59
62
  default: string | number | boolean | null;
60
63
  value: string | number | boolean | null;
61
64
  key: string;
62
65
  label: string;
63
66
  description: string | null;
67
+ group: string | null;
64
68
  required: boolean;
65
69
  is_set: boolean;
66
70
  source: "default" | "stored" | "config" | "none";
@@ -102,6 +106,7 @@ export declare const retrievePluginFeatures: (pluginKey: string) => Promise<{
102
106
  key: string;
103
107
  label: string;
104
108
  description: string | null;
109
+ group: string | null;
105
110
  required: boolean;
106
111
  is_set: boolean;
107
112
  source: "default" | "stored" | "config" | "none";
@@ -117,6 +122,7 @@ export declare const retrievePluginFeatures: (pluginKey: string) => Promise<{
117
122
  key: string;
118
123
  label: string;
119
124
  description: string | null;
125
+ group: string | null;
120
126
  required: boolean;
121
127
  is_set: boolean;
122
128
  source: "default" | "stored" | "config" | "none";
@@ -130,17 +136,19 @@ export declare const retrievePluginFeatures: (pluginKey: string) => Promise<{
130
136
  key: string;
131
137
  label: string;
132
138
  description: string | null;
139
+ group: string | null;
133
140
  required: boolean;
134
141
  is_set: boolean;
135
142
  source: "default" | "stored" | "config" | "none";
136
143
  invalidates: string[];
137
144
  } | {
138
- type: "string" | "boolean" | "url" | "image";
145
+ type: "string" | "boolean" | "color" | "url" | "image";
139
146
  default: string | number | boolean | null;
140
147
  value: string | number | boolean | null;
141
148
  key: string;
142
149
  label: string;
143
150
  description: string | null;
151
+ group: string | null;
144
152
  required: boolean;
145
153
  is_set: boolean;
146
154
  source: "default" | "stored" | "config" | "none";
@@ -182,6 +190,7 @@ export declare const updatePluginFeatures: (payload: UpdatePluginFeaturesPayload
182
190
  key: string;
183
191
  label: string;
184
192
  description: string | null;
193
+ group: string | null;
185
194
  required: boolean;
186
195
  is_set: boolean;
187
196
  source: "default" | "stored" | "config" | "none";
@@ -197,6 +206,7 @@ export declare const updatePluginFeatures: (payload: UpdatePluginFeaturesPayload
197
206
  key: string;
198
207
  label: string;
199
208
  description: string | null;
209
+ group: string | null;
200
210
  required: boolean;
201
211
  is_set: boolean;
202
212
  source: "default" | "stored" | "config" | "none";
@@ -210,17 +220,19 @@ export declare const updatePluginFeatures: (payload: UpdatePluginFeaturesPayload
210
220
  key: string;
211
221
  label: string;
212
222
  description: string | null;
223
+ group: string | null;
213
224
  required: boolean;
214
225
  is_set: boolean;
215
226
  source: "default" | "stored" | "config" | "none";
216
227
  invalidates: string[];
217
228
  } | {
218
- type: "string" | "boolean" | "url" | "image";
229
+ type: "string" | "boolean" | "color" | "url" | "image";
219
230
  default: string | number | boolean | null;
220
231
  value: string | number | boolean | null;
221
232
  key: string;
222
233
  label: string;
223
234
  description: string | null;
235
+ group: string | null;
224
236
  required: boolean;
225
237
  is_set: boolean;
226
238
  source: "default" | "stored" | "config" | "none";
@@ -262,6 +274,7 @@ export declare const updatePluginSettings: (pluginKey: string, payload: UpdatePl
262
274
  key: string;
263
275
  label: string;
264
276
  description: string | null;
277
+ group: string | null;
265
278
  required: boolean;
266
279
  is_set: boolean;
267
280
  source: "default" | "stored" | "config" | "none";
@@ -277,6 +290,7 @@ export declare const updatePluginSettings: (pluginKey: string, payload: UpdatePl
277
290
  key: string;
278
291
  label: string;
279
292
  description: string | null;
293
+ group: string | null;
280
294
  required: boolean;
281
295
  is_set: boolean;
282
296
  source: "default" | "stored" | "config" | "none";
@@ -290,17 +304,19 @@ export declare const updatePluginSettings: (pluginKey: string, payload: UpdatePl
290
304
  key: string;
291
305
  label: string;
292
306
  description: string | null;
307
+ group: string | null;
293
308
  required: boolean;
294
309
  is_set: boolean;
295
310
  source: "default" | "stored" | "config" | "none";
296
311
  invalidates: string[];
297
312
  } | {
298
- type: "string" | "boolean" | "url" | "image";
313
+ type: "string" | "boolean" | "color" | "url" | "image";
299
314
  default: string | number | boolean | null;
300
315
  value: string | number | boolean | null;
301
316
  key: string;
302
317
  label: string;
303
318
  description: string | null;
319
+ group: string | null;
304
320
  required: boolean;
305
321
  is_set: boolean;
306
322
  source: "default" | "stored" | "config" | "none";
@@ -1,5 +1,5 @@
1
1
  import { pluginFeaturesAdminPaths } from "@hartl-services/medusa-food-supplements-contracts/paths/plugin-features";
2
- import { sdk } from "../../../lib/sdk";
2
+ import { sdk } from "../../../shared/lib/sdk";
3
3
  export const listPluginFeatures = () => sdk.client.fetch(pluginFeaturesAdminPaths.get.list, { method: "GET" });
4
4
  export const retrievePluginFeatures = (pluginKey) => sdk.client.fetch(pluginFeaturesAdminPaths.get.retrieve(pluginKey), { method: "GET" });
5
5
  export const updatePluginFeatures = (payload) => sdk.client.fetch(pluginFeaturesAdminPaths.post.update, { method: "POST", body: payload });
@@ -1,6 +1,6 @@
1
1
  import type { AdminPluginSetting, UpdatePluginSettingsPayload } from "@hartl-services/medusa-food-supplements-contracts/types/plugin-features-admin";
2
2
  /**
3
- * Form state per setting: text for string/url/number inputs and the chosen
3
+ * Form state per setting: text for string/url/number/color inputs and the chosen
4
4
  * option of a select (`""` = none), a boolean for
5
5
  * switches, text for a new secret (`""` = keep) or `null` = clear the
6
6
  * stored secret on save.
@@ -8,6 +8,21 @@ import type { AdminPluginSetting, UpdatePluginSettingsPayload } from "@hartl-ser
8
8
  export type SettingsDraft = Record<string, string | boolean | null>;
9
9
  type SettingValues = UpdatePluginSettingsPayload["values"];
10
10
  export declare const initialSettingsDraft: (settings: readonly AdminPluginSetting[]) => SettingsDraft;
11
+ /** `#rrggbb` (either case); the server stores it lowercase. */
12
+ export declare const isHexColor: (value: string) => boolean;
13
+ /** Colors are typed and sent lowercase; surrounding spaces are dropped. */
14
+ export declare const normalizeColorInput: (value: string) => string;
15
+ export type SettingSection = {
16
+ /** Section heading; `null` = no heading. */
17
+ group: string | null;
18
+ settings: AdminPluginSetting[];
19
+ };
20
+ /**
21
+ * Splits the settings (in their given order) into consecutive runs of the
22
+ * same `group`; a new section starts whenever the group differs from the
23
+ * previous setting's group.
24
+ */
25
+ export declare const groupSettings: (settings: readonly AdminPluginSetting[]) => SettingSection[];
11
26
  /**
12
27
  * Keys of number fields whose input the browser could not parse (e.g. "1e"):
13
28
  * the input then reports `""`, which must not be read as "cleared".
@@ -15,7 +30,7 @@ export declare const initialSettingsDraft: (settings: readonly AdminPluginSettin
15
30
  export type UnparsableKeys = readonly string[];
16
31
  /**
17
32
  * Keys whose draft value cannot be sent: unparsable, not a number or
18
- * outside min/max. Saving is disabled while any key is listed.
33
+ * outside min/max, or a color that is not `#rrggbb`. Saving is disabled while any key is listed.
19
34
  */
20
35
  export declare const invalidDraftKeys: (settings: readonly AdminPluginSetting[], draft: SettingsDraft, unparsable?: UnparsableKeys) => string[];
21
36
  /**