@hartl-services/medusa-base 2.6.0 → 2.7.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 (149) hide show
  1. package/.medusa/server/src/admin/admin-components/features/plugin-features/components/ImageSettingInput.d.ts +3 -2
  2. package/.medusa/server/src/admin/admin-components/features/plugin-features/components/ImageSettingInput.js +4 -4
  3. package/.medusa/server/src/admin/admin-components/features/plugin-features/components/PluginActionsSection.js +4 -4
  4. package/.medusa/server/src/admin/admin-components/features/plugin-features/components/PluginBreadcrumb.d.ts +16 -0
  5. package/.medusa/server/src/admin/admin-components/features/plugin-features/components/PluginBreadcrumb.js +25 -0
  6. package/.medusa/server/src/admin/admin-components/features/plugin-features/components/PluginDetailPage.js +1 -1
  7. package/.medusa/server/src/admin/admin-components/features/plugin-features/components/PluginFeatureSections.d.ts +5 -4
  8. package/.medusa/server/src/admin/admin-components/features/plugin-features/components/PluginFeatureSections.js +8 -5
  9. package/.medusa/server/src/admin/admin-components/features/plugin-features/components/PluginFeaturesCard.d.ts +4 -4
  10. package/.medusa/server/src/admin/admin-components/features/plugin-features/components/PluginFeaturesCard.js +24 -27
  11. package/.medusa/server/src/admin/admin-components/features/plugin-features/components/PluginFeaturesSettingsPage.d.ts +2 -2
  12. package/.medusa/server/src/admin/admin-components/features/plugin-features/components/PluginFeaturesSettingsPage.js +9 -9
  13. package/.medusa/server/src/admin/admin-components/features/plugin-features/components/PluginHubCard.d.ts +5 -1
  14. package/.medusa/server/src/admin/admin-components/features/plugin-features/components/PluginHubCard.js +11 -15
  15. package/.medusa/server/src/admin/admin-components/features/plugin-features/components/PluginPageShell.d.ts +10 -4
  16. package/.medusa/server/src/admin/admin-components/features/plugin-features/components/PluginPageShell.js +10 -5
  17. package/.medusa/server/src/admin/admin-components/features/plugin-features/components/PluginSettingsForm.d.ts +0 -1
  18. package/.medusa/server/src/admin/admin-components/features/plugin-features/components/PluginSettingsForm.js +73 -26
  19. package/.medusa/server/src/admin/admin-components/features/plugin-features/components/PluginStatusChips.d.ts +5 -1
  20. package/.medusa/server/src/admin/admin-components/features/plugin-features/components/PluginStatusChips.js +8 -6
  21. package/.medusa/server/src/admin/admin-components/features/plugin-features/components/ShopMasterDataBanner.d.ts +11 -0
  22. package/.medusa/server/src/admin/admin-components/features/plugin-features/components/ShopMasterDataBanner.js +15 -0
  23. package/.medusa/server/src/admin/admin-components/features/plugin-features/hooks/usePluginFeatureEnabled.d.ts +36 -5
  24. package/.medusa/server/src/admin/admin-components/features/plugin-features/hooks/usePluginFeatures.d.ts +144 -20
  25. package/.medusa/server/src/admin/admin-components/features/plugin-features/hooks/usePluginSettingsForm.d.ts +36 -5
  26. package/.medusa/server/src/admin/admin-components/features/plugin-features/hooks/usePluginSwitch.d.ts +15 -0
  27. package/.medusa/server/src/admin/admin-components/features/plugin-features/hooks/usePluginSwitch.js +66 -0
  28. package/.medusa/server/src/admin/admin-components/features/plugin-features/lib/plugin-features-admin-client.d.ts +144 -20
  29. package/.medusa/server/src/admin/admin-components/features/plugin-features/lib/plugin-view.d.ts +49 -0
  30. package/.medusa/server/src/admin/admin-components/features/plugin-features/lib/plugin-view.js +72 -0
  31. package/.medusa/server/src/admin/admin-components/features/plugin-features/lib/settings-draft.d.ts +1 -12
  32. package/.medusa/server/src/admin/admin-components/features/plugin-features/lib/settings-draft.js +4 -20
  33. package/.medusa/server/src/admin/admin-components/features/plugin-features/lib/settings-layout.d.ts +43 -0
  34. package/.medusa/server/src/admin/admin-components/features/plugin-features/lib/settings-layout.js +66 -0
  35. package/.medusa/server/src/admin/admin-components/i18n/texts.d.ts +22 -2
  36. package/.medusa/server/src/admin/admin-components/i18n/texts.js +29 -7
  37. package/.medusa/server/src/admin/admin-components/index.d.ts +12 -0
  38. package/.medusa/server/src/admin/admin-components/index.js +11 -0
  39. package/.medusa/server/src/admin/admin-components/shared/ui/AdminPageHeader.d.ts +22 -0
  40. package/.medusa/server/src/admin/admin-components/shared/ui/AdminPageHeader.js +8 -0
  41. package/.medusa/server/src/admin/admin-components/shared/ui/AdminSection.d.ts +26 -0
  42. package/.medusa/server/src/admin/admin-components/shared/ui/AdminSection.js +12 -0
  43. package/.medusa/server/src/admin/admin-components/shared/ui/BreadcrumbTrail.d.ts +23 -0
  44. package/.medusa/server/src/admin/admin-components/shared/ui/BreadcrumbTrail.js +20 -0
  45. package/.medusa/server/src/admin/admin-components/shared/ui/FileDropField.d.ts +21 -0
  46. package/.medusa/server/src/admin/admin-components/shared/ui/FileDropField.js +33 -0
  47. package/.medusa/server/src/admin/admin-components/shared/ui/FocusModalShell.d.ts +27 -0
  48. package/.medusa/server/src/admin/admin-components/shared/ui/FocusModalShell.js +13 -0
  49. package/.medusa/server/src/admin/admin-components/shared/ui/InfoTooltip.d.ts +13 -0
  50. package/.medusa/server/src/admin/admin-components/shared/ui/InfoTooltip.js +8 -0
  51. package/.medusa/server/src/admin/admin-components/shared/ui/MultiSelectDropdown.d.ts +22 -0
  52. package/.medusa/server/src/admin/admin-components/shared/ui/MultiSelectDropdown.js +14 -0
  53. package/.medusa/server/src/admin/admin-components/shared/ui/PdfPreviewModal.js +1 -1
  54. package/.medusa/server/src/admin/admin-components/shared/ui/PluginIcon.d.ts +10 -0
  55. package/.medusa/server/src/admin/admin-components/shared/ui/PluginIcon.js +10 -0
  56. package/.medusa/server/src/admin/admin-components/shared/ui/SwitchRow.d.ts +27 -0
  57. package/.medusa/server/src/admin/admin-components/shared/ui/SwitchRow.js +15 -0
  58. package/.medusa/server/src/admin/admin-components/shared/ui/WidgetHeader.d.ts +15 -0
  59. package/.medusa/server/src/admin/admin-components/shared/ui/WidgetHeader.js +8 -0
  60. package/.medusa/server/src/admin/admin-components/shared/ui/file-drop.d.ts +13 -0
  61. package/.medusa/server/src/admin/admin-components/shared/ui/file-drop.js +16 -0
  62. package/.medusa/server/src/admin/admin-components/shared/ui/multi-select.d.ts +13 -0
  63. package/.medusa/server/src/admin/admin-components/shared/ui/multi-select.js +11 -0
  64. package/.medusa/server/src/admin/admin-components/shared/ui/plugin-icon.d.ts +12 -0
  65. package/.medusa/server/src/admin/admin-components/shared/ui/plugin-icon.js +29 -0
  66. package/.medusa/server/src/admin/index.js +3123 -2019
  67. package/.medusa/server/src/admin/index.mjs +3126 -2022
  68. package/.medusa/server/src/api/admin-first-login-password-policy.js +56 -0
  69. package/.medusa/server/src/api/answer-actor-type-casing-not-found.js +26 -0
  70. package/.medusa/server/src/api/answer-code-provider-route-not-found.js +34 -0
  71. package/.medusa/server/src/api/code-account-password-routes.js +92 -0
  72. package/.medusa/server/src/api/middlewares.js +82 -17
  73. package/.medusa/server/src/api/password-policy.js +55 -10
  74. package/.medusa/server/src/api/require-login-code-customer-email.js +40 -0
  75. package/.medusa/server/src/api/store/customer-auth/login-code/route.js +17 -0
  76. package/.medusa/server/src/api/store/customer-auth/password-policy/route.js +19 -0
  77. package/.medusa/server/src/customer-auth/application/prepare-code-account-password-reset.js +111 -0
  78. package/.medusa/server/src/customer-auth/application/request-login-code.js +145 -0
  79. package/.medusa/server/src/customer-auth/customer-auth-methods-snapshot.js +55 -0
  80. package/.medusa/server/src/customer-auth/customer-password-policy.js +40 -0
  81. package/.medusa/server/src/customer-auth/domain/account-linking.js +53 -0
  82. package/.medusa/server/src/customer-auth/domain/auth-methods.js +32 -0
  83. package/.medusa/server/src/customer-auth/domain/login-code.js +39 -0
  84. package/.medusa/server/src/customer-auth/login-code-accounts.js +146 -0
  85. package/.medusa/server/src/customer-auth/login-code-state.js +139 -0
  86. package/.medusa/server/src/customer-auth/plugin-features.js +80 -0
  87. package/.medusa/server/src/customer-auth/remove-provider-identity.js +18 -0
  88. package/.medusa/server/src/customer-auth/start-customer-auth-methods.js +20 -0
  89. package/.medusa/server/src/documents/plugin-features.js +8 -2
  90. package/.medusa/server/src/email/application/deliver-ephemeral-auth-mail.js +186 -0
  91. package/.medusa/server/src/email/application/deliver-login-code.js +89 -0
  92. package/.medusa/server/src/email/application/handle-customer-verification-event.js +29 -168
  93. package/.medusa/server/src/email/application/handle-password-reset-event.js +27 -166
  94. package/.medusa/server/src/email/customer-verification-snapshot.js +20 -108
  95. package/.medusa/server/src/email/domain/business-keys.js +15 -2
  96. package/.medusa/server/src/email/plugin-features.js +8 -3
  97. package/.medusa/server/src/email/rendering/default-templates.js +2 -1
  98. package/.medusa/server/src/email/templates/blocks/dynamic-blocks.js +19 -1
  99. package/.medusa/server/src/email/templates/defaults/documents.js +7 -1
  100. package/.medusa/server/src/email/templates/defaults/subjects.js +3 -1
  101. package/.medusa/server/src/email/templates/defaults/texts.js +5 -2
  102. package/.medusa/server/src/email/templates/render.js +2 -1
  103. package/.medusa/server/src/email/templates/sample-data.js +2 -1
  104. package/.medusa/server/src/email/templates/validate.js +8 -3
  105. package/.medusa/server/src/email/types/email-kinds.js +4 -2
  106. package/.medusa/server/src/email/types/template-data.js +9 -1
  107. package/.medusa/server/src/modules/customer-auth/index.js +14 -0
  108. package/.medusa/server/src/modules/customer-auth/service.js +35 -0
  109. package/.medusa/server/src/modules/email/migrations/Migration20261010090000.js +20 -0
  110. package/.medusa/server/src/modules/plugin-features/domain/plugin-settings.js +4 -1
  111. package/.medusa/server/src/modules/plugin-features/service.js +26 -1
  112. package/.medusa/server/src/providers/email-otp/index.js +8 -0
  113. package/.medusa/server/src/providers/email-otp/service.js +96 -0
  114. package/.medusa/server/src/public/descriptor.js +117 -5
  115. package/.medusa/server/src/public/effective-features.js +22 -1
  116. package/.medusa/server/src/public/index.js +4 -2
  117. package/.medusa/server/src/public/plugin-icons.js +28 -0
  118. package/.medusa/server/src/public/shop-master-data.js +33 -14
  119. package/.medusa/server/src/shared/lib/index.js +2 -1
  120. package/.medusa/server/src/shared/lib/refreshing-snapshot.js +122 -0
  121. package/.medusa/server/src/shop-config/build-food-shop-config.js +38 -1
  122. package/README.md +436 -87
  123. package/dist/customer-auth/customer-auth-methods-snapshot.d.ts +25 -0
  124. package/dist/customer-auth/customer-auth-methods-snapshot.js +54 -0
  125. package/dist/customer-auth/domain/auth-methods.d.ts +16 -0
  126. package/dist/customer-auth/domain/auth-methods.js +31 -0
  127. package/dist/customer-auth/plugin-features.d.ts +2 -0
  128. package/dist/customer-auth/plugin-features.js +79 -0
  129. package/dist/email/customer-verification-snapshot.d.ts +3 -15
  130. package/dist/email/customer-verification-snapshot.js +19 -107
  131. package/dist/email/types/email-kinds.d.ts +4 -3
  132. package/dist/email/types/email-kinds.js +3 -1
  133. package/dist/email/types/template-data.d.ts +8 -0
  134. package/dist/email/types/template-data.js +8 -0
  135. package/dist/public/descriptor.js +116 -4
  136. package/dist/public/effective-features.d.ts +10 -0
  137. package/dist/public/effective-features.js +21 -0
  138. package/dist/public/index.d.ts +2 -1
  139. package/dist/public/index.js +3 -1
  140. package/dist/public/plugin-icons.d.ts +7 -0
  141. package/dist/public/plugin-icons.js +27 -0
  142. package/dist/public/shop-master-data.js +32 -13
  143. package/dist/public/types.d.ts +63 -1
  144. package/dist/shared/lib/index.d.ts +1 -0
  145. package/dist/shared/lib/index.js +1 -0
  146. package/dist/shared/lib/refreshing-snapshot.d.ts +52 -0
  147. package/dist/shared/lib/refreshing-snapshot.js +121 -0
  148. package/dist/shop-config/build-food-shop-config.js +37 -0
  149. package/package.json +8 -3
