@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
@@ -25,8 +25,12 @@ export declare const listPluginFeatures: () => Promise<{
25
25
  group: string | null;
26
26
  required: boolean;
27
27
  is_set: boolean;
28
- source: "default" | "stored" | "config" | "none";
28
+ source: "none" | "default" | "stored" | "config";
29
29
  invalidates: string[];
30
+ hint: string | null;
31
+ placeholder: string | null;
32
+ width: "full" | "half";
33
+ section: string | null;
30
34
  } | {
31
35
  type: "select";
32
36
  options: {
@@ -41,12 +45,17 @@ export declare const listPluginFeatures: () => Promise<{
41
45
  group: string | null;
42
46
  required: boolean;
43
47
  is_set: boolean;
44
- source: "default" | "stored" | "config" | "none";
48
+ source: "none" | "default" | "stored" | "config";
45
49
  invalidates: string[];
50
+ hint: string | null;
51
+ placeholder: string | null;
52
+ width: "full" | "half";
53
+ section: string | null;
46
54
  } | {
47
55
  type: "number";
48
56
  min: number | null;
49
57
  max: number | null;
58
+ integer: boolean;
50
59
  default: number | null;
51
60
  value: number | null;
52
61
  key: string;
@@ -55,10 +64,14 @@ export declare const listPluginFeatures: () => Promise<{
55
64
  group: string | null;
56
65
  required: boolean;
57
66
  is_set: boolean;
58
- source: "default" | "stored" | "config" | "none";
67
+ source: "none" | "default" | "stored" | "config";
59
68
  invalidates: string[];
69
+ hint: string | null;
70
+ placeholder: string | null;
71
+ width: "full" | "half";
72
+ section: string | null;
60
73
  } | {
61
- type: "string" | "boolean" | "color" | "url" | "image";
74
+ type: "string" | "boolean" | "color" | "image" | "url";
62
75
  default: string | number | boolean | null;
63
76
  value: string | number | boolean | null;
64
77
  key: string;
@@ -67,8 +80,12 @@ export declare const listPluginFeatures: () => Promise<{
67
80
  group: string | null;
68
81
  required: boolean;
69
82
  is_set: boolean;
70
- source: "default" | "stored" | "config" | "none";
83
+ source: "none" | "default" | "stored" | "config";
71
84
  invalidates: string[];
85
+ hint: string | null;
86
+ placeholder: string | null;
87
+ width: "full" | "half";
88
+ section: string | null;
72
89
  })[];
73
90
  configured: boolean;
74
91
  missing: string[];
@@ -81,6 +98,20 @@ export declare const listPluginFeatures: () => Promise<{
81
98
  confirm: string | null;
82
99
  }[];
83
100
  admin_page: string | null;
101
+ icon: string | null;
102
+ summary: string | null;
103
+ disable_hint: string | null;
104
+ disable_confirm: string | null;
105
+ features_heading: string | null;
106
+ features_note: string | null;
107
+ all_off_warning: string | null;
108
+ require_enabled_feature: boolean;
109
+ setting_groups: {
110
+ name: string;
111
+ description: string | null;
112
+ note: string | null;
113
+ requires_feature: string | null;
114
+ }[];
84
115
  }[];
85
116
  }>;
86
117
  export declare const retrievePluginFeatures: (pluginKey: string) => Promise<{
@@ -109,8 +140,12 @@ export declare const retrievePluginFeatures: (pluginKey: string) => Promise<{
109
140
  group: string | null;
110
141
  required: boolean;
111
142
  is_set: boolean;
112
- source: "default" | "stored" | "config" | "none";
143
+ source: "none" | "default" | "stored" | "config";
113
144
  invalidates: string[];
145
+ hint: string | null;
146
+ placeholder: string | null;
147
+ width: "full" | "half";
148
+ section: string | null;
114
149
  } | {
115
150
  type: "select";
116
151
  options: {
@@ -125,12 +160,17 @@ export declare const retrievePluginFeatures: (pluginKey: string) => Promise<{
125
160
  group: string | null;
126
161
  required: boolean;
127
162
  is_set: boolean;
128
- source: "default" | "stored" | "config" | "none";
163
+ source: "none" | "default" | "stored" | "config";
129
164
  invalidates: string[];
165
+ hint: string | null;
166
+ placeholder: string | null;
167
+ width: "full" | "half";
168
+ section: string | null;
130
169
  } | {
131
170
  type: "number";
132
171
  min: number | null;
133
172
  max: number | null;
173
+ integer: boolean;
134
174
  default: number | null;
135
175
  value: number | null;
136
176
  key: string;
@@ -139,10 +179,14 @@ export declare const retrievePluginFeatures: (pluginKey: string) => Promise<{
139
179
  group: string | null;
140
180
  required: boolean;
141
181
  is_set: boolean;
142
- source: "default" | "stored" | "config" | "none";
182
+ source: "none" | "default" | "stored" | "config";
143
183
  invalidates: string[];
184
+ hint: string | null;
185
+ placeholder: string | null;
186
+ width: "full" | "half";
187
+ section: string | null;
144
188
  } | {
145
- type: "string" | "boolean" | "color" | "url" | "image";
189
+ type: "string" | "boolean" | "color" | "image" | "url";
146
190
  default: string | number | boolean | null;
147
191
  value: string | number | boolean | null;
148
192
  key: string;
@@ -151,8 +195,12 @@ export declare const retrievePluginFeatures: (pluginKey: string) => Promise<{
151
195
  group: string | null;
152
196
  required: boolean;
153
197
  is_set: boolean;
154
- source: "default" | "stored" | "config" | "none";
198
+ source: "none" | "default" | "stored" | "config";
155
199
  invalidates: string[];
200
+ hint: string | null;
201
+ placeholder: string | null;
202
+ width: "full" | "half";
203
+ section: string | null;
156
204
  })[];
157
205
  configured: boolean;
158
206
  missing: string[];
@@ -165,6 +213,20 @@ export declare const retrievePluginFeatures: (pluginKey: string) => Promise<{
165
213
  confirm: string | null;
166
214
  }[];
167
215
  admin_page: string | null;
216
+ icon: string | null;
217
+ summary: string | null;
218
+ disable_hint: string | null;
219
+ disable_confirm: string | null;
220
+ features_heading: string | null;
221
+ features_note: string | null;
222
+ all_off_warning: string | null;
223
+ require_enabled_feature: boolean;
224
+ setting_groups: {
225
+ name: string;
226
+ description: string | null;
227
+ note: string | null;
228
+ requires_feature: string | null;
229
+ }[];
168
230
  };
169
231
  }>;
170
232
  export declare const updatePluginFeatures: (payload: UpdatePluginFeaturesPayload) => Promise<{
@@ -193,8 +255,12 @@ export declare const updatePluginFeatures: (payload: UpdatePluginFeaturesPayload
193
255
  group: string | null;
194
256
  required: boolean;
195
257
  is_set: boolean;
196
- source: "default" | "stored" | "config" | "none";
258
+ source: "none" | "default" | "stored" | "config";
197
259
  invalidates: string[];
260
+ hint: string | null;
261
+ placeholder: string | null;
262
+ width: "full" | "half";
263
+ section: string | null;
198
264
  } | {
199
265
  type: "select";
200
266
  options: {
@@ -209,12 +275,17 @@ export declare const updatePluginFeatures: (payload: UpdatePluginFeaturesPayload
209
275
  group: string | null;
210
276
  required: boolean;
211
277
  is_set: boolean;
212
- source: "default" | "stored" | "config" | "none";
278
+ source: "none" | "default" | "stored" | "config";
213
279
  invalidates: string[];
280
+ hint: string | null;
281
+ placeholder: string | null;
282
+ width: "full" | "half";
283
+ section: string | null;
214
284
  } | {
215
285
  type: "number";
216
286
  min: number | null;
217
287
  max: number | null;
288
+ integer: boolean;
218
289
  default: number | null;
219
290
  value: number | null;
220
291
  key: string;
@@ -223,10 +294,14 @@ export declare const updatePluginFeatures: (payload: UpdatePluginFeaturesPayload
223
294
  group: string | null;
224
295
  required: boolean;
225
296
  is_set: boolean;
226
- source: "default" | "stored" | "config" | "none";
297
+ source: "none" | "default" | "stored" | "config";
227
298
  invalidates: string[];
299
+ hint: string | null;
300
+ placeholder: string | null;
301
+ width: "full" | "half";
302
+ section: string | null;
228
303
  } | {
229
- type: "string" | "boolean" | "color" | "url" | "image";
304
+ type: "string" | "boolean" | "color" | "image" | "url";
230
305
  default: string | number | boolean | null;
231
306
  value: string | number | boolean | null;
232
307
  key: string;
@@ -235,8 +310,12 @@ export declare const updatePluginFeatures: (payload: UpdatePluginFeaturesPayload
235
310
  group: string | null;
236
311
  required: boolean;
237
312
  is_set: boolean;
238
- source: "default" | "stored" | "config" | "none";
313
+ source: "none" | "default" | "stored" | "config";
239
314
  invalidates: string[];
315
+ hint: string | null;
316
+ placeholder: string | null;
317
+ width: "full" | "half";
318
+ section: string | null;
240
319
  })[];
241
320
  configured: boolean;
242
321
  missing: string[];
@@ -249,6 +328,20 @@ export declare const updatePluginFeatures: (payload: UpdatePluginFeaturesPayload
249
328
  confirm: string | null;
250
329
  }[];
251
330
  admin_page: string | null;
331
+ icon: string | null;
332
+ summary: string | null;
333
+ disable_hint: string | null;
334
+ disable_confirm: string | null;
335
+ features_heading: string | null;
336
+ features_note: string | null;
337
+ all_off_warning: string | null;
338
+ require_enabled_feature: boolean;
339
+ setting_groups: {
340
+ name: string;
341
+ description: string | null;
342
+ note: string | null;
343
+ requires_feature: string | null;
344
+ }[];
252
345
  };
253
346
  }>;
254
347
  export declare const updatePluginSettings: (pluginKey: string, payload: UpdatePluginSettingsPayload) => Promise<{
@@ -277,8 +370,12 @@ export declare const updatePluginSettings: (pluginKey: string, payload: UpdatePl
277
370
  group: string | null;
278
371
  required: boolean;
279
372
  is_set: boolean;
280
- source: "default" | "stored" | "config" | "none";
373
+ source: "none" | "default" | "stored" | "config";
281
374
  invalidates: string[];
375
+ hint: string | null;
376
+ placeholder: string | null;
377
+ width: "full" | "half";
378
+ section: string | null;
282
379
  } | {
283
380
  type: "select";
284
381
  options: {
@@ -293,12 +390,17 @@ export declare const updatePluginSettings: (pluginKey: string, payload: UpdatePl
293
390
  group: string | null;
294
391
  required: boolean;
295
392
  is_set: boolean;
296
- source: "default" | "stored" | "config" | "none";
393
+ source: "none" | "default" | "stored" | "config";
297
394
  invalidates: string[];
395
+ hint: string | null;
396
+ placeholder: string | null;
397
+ width: "full" | "half";
398
+ section: string | null;
298
399
  } | {
299
400
  type: "number";
300
401
  min: number | null;
301
402
  max: number | null;
403
+ integer: boolean;
302
404
  default: number | null;
303
405
  value: number | null;
304
406
  key: string;
@@ -307,10 +409,14 @@ export declare const updatePluginSettings: (pluginKey: string, payload: UpdatePl
307
409
  group: string | null;
308
410
  required: boolean;
309
411
  is_set: boolean;
310
- source: "default" | "stored" | "config" | "none";
412
+ source: "none" | "default" | "stored" | "config";
311
413
  invalidates: string[];
414
+ hint: string | null;
415
+ placeholder: string | null;
416
+ width: "full" | "half";
417
+ section: string | null;
312
418
  } | {
313
- type: "string" | "boolean" | "color" | "url" | "image";
419
+ type: "string" | "boolean" | "color" | "image" | "url";
314
420
  default: string | number | boolean | null;
315
421
  value: string | number | boolean | null;
316
422
  key: string;
@@ -319,8 +425,12 @@ export declare const updatePluginSettings: (pluginKey: string, payload: UpdatePl
319
425
  group: string | null;
320
426
  required: boolean;
321
427
  is_set: boolean;
322
- source: "default" | "stored" | "config" | "none";
428
+ source: "none" | "default" | "stored" | "config";
323
429
  invalidates: string[];
430
+ hint: string | null;
431
+ placeholder: string | null;
432
+ width: "full" | "half";
433
+ section: string | null;
324
434
  })[];
325
435
  configured: boolean;
326
436
  missing: string[];
@@ -333,6 +443,20 @@ export declare const updatePluginSettings: (pluginKey: string, payload: UpdatePl
333
443
  confirm: string | null;
334
444
  }[];
335
445
  admin_page: string | null;
446
+ icon: string | null;
447
+ summary: string | null;
448
+ disable_hint: string | null;
449
+ disable_confirm: string | null;
450
+ features_heading: string | null;
451
+ features_note: string | null;
452
+ all_off_warning: string | null;
453
+ require_enabled_feature: boolean;
454
+ setting_groups: {
455
+ name: string;
456
+ description: string | null;
457
+ note: string | null;
458
+ requires_feature: string | null;
459
+ }[];
336
460
  };
337
461
  }>;
338
462
  export declare const runPluginAction: (pluginKey: string, actionKey: string) => Promise<{
@@ -0,0 +1,49 @@
1
+ import type { AdminPluginFeature, AdminPluginFeatures, AdminPluginSetting, PluginSettingSource } from "@hartl-services/medusa-food-supplements-contracts/types/plugin-features-admin";
2
+ /** Configured feature values (what the base stores), keyed by feature key. */
3
+ export declare const configuredFeatures: (plugin: Pick<AdminPluginFeatures, "features">) => Record<string, boolean>;
4
+ /** Labels of the required settings that have no value, "A, B". */
5
+ export declare const missingLabels: (plugin: Pick<AdminPluginFeatures, "missing" | "settings">) => string;
6
+ /** The plugin has settings that must be filled for it to count as configured. */
7
+ export declare const hasRequiredSettings: (plugin: Pick<AdminPluginFeatures, "settings">) => boolean;
8
+ /** The plugin is not configured: something required is missing. */
9
+ export declare const isUnconfigured: (plugin: Pick<AdminPluginFeatures, "settings" | "configured">) => boolean;
10
+ /**
11
+ * Every top-level feature is switched off (as configured, regardless of the
12
+ * plugin switch). `false` for a plugin without features.
13
+ */
14
+ export declare const allTopLevelFeaturesOff: (plugin: Pick<AdminPluginFeatures, "features">) => boolean;
15
+ /**
16
+ * The feature is the only enabled top-level feature of a plugin that requires
17
+ * one (`require_enabled_feature`): switching it off would be rejected by the
18
+ * server, so the Admin locks it.
19
+ */
20
+ export declare const isLastRequiredFeature: (plugin: Pick<AdminPluginFeatures, "features" | "require_enabled_feature">, feature: Pick<AdminPluginFeature, "key" | "parent_key" | "enabled">) => boolean;
21
+ /** The feature's parent when that parent is off, else `undefined`. */
22
+ export declare const disabledParent: (features: readonly AdminPluginFeature[], feature: AdminPluginFeature) => AdminPluginFeature | undefined;
23
+ /**
24
+ * Labels of the settings whose change deletes the given secret (reverse of
25
+ * `invalidates`), in the order the settings are declared.
26
+ */
27
+ export declare const invalidatedByLabels: (settings: readonly AdminPluginSetting[], secretKey: string) => string[];
28
+ /** Whether a settings group is dimmed: its required feature exists and is not effective. */
29
+ export declare const isGroupDimmed: (features: readonly AdminPluginFeature[], requiresFeature: string | null) => boolean;
30
+ /**
31
+ * Labels of the secrets that a change of `setting` deletes (forward
32
+ * `invalidates`), in the setting's order; unknown keys fall back to the key.
33
+ */
34
+ export declare const invalidatesLabels: (settings: readonly AdminPluginSetting[], setting: Pick<AdminPluginSetting, "invalidates">) => string[];
35
+ /**
36
+ * The description a setting shows in its info tooltip: only when a `hint`
37
+ * takes the place under the field and the description says something else.
38
+ */
39
+ export declare const settingInfoText: (setting: Pick<AdminPluginSetting, "hint" | "description">) => string | null;
40
+ /** The description a page header shows in its info tooltip: when the summary is shown instead and differs. */
41
+ export declare const headerInfoText: (plugin: Pick<AdminPluginFeatures, "summary" | "description">) => string | null;
42
+ /** "default" is the normal case and not worth a line under every field. */
43
+ export declare const showsSourceHint: (source: PluginSettingSource) => boolean;
44
+ /** The plain-language range line ("Zwischen 8 und 128.") is only a separate line when no `hint` explains the field. */
45
+ export declare const showsBoundsLine: (setting: Pick<AdminPluginSetting, "hint">) => boolean;
46
+ /** The plugins in hub order: those that cannot be switched off first, then the server's order. */
47
+ export declare const hubOrder: <T extends {
48
+ switchable: boolean;
49
+ }>(plugins: readonly T[]) => T[];
@@ -0,0 +1,72 @@
1
+ /** Configured feature values (what the base stores), keyed by feature key. */
2
+ export const configuredFeatures = (plugin) => Object.fromEntries(plugin.features.map((feature) => [feature.key, feature.enabled]));
3
+ /** Labels of the required settings that have no value, "A, B". */
4
+ export const missingLabels = (plugin) => plugin.missing
5
+ .map((key) => plugin.settings.find((setting) => setting.key === key)?.label ?? key)
6
+ .join(", ");
7
+ /** The plugin has settings that must be filled for it to count as configured. */
8
+ export const hasRequiredSettings = (plugin) => plugin.settings.some((setting) => setting.required);
9
+ /** The plugin is not configured: something required is missing. */
10
+ export const isUnconfigured = (plugin) => !plugin.configured && hasRequiredSettings(plugin);
11
+ /**
12
+ * Every top-level feature is switched off (as configured, regardless of the
13
+ * plugin switch). `false` for a plugin without features.
14
+ */
15
+ export const allTopLevelFeaturesOff = (plugin) => {
16
+ const topLevel = plugin.features.filter((feature) => feature.parent_key === null);
17
+ return topLevel.length > 0 && topLevel.every((feature) => !feature.enabled);
18
+ };
19
+ /**
20
+ * The feature is the only enabled top-level feature of a plugin that requires
21
+ * one (`require_enabled_feature`): switching it off would be rejected by the
22
+ * server, so the Admin locks it.
23
+ */
24
+ export const isLastRequiredFeature = (plugin, feature) => plugin.require_enabled_feature &&
25
+ feature.parent_key === null &&
26
+ feature.enabled &&
27
+ plugin.features.every((other) => other.key === feature.key || other.parent_key !== null || !other.enabled);
28
+ /** The feature's parent when that parent is off, else `undefined`. */
29
+ export const disabledParent = (features, feature) => {
30
+ const parent = features.find((candidate) => candidate.key === feature.parent_key);
31
+ return parent && !parent.enabled ? parent : undefined;
32
+ };
33
+ /**
34
+ * Labels of the settings whose change deletes the given secret (reverse of
35
+ * `invalidates`), in the order the settings are declared.
36
+ */
37
+ export const invalidatedByLabels = (settings, secretKey) => settings
38
+ .filter((setting) => setting.invalidates.includes(secretKey))
39
+ .map((setting) => setting.label);
40
+ /** Whether a settings group is dimmed: its required feature exists and is not effective. */
41
+ export const isGroupDimmed = (features, requiresFeature) => requiresFeature !== null &&
42
+ features.find((feature) => feature.key === requiresFeature)
43
+ ?.effective_enabled === false;
44
+ /**
45
+ * Labels of the secrets that a change of `setting` deletes (forward
46
+ * `invalidates`), in the setting's order; unknown keys fall back to the key.
47
+ */
48
+ export const invalidatesLabels = (settings, setting) => setting.invalidates.map((key) => settings.find((candidate) => candidate.key === key)?.label ?? key);
49
+ /**
50
+ * The description a setting shows in its info tooltip: only when a `hint`
51
+ * takes the place under the field and the description says something else.
52
+ */
53
+ export const settingInfoText = (setting) => setting.hint !== null &&
54
+ setting.description !== null &&
55
+ setting.description !== setting.hint
56
+ ? setting.description
57
+ : null;
58
+ /** The description a page header shows in its info tooltip: when the summary is shown instead and differs. */
59
+ export const headerInfoText = (plugin) => plugin.summary !== null &&
60
+ plugin.description !== null &&
61
+ plugin.description !== plugin.summary
62
+ ? plugin.description
63
+ : null;
64
+ /** "default" is the normal case and not worth a line under every field. */
65
+ export const showsSourceHint = (source) => source !== "default";
66
+ /** The plain-language range line ("Zwischen 8 und 128.") is only a separate line when no `hint` explains the field. */
67
+ export const showsBoundsLine = (setting) => setting.hint === null;
68
+ /** The plugins in hub order: those that cannot be switched off first, then the server's order. */
69
+ export const hubOrder = (plugins) => [
70
+ ...plugins.filter((plugin) => !plugin.switchable),
71
+ ...plugins.filter((plugin) => plugin.switchable),
72
+ ];
@@ -12,17 +12,6 @@ export declare const initialSettingsDraft: (settings: readonly AdminPluginSettin
12
12
  export declare const isHexColor: (value: string) => boolean;
13
13
  /** Colors are typed and sent lowercase; surrounding spaces are dropped. */
14
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[];
26
15
  /**
27
16
  * Keys of number fields whose input the browser could not parse (e.g. "1e"):
28
17
  * the input then reports `""`, which must not be read as "cleared".
@@ -30,7 +19,7 @@ export declare const groupSettings: (settings: readonly AdminPluginSetting[]) =>
30
19
  export type UnparsableKeys = readonly string[];
31
20
  /**
32
21
  * Keys whose draft value cannot be sent: unparsable, not a number or
33
- * outside min/max, or a color that is not `#rrggbb`. Saving is disabled while any key is listed.
22
+ * outside min/max, a fraction for an integer setting, or a color that is not `#rrggbb`. Saving is disabled while any key is listed.
34
23
  */
35
24
  export declare const invalidDraftKeys: (settings: readonly AdminPluginSetting[], draft: SettingsDraft, unparsable?: UnparsableKeys) => string[];
36
25
  /**
@@ -13,24 +13,6 @@ const HEX_COLOR = /^#[0-9a-fA-F]{6}$/;
13
13
  export const isHexColor = (value) => HEX_COLOR.test(value);
14
14
  /** Colors are typed and sent lowercase; surrounding spaces are dropped. */
15
15
  export const normalizeColorInput = (value) => value.trim().toLowerCase();
16
- /**
17
- * Splits the settings (in their given order) into consecutive runs of the
18
- * same `group`; a new section starts whenever the group differs from the
19
- * previous setting's group.
20
- */
21
- export const groupSettings = (settings) => {
22
- const sections = [];
23
- for (const setting of settings) {
24
- const last = sections[sections.length - 1];
25
- if (last && last.group === setting.group) {
26
- last.settings.push(setting);
27
- }
28
- else {
29
- sections.push({ group: setting.group, settings: [setting] });
30
- }
31
- }
32
- return sections;
33
- };
34
16
  const outsideBounds = (setting, value) => (setting.min !== null && value < setting.min) ||
35
17
  (setting.max !== null && value > setting.max);
36
18
  const numberEntryValue = (entry) => {
@@ -39,7 +21,7 @@ const numberEntryValue = (entry) => {
39
21
  };
40
22
  /**
41
23
  * Keys whose draft value cannot be sent: unparsable, not a number or
42
- * outside min/max, or a color that is not `#rrggbb`. Saving is disabled while any key is listed.
24
+ * outside min/max, a fraction for an integer setting, or a color that is not `#rrggbb`. Saving is disabled while any key is listed.
43
25
  */
44
26
  export const invalidDraftKeys = (settings, draft, unparsable = []) => settings
45
27
  .filter((setting) => {
@@ -60,7 +42,9 @@ export const invalidDraftKeys = (settings, draft, unparsable = []) => settings
60
42
  return false;
61
43
  }
62
44
  const value = numberEntryValue(entry);
63
- return value === null || outsideBounds(setting, value);
45
+ return (value === null ||
46
+ outsideBounds(setting, value) ||
47
+ (setting.integer && !Number.isInteger(value)));
64
48
  })
65
49
  .map((setting) => setting.key);
66
50
  /**
@@ -0,0 +1,43 @@
1
+ import type { AdminPluginSetting, AdminPluginSettingGroup } from "@hartl-services/medusa-food-supplements-contracts/types/plugin-features-admin";
2
+ /** One row of fields: a full-width setting, or consecutive `half` settings sharing a row. */
3
+ export type SettingFieldRow = {
4
+ kind: "full";
5
+ setting: AdminPluginSetting;
6
+ } | {
7
+ kind: "half";
8
+ settings: AdminPluginSetting[];
9
+ };
10
+ /**
11
+ * A run of rows in a group. Boolean settings are switch rows of their own;
12
+ * all other settings between two switches (or two sub-headings) share one
13
+ * `fields` block. `heading` is the sub-heading that starts the block.
14
+ */
15
+ export type SettingBlock = {
16
+ kind: "fields";
17
+ heading: string | null;
18
+ rows: SettingFieldRow[];
19
+ } | {
20
+ kind: "switch";
21
+ heading: string | null;
22
+ setting: AdminPluginSetting;
23
+ };
24
+ /** One card of the settings form: a group with its metadata and blocks. */
25
+ export type SettingGroupView = {
26
+ /** Group name as in `setting.group`; `null` = the ungrouped settings. */
27
+ name: string | null;
28
+ /** Card heading (the group name, or the fallback title for ungrouped). */
29
+ title: string;
30
+ description: string | null;
31
+ note: string | null;
32
+ requiresFeature: string | null;
33
+ settings: AdminPluginSetting[];
34
+ blocks: SettingBlock[];
35
+ };
36
+ /** Blocks of one group's settings (in their given order). */
37
+ export declare const buildSettingBlocks: (settings: readonly AdminPluginSetting[]) => SettingBlock[];
38
+ /**
39
+ * Groups the settings into cards, in order of the first appearance of each
40
+ * group; settings without a group form one card titled `ungroupedTitle`.
41
+ * `groups` supplies the description, note and required feature per group.
42
+ */
43
+ export declare const buildSettingGroups: (settings: readonly AdminPluginSetting[], groups: readonly AdminPluginSettingGroup[], ungroupedTitle: string) => SettingGroupView[];
@@ -0,0 +1,66 @@
1
+ /** Blocks of one group's settings (in their given order). */
2
+ export const buildSettingBlocks = (settings) => {
3
+ const blocks = [];
4
+ let previousSection = null;
5
+ for (const [index, setting] of settings.entries()) {
6
+ const startsSection = setting.section !== null && (index === 0 || setting.section !== previousSection);
7
+ const sectionChanged = index > 0 && setting.section !== previousSection;
8
+ previousSection = setting.section;
9
+ const heading = startsSection ? setting.section : null;
10
+ if (setting.type === "boolean") {
11
+ blocks.push({ kind: "switch", heading, setting });
12
+ continue;
13
+ }
14
+ const last = blocks[blocks.length - 1];
15
+ let block;
16
+ if (last?.kind === "fields" && !startsSection && !sectionChanged) {
17
+ block = last;
18
+ }
19
+ else {
20
+ block = { kind: "fields", heading, rows: [] };
21
+ blocks.push(block);
22
+ }
23
+ const lastRow = block.rows[block.rows.length - 1];
24
+ if (setting.width === "half") {
25
+ if (lastRow?.kind === "half") {
26
+ lastRow.settings.push(setting);
27
+ }
28
+ else {
29
+ block.rows.push({ kind: "half", settings: [setting] });
30
+ }
31
+ }
32
+ else {
33
+ block.rows.push({ kind: "full", setting });
34
+ }
35
+ }
36
+ return blocks;
37
+ };
38
+ /**
39
+ * Groups the settings into cards, in order of the first appearance of each
40
+ * group; settings without a group form one card titled `ungroupedTitle`.
41
+ * `groups` supplies the description, note and required feature per group.
42
+ */
43
+ export const buildSettingGroups = (settings, groups, ungroupedTitle) => {
44
+ const byName = new Map();
45
+ for (const setting of settings) {
46
+ const entry = byName.get(setting.group);
47
+ if (entry) {
48
+ entry.push(setting);
49
+ }
50
+ else {
51
+ byName.set(setting.group, [setting]);
52
+ }
53
+ }
54
+ return [...byName.entries()].map(([name, groupSettings]) => {
55
+ const meta = name === null ? undefined : groups.find((group) => group.name === name);
56
+ return {
57
+ name,
58
+ title: name ?? ungroupedTitle,
59
+ description: meta?.description ?? null,
60
+ note: meta?.note ?? null,
61
+ requiresFeature: meta?.requires_feature ?? null,
62
+ settings: groupSettings,
63
+ blocks: buildSettingBlocks(groupSettings),
64
+ };
65
+ });
66
+ };