@hartl-services/medusa-base 2.7.0 → 2.8.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.
- package/.medusa/server/src/admin/admin-components/features/plugin-features/components/PluginSettingsForm.js +9 -5
- package/.medusa/server/src/admin/admin-components/features/plugin-features/hooks/usePluginFeatureEnabled.d.ts +5 -1
- package/.medusa/server/src/admin/admin-components/features/plugin-features/hooks/usePluginFeatures.d.ts +20 -4
- package/.medusa/server/src/admin/admin-components/features/plugin-features/hooks/usePluginSettingsForm.d.ts +5 -1
- package/.medusa/server/src/admin/admin-components/features/plugin-features/lib/plugin-features-admin-client.d.ts +20 -4
- package/.medusa/server/src/admin/admin-components/features/plugin-features/lib/settings-layout.d.ts +4 -0
- package/.medusa/server/src/admin/admin-components/features/plugin-features/lib/settings-layout.js +4 -0
- package/.medusa/server/src/admin/index.js +54 -36
- package/.medusa/server/src/admin/index.mjs +55 -37
- package/.medusa/server/src/customer-auth/plugin-features.js +10 -10
- package/.medusa/server/src/modules/plugin-features/domain/plugin-settings.js +27 -6
- package/.medusa/server/src/modules/plugin-features/service.js +4 -3
- package/.medusa/server/src/public/descriptor.js +24 -3
- package/.medusa/server/src/shared/lib/dates.js +8 -2
- package/dist/customer-auth/plugin-features.js +9 -9
- package/dist/public/descriptor.js +23 -2
- package/dist/public/types.d.ts +14 -4
- package/dist/shared/lib/dates.d.ts +2 -0
- package/dist/shared/lib/dates.js +7 -1
- package/package.json +2 -2
|
@@ -15,6 +15,7 @@ const SETTING_TYPES = new Set([
|
|
|
15
15
|
"select",
|
|
16
16
|
"image",
|
|
17
17
|
"color",
|
|
18
|
+
"date",
|
|
18
19
|
]);
|
|
19
20
|
const HEX_COLOR_PATTERN = /^#[0-9a-f]{6}$/;
|
|
20
21
|
const ACTION_MODES = new Set(["sync", "background"]);
|
|
@@ -24,7 +25,7 @@ const ADMIN_PAGE_PATTERN = /^\/settings\/hartl-services(\/[a-z0-9][a-z0-9_-]*)+$
|
|
|
24
25
|
const ICON_NAMES = new Set(plugin_icons_1.PLUGIN_ICON_NAMES);
|
|
25
26
|
const SETTING_WIDTHS = new Set(["full", "half"]);
|
|
26
27
|
/** Types an input placeholder makes no sense for. */
|
|
27
|
-
const NO_PLACEHOLDER_TYPES = new Set(["boolean", "select", "image", "color"]);
|
|
28
|
+
const NO_PLACEHOLDER_TYPES = new Set(["boolean", "select", "image", "color", "date"]);
|
|
28
29
|
const invalid = (pluginKey, message) => new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, `Ungültige Funktionsschalter für Plugin "${pluginKey}": ${message}`);
|
|
29
30
|
const defaultMatchesType = (setting) => {
|
|
30
31
|
const value = setting.default;
|
|
@@ -36,6 +37,8 @@ const defaultMatchesType = (setting) => {
|
|
|
36
37
|
return typeof value === "string" && (0, lib_1.isHttpUrl)(value);
|
|
37
38
|
case "color":
|
|
38
39
|
return typeof value === "string" && HEX_COLOR_PATTERN.test(value);
|
|
40
|
+
case "date":
|
|
41
|
+
return typeof value === "string" && (0, lib_1.isCalendarDate)(value);
|
|
39
42
|
case "number":
|
|
40
43
|
return (typeof value === "number" &&
|
|
41
44
|
Number.isFinite(value) &&
|
|
@@ -222,9 +225,26 @@ const validateAdminPage = (pluginKey, path) => {
|
|
|
222
225
|
throw invalid(pluginKey, `admin_page "${String(path)}" muss unter "${ADMIN_PAGE_PREFIX}<plugin>" liegen und darf nicht mit "${BASE_PAGE_PREFIX}" beginnen.`);
|
|
223
226
|
}
|
|
224
227
|
};
|
|
228
|
+
/**
|
|
229
|
+
* `visible_when` points at a select or boolean setting outside the group and
|
|
230
|
+
* `equals` is one of its possible values.
|
|
231
|
+
*/
|
|
232
|
+
const validateVisibleWhen = (pluginKey, groupName, condition, settings) => {
|
|
233
|
+
if (condition === undefined) {
|
|
234
|
+
return;
|
|
235
|
+
}
|
|
236
|
+
const { setting: key, equals } = (condition ?? {});
|
|
237
|
+
const target = settings.find((setting) => setting.key === key);
|
|
238
|
+
const fits = target?.type === "select"
|
|
239
|
+
? (target.options ?? []).some((option) => option.value === equals)
|
|
240
|
+
: target?.type === "boolean" && typeof equals === "boolean";
|
|
241
|
+
if (!target || target.group === groupName || !fits) {
|
|
242
|
+
throw invalid(pluginKey, `Einstellungsgruppe "${groupName}": visible_when muss auf eine Auswahl oder einen Schalter außerhalb der Gruppe mit einem ihrer Werte zeigen.`);
|
|
243
|
+
}
|
|
244
|
+
};
|
|
225
245
|
/**
|
|
226
246
|
* Metadata per settings group: unique names, each used by a setting's
|
|
227
|
-
* `group`, `requires_feature` a declared feature key.
|
|
247
|
+
* `group`, `requires_feature` a declared feature key, `visible_when` valid.
|
|
228
248
|
*/
|
|
229
249
|
const validateSettingGroups = (pluginKey, groups, settings, featureKeys) => {
|
|
230
250
|
if (groups === undefined) {
|
|
@@ -255,6 +275,7 @@ const validateSettingGroups = (pluginKey, groups, settings, featureKeys) => {
|
|
|
255
275
|
!featureKeys.has(group.requires_feature)) {
|
|
256
276
|
throw invalid(pluginKey, `Einstellungsgruppe "${group.name}": requires_feature "${String(group.requires_feature)}" ist kein Feature dieses Plugins.`);
|
|
257
277
|
}
|
|
278
|
+
validateVisibleWhen(pluginKey, group.name, group.visible_when, settings);
|
|
258
279
|
}
|
|
259
280
|
};
|
|
260
281
|
/** Optional texts and icon of the plugin's Admin page. */
|
package/dist/public/types.d.ts
CHANGED
|
@@ -36,8 +36,9 @@ export type PluginFeatureDefinition<K extends string = string> = {
|
|
|
36
36
|
/**
|
|
37
37
|
* `image`: public http(s) URL of an image the Admin uploads (PNG/JPEG).
|
|
38
38
|
* `color`: lowercase hex color `#rrggbb`.
|
|
39
|
+
* `date`: calendar day `YYYY-MM-DD`.
|
|
39
40
|
*/
|
|
40
|
-
export type PluginSettingType = "string" | "url" | "number" | "boolean" | "secret" | "select" | "image" | "color";
|
|
41
|
+
export type PluginSettingType = "string" | "url" | "number" | "boolean" | "secret" | "select" | "image" | "color" | "date";
|
|
41
42
|
/** One allowed value of a `"select"` setting. */
|
|
42
43
|
export type PluginSettingOption = {
|
|
43
44
|
readonly value: string;
|
|
@@ -76,7 +77,7 @@ export type PluginSettingDefinition<S extends string = string> = {
|
|
|
76
77
|
* Short text under the field; the Admin shows `hint ?? description`.
|
|
77
78
|
*/
|
|
78
79
|
readonly hint?: string;
|
|
79
|
-
/** Input placeholder; not for boolean, select, image and
|
|
80
|
+
/** Input placeholder; not for boolean, select, image, color and date. */
|
|
80
81
|
readonly placeholder?: string;
|
|
81
82
|
/**
|
|
82
83
|
* `"half"`: consecutive half-width settings share one two-column row.
|
|
@@ -90,7 +91,7 @@ export type PluginSettingDefinition<S extends string = string> = {
|
|
|
90
91
|
readonly section?: string;
|
|
91
92
|
};
|
|
92
93
|
/** Metadata of one settings group, keyed by the `group` name of its settings. */
|
|
93
|
-
export type PluginSettingGroupDefinition<K extends string = string> = {
|
|
94
|
+
export type PluginSettingGroupDefinition<K extends string = string, S extends string = string> = {
|
|
94
95
|
/** Equals the `group` of at least one setting; unique per plugin. */
|
|
95
96
|
readonly name: string;
|
|
96
97
|
/** Explanatory text under the group heading. */
|
|
@@ -102,6 +103,15 @@ export type PluginSettingGroupDefinition<K extends string = string> = {
|
|
|
102
103
|
* (still editable) while the feature is not effectively enabled.
|
|
103
104
|
*/
|
|
104
105
|
readonly requires_feature?: K;
|
|
106
|
+
/**
|
|
107
|
+
* The group applies only while the select or boolean setting `setting`
|
|
108
|
+
* (of another group) resolves to `equals`. Otherwise the Admin hides it and
|
|
109
|
+
* its required settings do not count as missing; stored values are kept.
|
|
110
|
+
*/
|
|
111
|
+
readonly visible_when?: {
|
|
112
|
+
readonly setting: S;
|
|
113
|
+
readonly equals: string | boolean;
|
|
114
|
+
};
|
|
105
115
|
};
|
|
106
116
|
export type PluginActionMode = "sync" | "background";
|
|
107
117
|
export type PluginActionDefinition<A extends string = string> = {
|
|
@@ -161,7 +171,7 @@ export type PluginFeatureDescriptor<K extends string = string, S extends string
|
|
|
161
171
|
*/
|
|
162
172
|
readonly require_enabled_feature?: true;
|
|
163
173
|
/** Metadata for the groups used in `settings[].group`. */
|
|
164
|
-
readonly setting_groups?: readonly PluginSettingGroupDefinition<K>[];
|
|
174
|
+
readonly setting_groups?: readonly PluginSettingGroupDefinition<K, S>[];
|
|
165
175
|
};
|
|
166
176
|
/** Values a plugin received from medusa-config; the base shows them as source "config". */
|
|
167
177
|
export type PluginSettingsFallback<S extends string = string> = Partial<Record<S, PluginSettingValue | null | undefined>>;
|
|
@@ -10,3 +10,5 @@ export declare const toWireDate: (value: Date | string) => string;
|
|
|
10
10
|
export declare const toOptionalWireDate: (value: Date | string | null | undefined) => string | null;
|
|
11
11
|
/** Whether the value is an IANA time zone this runtime knows ("Europe/Vienna"). */
|
|
12
12
|
export declare const isValidTimeZone: (value: unknown) => value is string;
|
|
13
|
+
/** Whether the value is an existing calendar day written `yyyy-mm-dd`. */
|
|
14
|
+
export declare const isCalendarDate: (value: unknown) => value is string;
|
package/dist/shared/lib/dates.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.isValidTimeZone = exports.toOptionalWireDate = exports.toWireDate = exports.toIsoDate = exports.startOfUtcDate = exports.toValidDate = void 0;
|
|
3
|
+
exports.isCalendarDate = exports.isValidTimeZone = exports.toOptionalWireDate = exports.toWireDate = exports.toIsoDate = exports.startOfUtcDate = exports.toValidDate = void 0;
|
|
4
4
|
const utils_1 = require("@medusajs/framework/utils");
|
|
5
5
|
/** A valid `Date`; throws `INVALID_DATA` for an unparsable value. */
|
|
6
6
|
const toValidDate = (value, message = "Invalid date.") => {
|
|
@@ -40,3 +40,9 @@ const isValidTimeZone = (value) => {
|
|
|
40
40
|
}
|
|
41
41
|
};
|
|
42
42
|
exports.isValidTimeZone = isValidTimeZone;
|
|
43
|
+
/** Whether the value is an existing calendar day written `yyyy-mm-dd`. */
|
|
44
|
+
const isCalendarDate = (value) => typeof value === "string" &&
|
|
45
|
+
/^\d{4}-\d{2}-\d{2}$/.test(value) &&
|
|
46
|
+
!Number.isNaN(Date.parse(`${value}T00:00:00Z`)) &&
|
|
47
|
+
new Date(`${value}T00:00:00Z`).toISOString().slice(0, 10) === value;
|
|
48
|
+
exports.isCalendarDate = isCalendarDate;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hartl-services/medusa-base",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.8.0",
|
|
4
4
|
"description": "Base plugin for Hartl Services Medusa shops: per-plugin feature toggles with a generic Admin settings page, a Store endpoint for storefronts, enforcement helpers, the complete-cart hook composition, the root redirect, cart-promotion link repair, the built-in E-Mail, Documents and S3 file storage modules, config helpers with the turnkey food-shop preset, and the Sentry logger wrapper and instrumentation.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"files": [
|
|
@@ -101,7 +101,7 @@
|
|
|
101
101
|
"mime-types": "3.0.1",
|
|
102
102
|
"nodemailer": "6.10.1",
|
|
103
103
|
"ulid": "^2.4.0",
|
|
104
|
-
"@hartl-services/medusa-food-supplements-contracts": "^0.
|
|
104
|
+
"@hartl-services/medusa-food-supplements-contracts": "^0.28.0"
|
|
105
105
|
},
|
|
106
106
|
"devDependencies": {
|
|
107
107
|
"@medusajs/admin-sdk": "2.19.0",
|