@@ -1,8 +1,10 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
1
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { StatusBadge } from "@medusajs/ui";
3
3
  import { texts } from "../../../i18n/texts";
4
- import { missingLabels } from "./PluginSettingsForm";
5
- /** aktiv/aus (switchable plugins only), plus konfiguriert/nicht konfiguriert when the plugin has settings. */
6
- export const PluginStatusChips = ({ plugin }) => (_jsxs("div", { className: "mt-2 flex flex-wrap gap-2", children: [plugin.switchable && (_jsx(StatusBadge, { color: plugin.enabled ? "green" : "grey", children: plugin.enabled ? texts.chips.enabled : texts.chips.disabled })), plugin.settings.length > 0 && (_jsx(StatusBadge, { color: plugin.configured ? "green" : "orange", children: plugin.configured
7
- ? texts.chips.configured
8
- : texts.chips.notConfigured(missingLabels(plugin)) }))] }));
4
+ import { hasRequiredSettings } from "../lib/plugin-view";
5
+ /**
6
+ * Aktiv/Aus (switchable plugins only), plus Konfiguriert/Nicht konfiguriert
7
+ * when the plugin has required settings. Renders bare badges: the caller
8
+ * lays them out (page header slot, flex row).
9
+ */
10
+ export const PluginStatusChips = ({ plugin }) => (_jsxs(_Fragment, { children: [plugin.switchable && (_jsx(StatusBadge, { color: plugin.enabled ? "green" : "grey", children: plugin.enabled ? texts.chips.enabled : texts.chips.disabled })), hasRequiredSettings(plugin) && (_jsx(StatusBadge, { color: plugin.configured ? "green" : "orange", children: plugin.configured ? texts.chips.configured : texts.chips.notConfigured }))] }));
@@ -0,0 +1,11 @@
1
+ import type { AdminPluginFeatures } from "@hartl-services/medusa-food-supplements-contracts/types/plugin-features-admin";
2
+ /** Plugin key of the shop master data, which the hub shows as a banner above the cards. */
3
+ export declare const SHOP_PLUGIN_KEY = "shop";
4
+ /**
5
+ * The shop master data (plugin `shop`, cannot be switched off) as a banner
6
+ * with an edit button; a subtle "Nicht konfiguriert" while required data is
7
+ * missing.
8
+ */
9
+ export declare const ShopMasterDataBanner: ({ plugin }: {
10
+ plugin: AdminPluginFeatures;
11
+ }) => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,15 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Button, Container, Heading, IconBadge, StatusBadge, Text } from "@medusajs/ui";
3
+ import { Link } from "react-router-dom";
4
+ import { texts } from "../../../i18n/texts";
5
+ import { PluginIcon } from "../../../shared/ui/PluginIcon";
6
+ import { pluginDetailPath } from "../lib/plugin-paths";
7
+ import { isUnconfigured } from "../lib/plugin-view";
8
+ /** Plugin key of the shop master data, which the hub shows as a banner above the cards. */
9
+ export const SHOP_PLUGIN_KEY = "shop";
10
+ /**
11
+ * The shop master data (plugin `shop`, cannot be switched off) as a banner
12
+ * with an edit button; a subtle "Nicht konfiguriert" while required data is
13
+ * missing.
14
+ */
15
+ export const ShopMasterDataBanner = ({ plugin }) => (_jsx(Container, { children: _jsxs("div", { className: "flex flex-wrap items-center gap-x-4 gap-y-3", children: [_jsx(IconBadge, { size: "large", children: _jsx(PluginIcon, { name: plugin.icon ?? "Buildings" }) }), _jsxs("div", { className: "flex min-w-0 flex-[1_1_320px] flex-col gap-y-0.5", children: [_jsx(Heading, { level: "h2", children: plugin.label }), _jsx(Text, { size: "small", leading: "compact", className: "text-ui-fg-subtle", children: plugin.summary ?? plugin.description })] }), isUnconfigured(plugin) && (_jsx(StatusBadge, { color: "orange", children: texts.chips.notConfigured })), _jsx(Button, { size: "small", variant: "secondary", asChild: true, children: _jsx(Link, { to: plugin.admin_page ?? pluginDetailPath(plugin.plugin_key), "aria-label": texts.plugin.openLabel(plugin.label), children: texts.page.editShop }) })] }) }));
@@ -44,8 +44,12 @@ export declare const pluginFeatureEnabledQueryOptions: (pluginKey: string, featu
44
44
  group: string | null;
45
45
  required: boolean;
46
46
  is_set: boolean;
47
- source: "default" | "stored" | "config" | "none";
47
+ source: "none" | "default" | "stored" | "config";
48
48
  invalidates: string[];
49
+ hint: string | null;
50
+ placeholder: string | null;
51
+ width: "full" | "half";
52
+ section: string | null;
49
53
  } | {
50
54
  type: "select";
51
55
  options: {
@@ -60,12 +64,17 @@ export declare const pluginFeatureEnabledQueryOptions: (pluginKey: string, featu
60
64
  group: string | null;
61
65
  required: boolean;
62
66
  is_set: boolean;
63
- source: "default" | "stored" | "config" | "none";
67
+ source: "none" | "default" | "stored" | "config";
64
68
  invalidates: string[];
69
+ hint: string | null;
70
+ placeholder: string | null;
71
+ width: "full" | "half";
72
+ section: string | null;
65
73
  } | {
66
74
  type: "number";
67
75
  min: number | null;
68
76
  max: number | null;
77
+ integer: boolean;
69
78
  default: number | null;
70
79
  value: number | null;
71
80
  key: string;
@@ -74,10 +83,14 @@ export declare const pluginFeatureEnabledQueryOptions: (pluginKey: string, featu
74
83
  group: string | null;
75
84
  required: boolean;
76
85
  is_set: boolean;
77
- source: "default" | "stored" | "config" | "none";
86
+ source: "none" | "default" | "stored" | "config";
78
87
  invalidates: string[];
88
+ hint: string | null;
89
+ placeholder: string | null;
90
+ width: "full" | "half";
91
+ section: string | null;
79
92
  } | {
80
- type: "string" | "boolean" | "color" | "url" | "image";
93
+ type: "string" | "boolean" | "color" | "image" | "url";
81
94
  default: string | number | boolean | null;
82
95
  value: string | number | boolean | null;
83
96
  key: string;
@@ -86,8 +99,12 @@ export declare const pluginFeatureEnabledQueryOptions: (pluginKey: string, featu
86
99
  group: string | null;
87
100
  required: boolean;
88
101
  is_set: boolean;
89
- source: "default" | "stored" | "config" | "none";
102
+ source: "none" | "default" | "stored" | "config";
90
103
  invalidates: string[];
104
+ hint: string | null;
105
+ placeholder: string | null;
106
+ width: "full" | "half";
107
+ section: string | null;
91
108
  })[];
92
109
  configured: boolean;
93
110
  missing: string[];
@@ -100,6 +117,20 @@ export declare const pluginFeatureEnabledQueryOptions: (pluginKey: string, featu
100
117
  confirm: string | null;
101
118
  }[];
102
119
  admin_page: string | null;
120
+ icon: string | null;
121
+ summary: string | null;
122
+ disable_hint: string | null;
123
+ disable_confirm: string | null;
124
+ features_heading: string | null;
125
+ features_note: string | null;
126
+ all_off_warning: string | null;
127
+ require_enabled_feature: boolean;
128
+ setting_groups: {
129
+ name: string;
130
+ description: string | null;
131
+ note: string | null;
132
+ requires_feature: string | null;
133
+ }[];
103
134
  }[];
104
135
  }>;
105
136
  staleTime: number;
@@ -24,8 +24,12 @@ export declare function usePluginFeatures(): import("@tanstack/react-query").Use
24
24
  group: string | null;
25
25
  required: boolean;
26
26
  is_set: boolean;
27
- source: "default" | "stored" | "config" | "none";
27
+ source: "none" | "default" | "stored" | "config";
28
28
  invalidates: string[];
29
+ hint: string | null;
30
+ placeholder: string | null;
31
+ width: "full" | "half";
32
+ section: string | null;
29
33
  } | {
30
34
  type: "select";
31
35
  options: {
@@ -40,12 +44,17 @@ export declare function usePluginFeatures(): import("@tanstack/react-query").Use
40
44
  group: string | null;
41
45
  required: boolean;
42
46
  is_set: boolean;
43
- source: "default" | "stored" | "config" | "none";
47
+ source: "none" | "default" | "stored" | "config";
44
48
  invalidates: string[];
49
+ hint: string | null;
50
+ placeholder: string | null;
51
+ width: "full" | "half";
52
+ section: string | null;
45
53
  } | {
46
54
  type: "number";
47
55
  min: number | null;
48
56
  max: number | null;
57
+ integer: boolean;
49
58
  default: number | null;
50
59
  value: number | null;
51
60
  key: string;
@@ -54,10 +63,14 @@ export declare function usePluginFeatures(): import("@tanstack/react-query").Use
54
63
  group: string | null;
55
64
  required: boolean;
56
65
  is_set: boolean;
57
- source: "default" | "stored" | "config" | "none";
66
+ source: "none" | "default" | "stored" | "config";
58
67
  invalidates: string[];
68
+ hint: string | null;
69
+ placeholder: string | null;
70
+ width: "full" | "half";
71
+ section: string | null;
59
72
  } | {
60
- type: "string" | "boolean" | "color" | "url" | "image";
73
+ type: "string" | "boolean" | "color" | "image" | "url";
61
74
  default: string | number | boolean | null;
62
75
  value: string | number | boolean | null;
63
76
  key: string;
@@ -66,8 +79,12 @@ export declare function usePluginFeatures(): import("@tanstack/react-query").Use
66
79
  group: string | null;
67
80
  required: boolean;
68
81
  is_set: boolean;
69
- source: "default" | "stored" | "config" | "none";
82
+ source: "none" | "default" | "stored" | "config";
70
83
  invalidates: string[];
84
+ hint: string | null;
85
+ placeholder: string | null;
86
+ width: "full" | "half";
87
+ section: string | null;
71
88
  })[];
72
89
  configured: boolean;
73
90
  missing: string[];
@@ -80,6 +97,20 @@ export declare function usePluginFeatures(): import("@tanstack/react-query").Use
80
97
  confirm: string | null;
81
98
  }[];
82
99
  admin_page: string | null;
100
+ icon: string | null;
101
+ summary: string | null;
102
+ disable_hint: string | null;
103
+ disable_confirm: string | null;
104
+ features_heading: string | null;
105
+ features_note: string | null;
106
+ all_off_warning: string | null;
107
+ require_enabled_feature: boolean;
108
+ setting_groups: {
109
+ name: string;
110
+ description: string | null;
111
+ note: string | null;
112
+ requires_feature: string | null;
113
+ }[];
83
114
  }[];
84
115
  }, Error>;
85
116
  /**
@@ -115,8 +146,12 @@ export declare function usePluginFeature(pluginKey: string | undefined): import(
115
146
  group: string | null;
116
147
  required: boolean;
117
148
  is_set: boolean;
118
- source: "default" | "stored" | "config" | "none";
149
+ source: "none" | "default" | "stored" | "config";
119
150
  invalidates: string[];
151
+ hint: string | null;
152
+ placeholder: string | null;
153
+ width: "full" | "half";
154
+ section: string | null;
120
155
  } | {
121
156
  type: "select";
122
157
  options: {
@@ -131,12 +166,17 @@ export declare function usePluginFeature(pluginKey: string | undefined): import(
131
166
  group: string | null;
132
167
  required: boolean;
133
168
  is_set: boolean;
134
- source: "default" | "stored" | "config" | "none";
169
+ source: "none" | "default" | "stored" | "config";
135
170
  invalidates: string[];
171
+ hint: string | null;
172
+ placeholder: string | null;
173
+ width: "full" | "half";
174
+ section: string | null;
136
175
  } | {
137
176
  type: "number";
138
177
  min: number | null;
139
178
  max: number | null;
179
+ integer: boolean;
140
180
  default: number | null;
141
181
  value: number | null;
142
182
  key: string;
@@ -145,10 +185,14 @@ export declare function usePluginFeature(pluginKey: string | undefined): import(
145
185
  group: string | null;
146
186
  required: boolean;
147
187
  is_set: boolean;
148
- source: "default" | "stored" | "config" | "none";
188
+ source: "none" | "default" | "stored" | "config";
149
189
  invalidates: string[];
190
+ hint: string | null;
191
+ placeholder: string | null;
192
+ width: "full" | "half";
193
+ section: string | null;
150
194
  } | {
151
- type: "string" | "boolean" | "color" | "url" | "image";
195
+ type: "string" | "boolean" | "color" | "image" | "url";
152
196
  default: string | number | boolean | null;
153
197
  value: string | number | boolean | null;
154
198
  key: string;
@@ -157,8 +201,12 @@ export declare function usePluginFeature(pluginKey: string | undefined): import(
157
201
  group: string | null;
158
202
  required: boolean;
159
203
  is_set: boolean;
160
- source: "default" | "stored" | "config" | "none";
204
+ source: "none" | "default" | "stored" | "config";
161
205
  invalidates: string[];
206
+ hint: string | null;
207
+ placeholder: string | null;
208
+ width: "full" | "half";
209
+ section: string | null;
162
210
  })[];
163
211
  configured: boolean;
164
212
  missing: string[];
@@ -171,6 +219,20 @@ export declare function usePluginFeature(pluginKey: string | undefined): import(
171
219
  confirm: string | null;
172
220
  }[];
173
221
  admin_page: string | null;
222
+ icon: string | null;
223
+ summary: string | null;
224
+ disable_hint: string | null;
225
+ disable_confirm: string | null;
226
+ features_heading: string | null;
227
+ features_note: string | null;
228
+ all_off_warning: string | null;
229
+ require_enabled_feature: boolean;
230
+ setting_groups: {
231
+ name: string;
232
+ description: string | null;
233
+ note: string | null;
234
+ requires_feature: string | null;
235
+ }[];
174
236
  };
175
237
  }, Error>;
176
238
  /** One instance per plugin card, so pending state is scoped to that plugin. */
@@ -200,8 +262,12 @@ export declare function useUpdatePluginFeatures(): import("@tanstack/react-query
200
262
  group: string | null;
201
263
  required: boolean;
202
264
  is_set: boolean;
203
- source: "default" | "stored" | "config" | "none";
265
+ source: "none" | "default" | "stored" | "config";
204
266
  invalidates: string[];
267
+ hint: string | null;
268
+ placeholder: string | null;
269
+ width: "full" | "half";
270
+ section: string | null;
205
271
  } | {
206
272
  type: "select";
207
273
  options: {
@@ -216,12 +282,17 @@ export declare function useUpdatePluginFeatures(): import("@tanstack/react-query
216
282
  group: string | null;
217
283
  required: boolean;
218
284
  is_set: boolean;
219
- source: "default" | "stored" | "config" | "none";
285
+ source: "none" | "default" | "stored" | "config";
220
286
  invalidates: string[];
287
+ hint: string | null;
288
+ placeholder: string | null;
289
+ width: "full" | "half";
290
+ section: string | null;
221
291
  } | {
222
292
  type: "number";
223
293
  min: number | null;
224
294
  max: number | null;
295
+ integer: boolean;
225
296
  default: number | null;
226
297
  value: number | null;
227
298
  key: string;
@@ -230,10 +301,14 @@ export declare function useUpdatePluginFeatures(): import("@tanstack/react-query
230
301
  group: string | null;
231
302
  required: boolean;
232
303
  is_set: boolean;
233
- source: "default" | "stored" | "config" | "none";
304
+ source: "none" | "default" | "stored" | "config";
234
305
  invalidates: string[];
306
+ hint: string | null;
307
+ placeholder: string | null;
308
+ width: "full" | "half";
309
+ section: string | null;
235
310
  } | {
236
- type: "string" | "boolean" | "color" | "url" | "image";
311
+ type: "string" | "boolean" | "color" | "image" | "url";
237
312
  default: string | number | boolean | null;
238
313
  value: string | number | boolean | null;
239
314
  key: string;
@@ -242,8 +317,12 @@ export declare function useUpdatePluginFeatures(): import("@tanstack/react-query
242
317
  group: string | null;
243
318
  required: boolean;
244
319
  is_set: boolean;
245
- source: "default" | "stored" | "config" | "none";
320
+ source: "none" | "default" | "stored" | "config";
246
321
  invalidates: string[];
322
+ hint: string | null;
323
+ placeholder: string | null;
324
+ width: "full" | "half";
325
+ section: string | null;
247
326
  })[];
248
327
  configured: boolean;
249
328
  missing: string[];
@@ -256,6 +335,20 @@ export declare function useUpdatePluginFeatures(): import("@tanstack/react-query
256
335
  confirm: string | null;
257
336
  }[];
258
337
  admin_page: string | null;
338
+ icon: string | null;
339
+ summary: string | null;
340
+ disable_hint: string | null;
341
+ disable_confirm: string | null;
342
+ features_heading: string | null;
343
+ features_note: string | null;
344
+ all_off_warning: string | null;
345
+ require_enabled_feature: boolean;
346
+ setting_groups: {
347
+ name: string;
348
+ description: string | null;
349
+ note: string | null;
350
+ requires_feature: string | null;
351
+ }[];
259
352
  };
260
353
  }, Error, {
261
354
  plugin_key: string;
@@ -289,8 +382,12 @@ export declare function useUpdatePluginSettings(pluginKey: string): import("@tan
289
382
  group: string | null;
290
383
  required: boolean;
291
384
  is_set: boolean;
292
- source: "default" | "stored" | "config" | "none";
385
+ source: "none" | "default" | "stored" | "config";
293
386
  invalidates: string[];
387
+ hint: string | null;
388
+ placeholder: string | null;
389
+ width: "full" | "half";
390
+ section: string | null;
294
391
  } | {
295
392
  type: "select";
296
393
  options: {
@@ -305,12 +402,17 @@ export declare function useUpdatePluginSettings(pluginKey: string): import("@tan
305
402
  group: string | null;
306
403
  required: boolean;
307
404
  is_set: boolean;
308
- source: "default" | "stored" | "config" | "none";
405
+ source: "none" | "default" | "stored" | "config";
309
406
  invalidates: string[];
407
+ hint: string | null;
408
+ placeholder: string | null;
409
+ width: "full" | "half";
410
+ section: string | null;
310
411
  } | {
311
412
  type: "number";
312
413
  min: number | null;
313
414
  max: number | null;
415
+ integer: boolean;
314
416
  default: number | null;
315
417
  value: number | null;
316
418
  key: string;
@@ -319,10 +421,14 @@ export declare function useUpdatePluginSettings(pluginKey: string): import("@tan
319
421
  group: string | null;
320
422
  required: boolean;
321
423
  is_set: boolean;
322
- source: "default" | "stored" | "config" | "none";
424
+ source: "none" | "default" | "stored" | "config";
323
425
  invalidates: string[];
426
+ hint: string | null;
427
+ placeholder: string | null;
428
+ width: "full" | "half";
429
+ section: string | null;
324
430
  } | {
325
- type: "string" | "boolean" | "color" | "url" | "image";
431
+ type: "string" | "boolean" | "color" | "image" | "url";
326
432
  default: string | number | boolean | null;
327
433
  value: string | number | boolean | null;
328
434
  key: string;
@@ -331,8 +437,12 @@ export declare function useUpdatePluginSettings(pluginKey: string): import("@tan
331
437
  group: string | null;
332
438
  required: boolean;
333
439
  is_set: boolean;
334
- source: "default" | "stored" | "config" | "none";
440
+ source: "none" | "default" | "stored" | "config";
335
441
  invalidates: string[];
442
+ hint: string | null;
443
+ placeholder: string | null;
444
+ width: "full" | "half";
445
+ section: string | null;
336
446
  })[];
337
447
  configured: boolean;
338
448
  missing: string[];
@@ -345,6 +455,20 @@ export declare function useUpdatePluginSettings(pluginKey: string): import("@tan
345
455
  confirm: string | null;
346
456
  }[];
347
457
  admin_page: string | null;
458
+ icon: string | null;
459
+ summary: string | null;
460
+ disable_hint: string | null;
461
+ disable_confirm: string | null;
462
+ features_heading: string | null;
463
+ features_note: string | null;
464
+ all_off_warning: string | null;
465
+ require_enabled_feature: boolean;
466
+ setting_groups: {
467
+ name: string;
468
+ description: string | null;
469
+ note: string | null;
470
+ requires_feature: string | null;
471
+ }[];
348
472
  };
349
473
  }, Error, {
350
474
  expected_version: number;
@@ -33,8 +33,12 @@ export declare function usePluginSettingsForm(plugin: AdminPluginFeatures): {
33
33
  group: string | null;
34
34
  required: boolean;
35
35
  is_set: boolean;
36
- source: "default" | "stored" | "config" | "none";
36
+ source: "none" | "default" | "stored" | "config";
37
37
  invalidates: string[];
38
+ hint: string | null;
39
+ placeholder: string | null;
40
+ width: "full" | "half";
41
+ section: string | null;
38
42
  } | {
39
43
  type: "select";
40
44
  options: {
@@ -49,12 +53,17 @@ export declare function usePluginSettingsForm(plugin: AdminPluginFeatures): {
49
53
  group: string | null;
50
54
  required: boolean;
51
55
  is_set: boolean;
52
- source: "default" | "stored" | "config" | "none";
56
+ source: "none" | "default" | "stored" | "config";
53
57
  invalidates: string[];
58
+ hint: string | null;
59
+ placeholder: string | null;
60
+ width: "full" | "half";
61
+ section: string | null;
54
62
  } | {
55
63
  type: "number";
56
64
  min: number | null;
57
65
  max: number | null;
66
+ integer: boolean;
58
67
  default: number | null;
59
68
  value: number | null;
60
69
  key: string;
@@ -63,10 +72,14 @@ export declare function usePluginSettingsForm(plugin: AdminPluginFeatures): {
63
72
  group: string | null;
64
73
  required: boolean;
65
74
  is_set: boolean;
66
- source: "default" | "stored" | "config" | "none";
75
+ source: "none" | "default" | "stored" | "config";
67
76
  invalidates: string[];
77
+ hint: string | null;
78
+ placeholder: string | null;
79
+ width: "full" | "half";
80
+ section: string | null;
68
81
  } | {
69
- type: "string" | "boolean" | "color" | "url" | "image";
82
+ type: "string" | "boolean" | "color" | "image" | "url";
70
83
  default: string | number | boolean | null;
71
84
  value: string | number | boolean | null;
72
85
  key: string;
@@ -75,8 +88,12 @@ export declare function usePluginSettingsForm(plugin: AdminPluginFeatures): {
75
88
  group: string | null;
76
89
  required: boolean;
77
90
  is_set: boolean;
78
- source: "default" | "stored" | "config" | "none";
91
+ source: "none" | "default" | "stored" | "config";
79
92
  invalidates: string[];
93
+ hint: string | null;
94
+ placeholder: string | null;
95
+ width: "full" | "half";
96
+ section: string | null;
80
97
  })[];
81
98
  configured: boolean;
82
99
  missing: string[];
@@ -89,6 +106,20 @@ export declare function usePluginSettingsForm(plugin: AdminPluginFeatures): {
89
106
  confirm: string | null;
90
107
  }[];
91
108
  admin_page: string | null;
109
+ icon: string | null;
110
+ summary: string | null;
111
+ disable_hint: string | null;
112
+ disable_confirm: string | null;
113
+ features_heading: string | null;
114
+ features_note: string | null;
115
+ all_off_warning: string | null;
116
+ require_enabled_feature: boolean;
117
+ setting_groups: {
118
+ name: string;
119
+ description: string | null;
120
+ note: string | null;
121
+ requires_feature: string | null;
122
+ }[];
92
123
  };
93
124
  }, Error, {
94
125
  expected_version: number;
@@ -0,0 +1,15 @@
1
+ import type { AdminPluginFeatures } from "@hartl-services/medusa-food-supplements-contracts/types/plugin-features-admin";
2
+ /**
3
+ * Plugin switch of the hub card and of the plugin page: switching ON saves at
4
+ * once, switching OFF asks for confirmation first (the descriptor's
5
+ * `disable_confirm`, else a generic text). Saves with the loaded `version`, so
6
+ * a concurrent change answers 409 and reloads. After the confirmation the
7
+ * plugin is read from the query cache again, so a save made while the dialog
8
+ * was open does not send a stale `version`. Feature switches save through
9
+ * `saveFeatures`.
10
+ */
11
+ export declare function usePluginSwitch(plugin: AdminPluginFeatures): {
12
+ pending: boolean;
13
+ setEnabled: (enabled: boolean) => undefined;
14
+ setFeature: (key: string, enabled: boolean) => void;
15
+ };
@@ -0,0 +1,66 @@
1
+ import { usePrompt } from "@medusajs/ui";
2
+ import { useQueryClient } from "@tanstack/react-query";
3
+ import { texts } from "../../../i18n/texts";
4
+ import { configuredFeatures } from "../lib/plugin-view";
5
+ import { pluginFeatureKeys } from "../queries/pluginFeatureKeys";
6
+ import { useUpdatePluginFeatures } from "./usePluginFeatures";
7
+ /**
8
+ * Plugin switch of the hub card and of the plugin page: switching ON saves at
9
+ * once, switching OFF asks for confirmation first (the descriptor's
10
+ * `disable_confirm`, else a generic text). Saves with the loaded `version`, so
11
+ * a concurrent change answers 409 and reloads. After the confirmation the
12
+ * plugin is read from the query cache again, so a save made while the dialog
13
+ * was open does not send a stale `version`. Feature switches save through
14
+ * `saveFeatures`.
15
+ */
16
+ export function usePluginSwitch(plugin) {
17
+ const mutation = useUpdatePluginFeatures();
18
+ const prompt = usePrompt();
19
+ const queryClient = useQueryClient();
20
+ /** The newest cached entry of this plugin (detail or list), else the one rendered with. */
21
+ const latest = () => {
22
+ const candidates = [
23
+ queryClient.getQueryData(pluginFeatureKeys.detail(plugin.plugin_key))?.plugin,
24
+ queryClient
25
+ .getQueryData(pluginFeatureKeys.list())
26
+ ?.plugins.find((entry) => entry.plugin_key === plugin.plugin_key),
27
+ plugin,
28
+ ].filter((entry) => entry !== undefined);
29
+ return candidates.reduce((newest, entry) => entry.version > newest.version ? entry : newest);
30
+ };
31
+ const save = (current, enabled, features) => {
32
+ mutation.mutate({
33
+ plugin_key: current.plugin_key,
34
+ expected_version: current.version,
35
+ enabled,
36
+ features,
37
+ });
38
+ };
39
+ const setEnabled = async (enabled) => {
40
+ if (!enabled) {
41
+ const confirmed = await prompt({
42
+ title: texts.plugin.disableTitle(plugin.label),
43
+ description: plugin.disable_confirm ?? texts.plugin.disableConfirmDefault,
44
+ confirmText: texts.plugin.disable,
45
+ cancelText: texts.plugin.cancel,
46
+ });
47
+ if (!confirmed) {
48
+ return;
49
+ }
50
+ }
51
+ const current = latest();
52
+ save(current, enabled, configuredFeatures(current));
53
+ };
54
+ const setFeature = (key, enabled) => {
55
+ const current = latest();
56
+ save(current, current.enabled, {
57
+ ...configuredFeatures(current),
58
+ [key]: enabled,
59
+ });
60
+ };
61
+ return {
62
+ pending: mutation.isPending,
63
+ setEnabled: (enabled) => void setEnabled(enabled),
64
+ setFeature,
65
+ };
66
+ }