medusa-dynamic-metadata 0.0.8 → 0.0.10
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/index.js +31 -27
- package/.medusa/server/src/admin/index.mjs +31 -27
- package/.medusa/server/src/shared/metadata/utils.js +33 -18
- package/README.md +295 -312
- package/package.json +1 -1
|
@@ -409,6 +409,12 @@ const OPTION_TYPES = /* @__PURE__ */ new Set([
|
|
|
409
409
|
"radio",
|
|
410
410
|
"checkbox"
|
|
411
411
|
]);
|
|
412
|
+
const COERCE_EMPTY_STRING_FOR_TYPES = /* @__PURE__ */ new Set([
|
|
413
|
+
"text",
|
|
414
|
+
"textarea",
|
|
415
|
+
"richtext",
|
|
416
|
+
"markdown"
|
|
417
|
+
]);
|
|
412
418
|
const BOOLEAN_TRUES = /* @__PURE__ */ new Set(["true", "1", "yes", "y", "on"]);
|
|
413
419
|
const BOOLEAN_FALSES = /* @__PURE__ */ new Set(["false", "0", "no", "n", "off"]);
|
|
414
420
|
const EMAIL_REGEX = /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/;
|
|
@@ -466,7 +472,10 @@ function buildInitialFormState(descriptors, metadata) {
|
|
|
466
472
|
return descriptors.reduce(
|
|
467
473
|
(acc, descriptor) => {
|
|
468
474
|
const currentValue = base[descriptor.key];
|
|
469
|
-
const
|
|
475
|
+
const emptyStringCountsAsValue = COERCE_EMPTY_STRING_FOR_TYPES.has(
|
|
476
|
+
descriptor.type
|
|
477
|
+
);
|
|
478
|
+
const hasValue = currentValue !== void 0 && currentValue !== null && (currentValue !== "" || emptyStringCountsAsValue);
|
|
470
479
|
const valueToUse = hasValue ? currentValue : descriptor.default_value;
|
|
471
480
|
acc[descriptor.key] = normalizeFormValue(descriptor, valueToUse);
|
|
472
481
|
return acc;
|
|
@@ -477,18 +486,16 @@ function buildInitialFormState(descriptors, metadata) {
|
|
|
477
486
|
function buildMetadataPayload({
|
|
478
487
|
descriptors,
|
|
479
488
|
values,
|
|
480
|
-
originalMetadata
|
|
489
|
+
originalMetadata: _originalMetadata
|
|
481
490
|
}) {
|
|
482
|
-
const
|
|
491
|
+
const result = {};
|
|
483
492
|
descriptors.forEach((descriptor) => {
|
|
484
493
|
const coerced = coerceMetadataValue(descriptor, values[descriptor.key]);
|
|
485
|
-
if (coerced
|
|
486
|
-
|
|
487
|
-
} else {
|
|
488
|
-
base[descriptor.key] = coerced;
|
|
494
|
+
if (coerced !== void 0) {
|
|
495
|
+
result[descriptor.key] = coerced;
|
|
489
496
|
}
|
|
490
497
|
});
|
|
491
|
-
return
|
|
498
|
+
return result;
|
|
492
499
|
}
|
|
493
500
|
function hasMetadataChanges({
|
|
494
501
|
descriptors,
|
|
@@ -669,7 +676,9 @@ function normalizeFormValue(descriptor, currentValue) {
|
|
|
669
676
|
return "";
|
|
670
677
|
}
|
|
671
678
|
function coerceMetadataValue(descriptor, value) {
|
|
672
|
-
if (value == null
|
|
679
|
+
if (value == null) {
|
|
680
|
+
return COERCE_EMPTY_STRING_FOR_TYPES.has(descriptor.type) ? "" : void 0;
|
|
681
|
+
}
|
|
673
682
|
if (descriptor.type === "bool") {
|
|
674
683
|
if (typeof value === "boolean") return value;
|
|
675
684
|
if (typeof value === "number") return value !== 0;
|
|
@@ -680,7 +689,9 @@ function coerceMetadataValue(descriptor, value) {
|
|
|
680
689
|
return Boolean(value);
|
|
681
690
|
}
|
|
682
691
|
if (descriptor.type === "number" || descriptor.type === "integer" || descriptor.type === "float") {
|
|
683
|
-
const
|
|
692
|
+
const raw = typeof value === "number" ? String(value) : String(value).trim();
|
|
693
|
+
if (raw === "") return void 0;
|
|
694
|
+
const num = Number(raw);
|
|
684
695
|
return isNaN(num) ? void 0 : descriptor.type === "integer" ? Math.floor(num) : num;
|
|
685
696
|
}
|
|
686
697
|
if (descriptor.type === "multiselect" || descriptor.type === "checkbox") {
|
|
@@ -696,16 +707,19 @@ function coerceMetadataValue(descriptor, value) {
|
|
|
696
707
|
if (Array.isArray(value)) {
|
|
697
708
|
return value;
|
|
698
709
|
}
|
|
699
|
-
const
|
|
700
|
-
if (!
|
|
710
|
+
const str2 = String(value).trim();
|
|
711
|
+
if (!str2) return void 0;
|
|
701
712
|
try {
|
|
702
|
-
return JSON.parse(
|
|
713
|
+
return JSON.parse(str2);
|
|
703
714
|
} catch {
|
|
704
715
|
return void 0;
|
|
705
716
|
}
|
|
706
717
|
}
|
|
707
|
-
const
|
|
708
|
-
|
|
718
|
+
const str = String(value);
|
|
719
|
+
const trimmed = str.trim();
|
|
720
|
+
if (!trimmed) {
|
|
721
|
+
return COERCE_EMPTY_STRING_FOR_TYPES.has(descriptor.type) ? "" : void 0;
|
|
722
|
+
}
|
|
709
723
|
return trimmed;
|
|
710
724
|
}
|
|
711
725
|
function normalizeKey(value) {
|
|
@@ -1236,7 +1250,7 @@ const MetadataTableWidget = ({
|
|
|
1236
1250
|
}) })
|
|
1237
1251
|
] }) }),
|
|
1238
1252
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-y-3 border-t border-ui-border-subtle pt-3 md:flex-row md:items-center md:justify-between", children: [
|
|
1239
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-muted", children: "
|
|
1253
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-muted", children: "Save sends only the keys shown in this table. Clearing a text field sends that key as an empty string; other cleared field types omit the key." }),
|
|
1240
1254
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-x-2", children: [
|
|
1241
1255
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1242
1256
|
ui.Button,
|
|
@@ -1255,7 +1269,7 @@ const MetadataTableWidget = ({
|
|
|
1255
1269
|
onClick: handleSubmit,
|
|
1256
1270
|
disabled: !isDirty || hasErrors || isSaving,
|
|
1257
1271
|
isLoading: isSaving,
|
|
1258
|
-
children: "Save
|
|
1272
|
+
children: "Save"
|
|
1259
1273
|
}
|
|
1260
1274
|
)
|
|
1261
1275
|
] })
|
|
@@ -1714,17 +1728,10 @@ const UniversalMetadataWidget = ({ data, zone }) => {
|
|
|
1714
1728
|
try {
|
|
1715
1729
|
return resolveEntityType(zone, data);
|
|
1716
1730
|
} catch (err) {
|
|
1717
|
-
console.error("[UniversalMetadataWidget] Entity type resolution failed:", err);
|
|
1718
1731
|
return void 0;
|
|
1719
1732
|
}
|
|
1720
1733
|
}, [zone, data]);
|
|
1721
1734
|
if (!entityType) {
|
|
1722
|
-
if (process.env.NODE_ENV !== "production") {
|
|
1723
|
-
console.warn("[UniversalMetadataWidget] Could not resolve entity type.", {
|
|
1724
|
-
zone,
|
|
1725
|
-
dataKeys: data ? Object.keys(data) : []
|
|
1726
|
-
});
|
|
1727
|
-
}
|
|
1728
1735
|
return null;
|
|
1729
1736
|
}
|
|
1730
1737
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -1741,9 +1748,6 @@ const MetadataWidgetLoader = ({ data, entityType, queryKey }) => {
|
|
|
1741
1748
|
entity: entityType,
|
|
1742
1749
|
enabled: true
|
|
1743
1750
|
});
|
|
1744
|
-
if (process.env.NODE_ENV !== "production") {
|
|
1745
|
-
console.debug("[UniversalMetadataWidget]", { entityType, descriptors: descriptors.length, isPending, queryKey });
|
|
1746
|
-
}
|
|
1747
1751
|
if (!isPending && descriptors.length === 0) {
|
|
1748
1752
|
return null;
|
|
1749
1753
|
}
|
|
@@ -408,6 +408,12 @@ const OPTION_TYPES = /* @__PURE__ */ new Set([
|
|
|
408
408
|
"radio",
|
|
409
409
|
"checkbox"
|
|
410
410
|
]);
|
|
411
|
+
const COERCE_EMPTY_STRING_FOR_TYPES = /* @__PURE__ */ new Set([
|
|
412
|
+
"text",
|
|
413
|
+
"textarea",
|
|
414
|
+
"richtext",
|
|
415
|
+
"markdown"
|
|
416
|
+
]);
|
|
411
417
|
const BOOLEAN_TRUES = /* @__PURE__ */ new Set(["true", "1", "yes", "y", "on"]);
|
|
412
418
|
const BOOLEAN_FALSES = /* @__PURE__ */ new Set(["false", "0", "no", "n", "off"]);
|
|
413
419
|
const EMAIL_REGEX = /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/;
|
|
@@ -465,7 +471,10 @@ function buildInitialFormState(descriptors, metadata) {
|
|
|
465
471
|
return descriptors.reduce(
|
|
466
472
|
(acc, descriptor) => {
|
|
467
473
|
const currentValue = base[descriptor.key];
|
|
468
|
-
const
|
|
474
|
+
const emptyStringCountsAsValue = COERCE_EMPTY_STRING_FOR_TYPES.has(
|
|
475
|
+
descriptor.type
|
|
476
|
+
);
|
|
477
|
+
const hasValue = currentValue !== void 0 && currentValue !== null && (currentValue !== "" || emptyStringCountsAsValue);
|
|
469
478
|
const valueToUse = hasValue ? currentValue : descriptor.default_value;
|
|
470
479
|
acc[descriptor.key] = normalizeFormValue(descriptor, valueToUse);
|
|
471
480
|
return acc;
|
|
@@ -476,18 +485,16 @@ function buildInitialFormState(descriptors, metadata) {
|
|
|
476
485
|
function buildMetadataPayload({
|
|
477
486
|
descriptors,
|
|
478
487
|
values,
|
|
479
|
-
originalMetadata
|
|
488
|
+
originalMetadata: _originalMetadata
|
|
480
489
|
}) {
|
|
481
|
-
const
|
|
490
|
+
const result = {};
|
|
482
491
|
descriptors.forEach((descriptor) => {
|
|
483
492
|
const coerced = coerceMetadataValue(descriptor, values[descriptor.key]);
|
|
484
|
-
if (coerced
|
|
485
|
-
|
|
486
|
-
} else {
|
|
487
|
-
base[descriptor.key] = coerced;
|
|
493
|
+
if (coerced !== void 0) {
|
|
494
|
+
result[descriptor.key] = coerced;
|
|
488
495
|
}
|
|
489
496
|
});
|
|
490
|
-
return
|
|
497
|
+
return result;
|
|
491
498
|
}
|
|
492
499
|
function hasMetadataChanges({
|
|
493
500
|
descriptors,
|
|
@@ -668,7 +675,9 @@ function normalizeFormValue(descriptor, currentValue) {
|
|
|
668
675
|
return "";
|
|
669
676
|
}
|
|
670
677
|
function coerceMetadataValue(descriptor, value) {
|
|
671
|
-
if (value == null
|
|
678
|
+
if (value == null) {
|
|
679
|
+
return COERCE_EMPTY_STRING_FOR_TYPES.has(descriptor.type) ? "" : void 0;
|
|
680
|
+
}
|
|
672
681
|
if (descriptor.type === "bool") {
|
|
673
682
|
if (typeof value === "boolean") return value;
|
|
674
683
|
if (typeof value === "number") return value !== 0;
|
|
@@ -679,7 +688,9 @@ function coerceMetadataValue(descriptor, value) {
|
|
|
679
688
|
return Boolean(value);
|
|
680
689
|
}
|
|
681
690
|
if (descriptor.type === "number" || descriptor.type === "integer" || descriptor.type === "float") {
|
|
682
|
-
const
|
|
691
|
+
const raw = typeof value === "number" ? String(value) : String(value).trim();
|
|
692
|
+
if (raw === "") return void 0;
|
|
693
|
+
const num = Number(raw);
|
|
683
694
|
return isNaN(num) ? void 0 : descriptor.type === "integer" ? Math.floor(num) : num;
|
|
684
695
|
}
|
|
685
696
|
if (descriptor.type === "multiselect" || descriptor.type === "checkbox") {
|
|
@@ -695,16 +706,19 @@ function coerceMetadataValue(descriptor, value) {
|
|
|
695
706
|
if (Array.isArray(value)) {
|
|
696
707
|
return value;
|
|
697
708
|
}
|
|
698
|
-
const
|
|
699
|
-
if (!
|
|
709
|
+
const str2 = String(value).trim();
|
|
710
|
+
if (!str2) return void 0;
|
|
700
711
|
try {
|
|
701
|
-
return JSON.parse(
|
|
712
|
+
return JSON.parse(str2);
|
|
702
713
|
} catch {
|
|
703
714
|
return void 0;
|
|
704
715
|
}
|
|
705
716
|
}
|
|
706
|
-
const
|
|
707
|
-
|
|
717
|
+
const str = String(value);
|
|
718
|
+
const trimmed = str.trim();
|
|
719
|
+
if (!trimmed) {
|
|
720
|
+
return COERCE_EMPTY_STRING_FOR_TYPES.has(descriptor.type) ? "" : void 0;
|
|
721
|
+
}
|
|
708
722
|
return trimmed;
|
|
709
723
|
}
|
|
710
724
|
function normalizeKey(value) {
|
|
@@ -1235,7 +1249,7 @@ const MetadataTableWidget = ({
|
|
|
1235
1249
|
}) })
|
|
1236
1250
|
] }) }),
|
|
1237
1251
|
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-y-3 border-t border-ui-border-subtle pt-3 md:flex-row md:items-center md:justify-between", children: [
|
|
1238
|
-
/* @__PURE__ */ jsx(Text, { className: "text-ui-fg-muted", children: "
|
|
1252
|
+
/* @__PURE__ */ jsx(Text, { className: "text-ui-fg-muted", children: "Save sends only the keys shown in this table. Clearing a text field sends that key as an empty string; other cleared field types omit the key." }),
|
|
1239
1253
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-x-2", children: [
|
|
1240
1254
|
/* @__PURE__ */ jsx(
|
|
1241
1255
|
Button,
|
|
@@ -1254,7 +1268,7 @@ const MetadataTableWidget = ({
|
|
|
1254
1268
|
onClick: handleSubmit,
|
|
1255
1269
|
disabled: !isDirty || hasErrors || isSaving,
|
|
1256
1270
|
isLoading: isSaving,
|
|
1257
|
-
children: "Save
|
|
1271
|
+
children: "Save"
|
|
1258
1272
|
}
|
|
1259
1273
|
)
|
|
1260
1274
|
] })
|
|
@@ -1713,17 +1727,10 @@ const UniversalMetadataWidget = ({ data, zone }) => {
|
|
|
1713
1727
|
try {
|
|
1714
1728
|
return resolveEntityType(zone, data);
|
|
1715
1729
|
} catch (err) {
|
|
1716
|
-
console.error("[UniversalMetadataWidget] Entity type resolution failed:", err);
|
|
1717
1730
|
return void 0;
|
|
1718
1731
|
}
|
|
1719
1732
|
}, [zone, data]);
|
|
1720
1733
|
if (!entityType) {
|
|
1721
|
-
if (process.env.NODE_ENV !== "production") {
|
|
1722
|
-
console.warn("[UniversalMetadataWidget] Could not resolve entity type.", {
|
|
1723
|
-
zone,
|
|
1724
|
-
dataKeys: data ? Object.keys(data) : []
|
|
1725
|
-
});
|
|
1726
|
-
}
|
|
1727
1734
|
return null;
|
|
1728
1735
|
}
|
|
1729
1736
|
return /* @__PURE__ */ jsx(
|
|
@@ -1740,9 +1747,6 @@ const MetadataWidgetLoader = ({ data, entityType, queryKey }) => {
|
|
|
1740
1747
|
entity: entityType,
|
|
1741
1748
|
enabled: true
|
|
1742
1749
|
});
|
|
1743
|
-
if (process.env.NODE_ENV !== "production") {
|
|
1744
|
-
console.debug("[UniversalMetadataWidget]", { entityType, descriptors: descriptors.length, isPending, queryKey });
|
|
1745
|
-
}
|
|
1746
1750
|
if (!isPending && descriptors.length === 0) {
|
|
1747
1751
|
return null;
|
|
1748
1752
|
}
|
|
@@ -14,6 +14,13 @@ const OPTION_TYPES = new Set([
|
|
|
14
14
|
"radio",
|
|
15
15
|
"checkbox",
|
|
16
16
|
]);
|
|
17
|
+
/** Cleared text inputs coerce to `""` so the key is still sent in the update payload. */
|
|
18
|
+
const COERCE_EMPTY_STRING_FOR_TYPES = new Set([
|
|
19
|
+
"text",
|
|
20
|
+
"textarea",
|
|
21
|
+
"richtext",
|
|
22
|
+
"markdown",
|
|
23
|
+
]);
|
|
17
24
|
const BOOLEAN_TRUES = new Set(["true", "1", "yes", "y", "on"]);
|
|
18
25
|
const BOOLEAN_FALSES = new Set(["false", "0", "no", "n", "off"]);
|
|
19
26
|
const EMAIL_REGEX = /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/;
|
|
@@ -83,9 +90,10 @@ function buildInitialFormState(descriptors, metadata) {
|
|
|
83
90
|
: {};
|
|
84
91
|
return descriptors.reduce((acc, descriptor) => {
|
|
85
92
|
const currentValue = base[descriptor.key];
|
|
93
|
+
const emptyStringCountsAsValue = COERCE_EMPTY_STRING_FOR_TYPES.has(descriptor.type);
|
|
86
94
|
const hasValue = currentValue !== undefined &&
|
|
87
95
|
currentValue !== null &&
|
|
88
|
-
currentValue !== "";
|
|
96
|
+
(currentValue !== "" || emptyStringCountsAsValue);
|
|
89
97
|
const valueToUse = hasValue
|
|
90
98
|
? currentValue
|
|
91
99
|
: descriptor.default_value;
|
|
@@ -93,20 +101,21 @@ function buildInitialFormState(descriptors, metadata) {
|
|
|
93
101
|
return acc;
|
|
94
102
|
}, {});
|
|
95
103
|
}
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
104
|
+
/**
|
|
105
|
+
* Builds metadata to send on entity update. Only keys listed in `descriptors`
|
|
106
|
+
* are included. Cleared text/textarea/rich/markdown fields are sent as `""`;
|
|
107
|
+
* other cleared types omit the key. Keys not in the plugin configuration are
|
|
108
|
+
* not carried over from the entity.
|
|
109
|
+
*/
|
|
110
|
+
function buildMetadataPayload({ descriptors, values, originalMetadata: _originalMetadata, }) {
|
|
111
|
+
const result = {};
|
|
100
112
|
descriptors.forEach((descriptor) => {
|
|
101
113
|
const coerced = coerceMetadataValue(descriptor, values[descriptor.key]);
|
|
102
|
-
if (coerced
|
|
103
|
-
|
|
104
|
-
}
|
|
105
|
-
else {
|
|
106
|
-
base[descriptor.key] = coerced;
|
|
114
|
+
if (coerced !== undefined) {
|
|
115
|
+
result[descriptor.key] = coerced;
|
|
107
116
|
}
|
|
108
117
|
});
|
|
109
|
-
return
|
|
118
|
+
return result;
|
|
110
119
|
}
|
|
111
120
|
function hasMetadataChanges({ descriptors, values, originalMetadata, }) {
|
|
112
121
|
const next = buildMetadataPayload({ descriptors, values, originalMetadata });
|
|
@@ -321,8 +330,9 @@ function normalizeFormValue(descriptor, currentValue) {
|
|
|
321
330
|
return "";
|
|
322
331
|
}
|
|
323
332
|
function coerceMetadataValue(descriptor, value) {
|
|
324
|
-
if (value == null
|
|
325
|
-
return undefined;
|
|
333
|
+
if (value == null) {
|
|
334
|
+
return COERCE_EMPTY_STRING_FOR_TYPES.has(descriptor.type) ? "" : undefined;
|
|
335
|
+
}
|
|
326
336
|
if (descriptor.type === "bool") {
|
|
327
337
|
if (typeof value === "boolean")
|
|
328
338
|
return value;
|
|
@@ -340,7 +350,10 @@ function coerceMetadataValue(descriptor, value) {
|
|
|
340
350
|
if (descriptor.type === "number" ||
|
|
341
351
|
descriptor.type === "integer" ||
|
|
342
352
|
descriptor.type === "float") {
|
|
343
|
-
const
|
|
353
|
+
const raw = typeof value === "number" ? String(value) : String(value).trim();
|
|
354
|
+
if (raw === "")
|
|
355
|
+
return undefined;
|
|
356
|
+
const num = Number(raw);
|
|
344
357
|
return isNaN(num) ? undefined : descriptor.type === "integer" ? Math.floor(num) : num;
|
|
345
358
|
}
|
|
346
359
|
if (descriptor.type === "multiselect" || descriptor.type === "checkbox") {
|
|
@@ -368,9 +381,11 @@ function coerceMetadataValue(descriptor, value) {
|
|
|
368
381
|
return undefined;
|
|
369
382
|
}
|
|
370
383
|
}
|
|
371
|
-
const
|
|
372
|
-
|
|
373
|
-
|
|
384
|
+
const str = String(value);
|
|
385
|
+
const trimmed = str.trim();
|
|
386
|
+
if (!trimmed) {
|
|
387
|
+
return COERCE_EMPTY_STRING_FOR_TYPES.has(descriptor.type) ? "" : undefined;
|
|
388
|
+
}
|
|
374
389
|
return trimmed;
|
|
375
390
|
}
|
|
376
391
|
function normalizeKey(value) {
|
|
@@ -430,4 +445,4 @@ function isDeepEqual(a, b) {
|
|
|
430
445
|
return false;
|
|
431
446
|
return aKeys.every((key) => isDeepEqual(a[key], b[key]));
|
|
432
447
|
}
|
|
433
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9zcmMvc2hhcmVkL21ldGFkYXRhL3V0aWxzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBb0NBLG9FQWtEQztBQUVELDRDQU9DO0FBRUQsc0RBd0JDO0FBRUQsb0RBeUJDO0FBRUQsZ0RBZ0JDO0FBaUJELGdFQW1KQztBQTFVRCxtQ0FNZ0I7QUFhaEIsTUFBTSxpQkFBaUIsR0FBRyxJQUFJLEdBQUcsQ0FBb0IsNEJBQW9CLENBQUMsQ0FBQTtBQUMxRSxNQUFNLFlBQVksR0FBRyxJQUFJLEdBQUcsQ0FBb0I7SUFDOUMsUUFBUTtJQUNSLGFBQWE7SUFDYixPQUFPO0lBQ1AsVUFBVTtDQUNYLENBQUMsQ0FBQTtBQUNGLE1BQU0sYUFBYSxHQUFHLElBQUksR0FBRyxDQUFDLENBQUMsTUFBTSxFQUFFLEdBQUcsRUFBRSxLQUFLLEVBQUUsR0FBRyxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUE7QUFDOUQsTUFBTSxjQUFjLEdBQUcsSUFBSSxHQUFHLENBQUMsQ0FBQyxPQUFPLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBRSxHQUFHLEVBQUUsS0FBSyxDQUFDLENBQUMsQ0FBQTtBQUVoRSxNQUFNLFdBQVcsR0FDZixzSUFBc0ksQ0FBQTtBQUN4SSxNQUFNLFdBQVcsR0FBRyx1QkFBdUIsQ0FBQTtBQUMzQyxNQUFNLGVBQWUsR0FBRyxvQ0FBb0MsQ0FBQTtBQUM1RCxNQUFNLGVBQWUsR0FDbkIsZ0dBQWdHLENBQUE7QUFFbEcsU0FBZ0IsNEJBQTRCLENBQUMsS0FBYztJQUN6RCxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUM7UUFBRSxPQUFPLEVBQUUsQ0FBQTtJQUVwQyxNQUFNLFFBQVEsR0FBRyxJQUFJLEdBQUcsRUFBVSxDQUFBO0lBQ2xDLE9BQU8sS0FBSztTQUNULE1BQU0sQ0FBQyxDQUFDLElBQUksRUFBbUMsRUFBRSxDQUNoRCxJQUFJLElB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Q0FBQyxJQUFJLEtBQUssUUFBUSxJQUFJLFVBQVUsQ0FBQyxPQUFPLEVBQUUsTUFBTSxFQUFFLENBQUM7UUFDL0QsSUFBSSxLQUFLLElBQUksSUFBSSxJQUFJLEtBQUssS0FBSyxFQUFFO1lBQUUsT0FBTyxVQUFVLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyx3QkFBd0IsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFBO1FBQ3BHLE1BQU0sR0FBRyxHQUFHLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxJQUFJLEVBQUUsQ0FBQTtRQUNoQyxNQUFNLE9BQU8sR0FBRyxJQUFJLEdBQUcsQ0FBQyxVQUFVLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUE7UUFDL0QsT0FBTyxPQUFPLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLG1DQUFtQyxDQUFBO0lBQzNFLENBQUM7SUFFRCxJQUFJLFVBQVUsQ0FBQyxJQUFJLEtBQUssYUFBYSxJQUFJLFVBQVUsQ0FBQyxPQUFPLEVBQUUsTUFBTSxFQUFFLENBQUM7UUFDcEUsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDO1lBQUUsT0FBTyxlQUFlLENBQUE7UUFDakQsTUFBTSxPQUFPLEdBQUcsSUFBSSxHQUFHLENBQUMsVUFBVSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFBO1FBQy9ELE1BQU0sT0FBTyxHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFBO1FBQzFELE9BQU8sT0FBTyxDQUFDLENBQUMsQ0FBQyxpREFBaUQsQ0FBQyxDQUFDLENBQUMs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
|
|
448
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9zcmMvc2hhcmVkL21ldGFkYXRhL3V0aWxzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBNENBLG9FQWtEQztBQUVELDRDQU9DO0FBRUQsc0RBMkJDO0FBUUQsb0RBb0JDO0FBRUQsZ0RBZ0JDO0FBaUJELGdFQW1KQztBQXRWRCxtQ0FNZ0I7QUFhaEIsTUFBTSxpQkFBaUIsR0FBRyxJQUFJLEdBQUcsQ0FBb0IsNEJBQW9CLENBQUMsQ0FBQTtBQUMxRSxNQUFNLFlBQVksR0FBRyxJQUFJLEdBQUcsQ0FBb0I7SUFDOUMsUUFBUTtJQUNSLGFBQWE7SUFDYixPQUFPO0lBQ1AsVUFBVTtDQUNYLENBQUMsQ0FBQTtBQUVGLHlGQUF5RjtBQUN6RixNQUFNLDZCQUE2QixHQUFHLElBQUksR0FBRyxDQUFvQjtJQUMvRCxNQUFNO0lBQ04sVUFBVTtJQUNWLFVBQVU7SUFDVixVQUFVO0NBQ1gsQ0FBQyxDQUFBO0FBQ0YsTUFBTSxhQUFhLEdBQUcsSUFBSSxHQUFHLENBQUMsQ0FBQyxNQUFNLEVBQUUsR0FBRyxFQUFFLEtBQUssRUFBRSxHQUFHLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQTtBQUM5RCxNQUFNLGNBQWMsR0FBRyxJQUFJLEdBQUcsQ0FBQyxDQUFDLE9BQU8sRUFBRSxHQUFHLEVBQUUsSUFBSSxFQUFFLEdBQUcsRUFBRSxLQUFLLENBQUMsQ0FBQyxDQUFBO0FBRWhFLE1BQU0sV0FBVyxHQUNmLHNJQUFzSSxDQUFBO0FBQ3hJLE1BQU0sV0FBVyxHQUFHLHVCQUF1QixDQUFBO0FBQzNDLE1BQU0sZUFBZSxHQUFHLG9DQUFvQyxDQUFBO0FBQzVELE1BQU0sZUFBZSxHQUNuQixnR0FBZ0csQ0FBQTtBQUVsRyxTQUFnQiw0QkFBNEIsQ0FBQyxLQUFjO0lBQ3pELElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQztRQUFFLE9BQU8sRUFBRSxDQUFB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
|
package/README.md
CHANGED
|
@@ -1,92 +1,45 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
<a href="https://twitter.com/intent/follow?screen_name=medusajs">
|
|
31
|
-
<img src="https://img.shields.io/twitter/follow/medusajs.svg?label=Follow%20@medusajs" alt="Follow @medusajs" />
|
|
32
|
-
</a>
|
|
33
|
-
</p>
|
|
34
|
-
|
|
35
|
-
## Compatibility
|
|
36
|
-
|
|
37
|
-
This plugin is compatible with versions >= 2.4.0 of `@medusajs/medusa`.
|
|
38
|
-
|
|
39
|
-
## Overview
|
|
40
|
-
|
|
41
|
-
`medusa-dynamic-metadata` is a flexible, configuration-driven plugin that enables metadata management for any Medusa entity type. Simply configure entities in your `medusa-config.ts` file, and the plugin provides a universal widget component that automatically detects entity types and renders the appropriate metadata fields.
|
|
42
|
-
|
|
43
|
-
### Key Features
|
|
44
|
-
|
|
45
|
-
- **Configuration-Driven**: Enable metadata for any entity type through simple configuration
|
|
46
|
-
- **Universal Widget**: Single widget component works for all entities with runtime entity detection
|
|
47
|
-
- **Type-Safe**: Full TypeScript support with proper type definitions
|
|
48
|
-
- **Enterprise Field Types**: 27+ field types including text, textarea, richtext, markdown, number, integer, float, bool, date/time/datetime, select/multiselect/radio/checkbox, image/video/audio/file, url/email/phone, color, json/object/array, relation
|
|
49
|
-
- **Schema Validation**: Support for `required`, `default_value`, and `validation` (min, max, regex) per field
|
|
50
|
-
- **Zero Code Changes**: Add metadata to new entities by updating configuration only
|
|
51
|
-
|
|
52
|
-
## Supported Entities
|
|
53
|
-
|
|
54
|
-
This plugin supports metadata configuration for the following entities that have valid admin detail pages:
|
|
55
|
-
|
|
56
|
-
1. **products** - Widget zone: `product.details.after`
|
|
57
|
-
2. **orders** - Widget zone: `order.details.after`
|
|
58
|
-
3. **categories** - Widget zone: `product_category.details.after`
|
|
59
|
-
4. **collections** - Widget zone: `product_collection.details.after`
|
|
60
|
-
5. **customers** - Widget zone: `customer.details.after`
|
|
61
|
-
6. **regions** - Widget zone: `region.details.after`
|
|
62
|
-
7. **sales_channels** - Widget zone: `sales_channel.details.after`
|
|
63
|
-
8. **stores** - Widget zone: `store.details.after`
|
|
64
|
-
9. **promotions** - Widget zone: `promotion.details.after`
|
|
65
|
-
10. **campaigns** - Widget zone: `campaign.details.after`
|
|
66
|
-
11. **price_lists** - Widget zone: `price_list.details.after`
|
|
67
|
-
12. **shipping_profiles** - Widget zone: `shipping_profile.details.after`
|
|
68
|
-
13. **inventory_items** - Widget zone: `inventory_item.details.after`
|
|
69
|
-
14. **product_variants** - Widget zone: `product_variant.details.after`
|
|
70
|
-
|
|
71
|
-
> **Note**: Only entities with valid admin detail pages can be configured. The plugin includes pre-built widget files for all 14 supported entities above.
|
|
72
|
-
|
|
73
|
-
## Getting Started
|
|
74
|
-
|
|
75
|
-
### Installation
|
|
1
|
+
# medusa-dynamic-metadata
|
|
2
|
+
> Configuration-driven Medusa v2 plugin for rendering and persisting dynamic metadata fields across admin entity detail pages.
|
|
3
|
+
|
|
4
|
+
## Plugin Overview
|
|
5
|
+
|
|
6
|
+
`medusa-dynamic-metadata` lets you define metadata descriptors per entity in plugin options, then automatically renders a typed metadata editor in Medusa Admin widgets for those entity detail pages.
|
|
7
|
+
|
|
8
|
+
### What It Does
|
|
9
|
+
|
|
10
|
+
- Resolves metadata configuration from `medusa-config.ts` (`entities` map).
|
|
11
|
+
- Detects entity type in admin widgets (zone first, data-shape fallback).
|
|
12
|
+
- Renders a universal metadata form supporting 27 field types (`text`, `number`, `select`, `json`, `relation`, media URL/file upload, etc.).
|
|
13
|
+
- Validates descriptor-driven constraints (`required`, `validation.min/max/regex`, options validation).
|
|
14
|
+
- Saves metadata to entity-specific admin APIs (or custom endpoint override).
|
|
15
|
+
- Provides admin API for retrieving resolved descriptors by entity.
|
|
16
|
+
|
|
17
|
+
### Problem It Solves
|
|
18
|
+
|
|
19
|
+
It removes the need to hand-build custom metadata UI and persistence logic per entity. Teams can add/modify metadata fields through plugin configuration instead of repeated frontend/backend boilerplate.
|
|
20
|
+
|
|
21
|
+
### Medusa Version
|
|
22
|
+
|
|
23
|
+
Built for **Medusa v2** (`@medusajs/framework` / `@medusajs/medusa` `2.12.3`).
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## Installation & Setup
|
|
28
|
+
|
|
29
|
+
### Install
|
|
76
30
|
|
|
77
31
|
```bash
|
|
78
32
|
npm install medusa-dynamic-metadata
|
|
33
|
+
# or
|
|
34
|
+
yarn add medusa-dynamic-metadata
|
|
79
35
|
```
|
|
80
36
|
|
|
81
|
-
###
|
|
82
|
-
|
|
83
|
-
Add the plugin to your `medusa-config.ts`:
|
|
37
|
+
### Register in `medusa-config.ts`
|
|
84
38
|
|
|
85
|
-
```
|
|
39
|
+
```ts
|
|
86
40
|
import { defineConfig } from "@medusajs/framework"
|
|
87
41
|
|
|
88
42
|
export default defineConfig({
|
|
89
|
-
// ... other config
|
|
90
43
|
plugins: [
|
|
91
44
|
{
|
|
92
45
|
resolve: "medusa-dynamic-metadata",
|
|
@@ -96,23 +49,6 @@ export default defineConfig({
|
|
|
96
49
|
descriptors: [
|
|
97
50
|
{ key: "brand", label: "Brand", type: "text", filterable: true },
|
|
98
51
|
{ key: "warranty_years", label: "Warranty (Years)", type: "number" },
|
|
99
|
-
{
|
|
100
|
-
key: "status",
|
|
101
|
-
label: "Status",
|
|
102
|
-
type: "select",
|
|
103
|
-
options: [
|
|
104
|
-
{ value: "draft", label: "Draft" },
|
|
105
|
-
{ value: "active", label: "Active" },
|
|
106
|
-
{ value: "archived", label: "Archived" },
|
|
107
|
-
],
|
|
108
|
-
},
|
|
109
|
-
],
|
|
110
|
-
expose_client_helpers: true,
|
|
111
|
-
filterable: true,
|
|
112
|
-
},
|
|
113
|
-
orders: {
|
|
114
|
-
descriptors: [
|
|
115
|
-
{ key: "source", label: "Source", type: "text" },
|
|
116
52
|
],
|
|
117
53
|
},
|
|
118
54
|
},
|
|
@@ -122,262 +58,309 @@ export default defineConfig({
|
|
|
122
58
|
})
|
|
123
59
|
```
|
|
124
60
|
|
|
125
|
-
###
|
|
61
|
+
### Database Migrations
|
|
126
62
|
|
|
127
|
-
|
|
63
|
+
No custom module/entity migrations are present in this plugin source. It uses existing Medusa entity metadata columns and admin endpoints.
|
|
128
64
|
|
|
129
|
-
|
|
130
|
-
2. Delegates to the universal `UniversalMetadataWidget` component
|
|
131
|
-
3. Automatically detects the entity type at runtime
|
|
65
|
+
---
|
|
132
66
|
|
|
133
|
-
|
|
67
|
+
## Configuration (`config.ts` / plugin options)
|
|
134
68
|
|
|
135
|
-
|
|
69
|
+
Defined in `src/config/metadata-options.ts`.
|
|
136
70
|
|
|
137
|
-
###
|
|
71
|
+
### Root Options
|
|
138
72
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
73
|
+
| Option | Type | Required | Default | Description |
|
|
74
|
+
|---|---|---|---|---|
|
|
75
|
+
| `entities` | `Record<string, EntityMetadataConfig>` | Optional | `{}` | Per-entity metadata configuration keyed by entity type (for example `products`, `orders`). |
|
|
142
76
|
|
|
143
|
-
|
|
77
|
+
### Entity Metadata Config
|
|
144
78
|
|
|
145
|
-
|
|
79
|
+
| Option | Type | Required | Default | Description |
|
|
80
|
+
|---|---|---|---|---|
|
|
81
|
+
| `descriptors` | `MetadataDescriptor[]` | Optional | `[]` | Field definitions to render and persist. |
|
|
82
|
+
| `expose_client_helpers` | `boolean` | Optional | `false` | Flag stored in normalized config (helper exposure toggle). |
|
|
83
|
+
| `filterable` | `boolean` | Optional | `false` | Entity-level filterability flag in config. |
|
|
84
|
+
| `widget_zone` | `string` | Optional | Auto-resolved from entity mapping or `{singular}.details.after` | Admin widget zone override. |
|
|
85
|
+
| `api_endpoint` | `string` | Optional | Derived from entity registry | Admin update endpoint override for saving metadata. |
|
|
146
86
|
|
|
147
|
-
|
|
148
|
-
npm run dev
|
|
149
|
-
```
|
|
87
|
+
### Metadata Descriptor Fields
|
|
150
88
|
|
|
151
|
-
|
|
89
|
+
| Field | Type | Required | Default | Description |
|
|
90
|
+
|---|---|---|---|---|
|
|
91
|
+
| `key` | `string` | Yes | - | Metadata key on entity. |
|
|
92
|
+
| `type` | `MetadataFieldType` | Yes | - | Input type and coercion/validation behavior. |
|
|
93
|
+
| `label` | `string` | Optional | `key` | Display label. |
|
|
94
|
+
| `filterable` | `boolean` | Optional | `false` | Per-field filterable marker. |
|
|
95
|
+
| `required` | `boolean` | Optional | `false` | Required validation. |
|
|
96
|
+
| `default_value` | `unknown` | Optional | `undefined` | Default form value when metadata is missing. |
|
|
97
|
+
| `validation` | `{ min?: number; max?: number; regex?: string }` | Optional | `undefined` | Numeric/regex constraints. |
|
|
98
|
+
| `options` | `{ value: string; label?: string }[]` | Optional | `undefined` | Used for `select`, `multiselect`, `radio`, `checkbox`. |
|
|
152
99
|
|
|
153
|
-
|
|
100
|
+
### Supported `MetadataFieldType` Values
|
|
154
101
|
|
|
155
|
-
|
|
102
|
+
`text`, `textarea`, `richtext`, `markdown`, `number`, `integer`, `float`, `bool`, `date`, `time`, `datetime`, `select`, `multiselect`, `radio`, `checkbox`, `image`, `video`, `audio`, `file`, `url`, `email`, `phone`, `color`, `json`, `object`, `array`, `relation`
|
|
156
103
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
104
|
+
### Complete Example Config
|
|
105
|
+
|
|
106
|
+
```ts
|
|
107
|
+
{
|
|
108
|
+
resolve: "medusa-dynamic-metadata",
|
|
109
|
+
options: {
|
|
110
|
+
entities: {
|
|
111
|
+
products: {
|
|
112
|
+
descriptors: [
|
|
113
|
+
{ key: "brand", label: "Brand", type: "text", filterable: true, required: true },
|
|
114
|
+
{ key: "warranty_years", label: "Warranty (Years)", type: "integer", validation: { min: 0, max: 20 } },
|
|
115
|
+
{
|
|
116
|
+
key: "status",
|
|
117
|
+
label: "Status",
|
|
118
|
+
type: "select",
|
|
119
|
+
options: [
|
|
120
|
+
{ value: "draft", label: "Draft" },
|
|
121
|
+
{ value: "active", label: "Active" },
|
|
122
|
+
],
|
|
123
|
+
},
|
|
124
|
+
{ key: "care_guide", label: "Care Guide", type: "file" },
|
|
125
|
+
{ key: "specs", label: "Specs", type: "json" },
|
|
126
|
+
],
|
|
127
|
+
expose_client_helpers: false,
|
|
128
|
+
filterable: true,
|
|
129
|
+
widget_zone: "product.details.after",
|
|
130
|
+
api_endpoint: "/admin/products/{id}",
|
|
131
|
+
},
|
|
132
|
+
orders: {
|
|
133
|
+
descriptors: [
|
|
134
|
+
{ key: "source", label: "Source", type: "text" },
|
|
135
|
+
{ key: "priority", label: "Priority", type: "radio", options: [{ value: "normal" }, { value: "high" }] },
|
|
136
|
+
],
|
|
137
|
+
},
|
|
138
|
+
},
|
|
139
|
+
},
|
|
140
|
+
}
|
|
169
141
|
```
|
|
170
142
|
|
|
171
|
-
|
|
143
|
+
---
|
|
172
144
|
|
|
173
|
-
|
|
145
|
+
## Environment Variables
|
|
174
146
|
|
|
175
|
-
|
|
176
|
-
- **Zone-based detection** (primary): Resolves entity type from the widget zone (e.g., `"product.details.after"` → `"products"`)
|
|
177
|
-
- **Data structure detection** (fallback): Pattern matching on data properties (e.g., `handle`, `title` → products; `display_id`, `status` → orders)
|
|
147
|
+
Environment variable usage found in plugin source:
|
|
178
148
|
|
|
179
|
-
|
|
149
|
+
| Variable | Where | Purpose | Required | Example |
|
|
150
|
+
|---|---|---|---|---|
|
|
151
|
+
| `NODE_ENV` | `src/admin/components/universal-metadata-widget.tsx` | Enables/disables debug/warn logs in non-production mode. | Optional | `production` |
|
|
180
152
|
|
|
181
|
-
|
|
153
|
+
> ⚠️ Note: `src/modules/README.md` contains example text referencing `process.env.API_KEY`, but it is documentation content, not runtime plugin code.
|
|
182
154
|
|
|
183
|
-
|
|
155
|
+
---
|
|
184
156
|
|
|
185
|
-
|
|
157
|
+
## REST APIs / Routes
|
|
186
158
|
|
|
187
|
-
|
|
188
|
-
- Specify the widget zone (required by Medusa)
|
|
189
|
-
- Pass the zone to `UniversalMetadataWidget`
|
|
190
|
-
- Let the universal component handle all entity-specific logic
|
|
159
|
+
### 1) `GET /admin/metadata-config`
|
|
191
160
|
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
161
|
+
- **Auth:** Admin (admin route namespace)
|
|
162
|
+
- **Query params:**
|
|
163
|
+
- `entity` (`string`, optional, default: `"products"`)
|
|
164
|
+
- **Response:**
|
|
165
|
+
```json
|
|
166
|
+
{
|
|
167
|
+
"metadataDescriptors": [
|
|
168
|
+
{
|
|
169
|
+
"key": "brand",
|
|
170
|
+
"type": "text",
|
|
171
|
+
"label": "Brand"
|
|
172
|
+
}
|
|
173
|
+
]
|
|
174
|
+
}
|
|
175
|
+
```
|
|
176
|
+
- **Behavior:**
|
|
177
|
+
- Reads plugin config with `resolveDynamicMetadataOptions`.
|
|
178
|
+
- Returns empty descriptor array when entity is not configured (no 404).
|
|
179
|
+
|
|
180
|
+
### 2) `POST /admin/product-variants/:id`
|
|
181
|
+
|
|
182
|
+
- **Auth:** Admin (admin route namespace)
|
|
183
|
+
- **Path params:**
|
|
184
|
+
- `id` (`string`, required): product variant ID.
|
|
185
|
+
- **Body:** passthrough payload with optional `metadata` object plus other variant update fields.
|
|
186
|
+
- **Response:**
|
|
187
|
+
```json
|
|
188
|
+
{
|
|
189
|
+
"product_variant": {
|
|
190
|
+
"id": "variant_...",
|
|
191
|
+
"metadata": {}
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
```
|
|
195
|
+
- **Behavior:**
|
|
196
|
+
- Executes `updateProductVariantsWorkflow` with selector by ID and update payload.
|
|
197
|
+
- Returns first updated variant as `product_variant`.
|
|
197
198
|
|
|
198
|
-
|
|
199
|
-
|
|
199
|
+
### Important Endpoint Examples
|
|
200
|
+
|
|
201
|
+
```bash
|
|
202
|
+
# Get metadata descriptors for products
|
|
203
|
+
curl -X GET "http://localhost:9000/admin/metadata-config?entity=products" \
|
|
204
|
+
-H "Authorization: Bearer <admin_token>"
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
```bash
|
|
208
|
+
# Update metadata on a product variant
|
|
209
|
+
curl -X POST "http://localhost:9000/admin/product-variants/variant_123" \
|
|
210
|
+
-H "Authorization: Bearer <admin_token>" \
|
|
211
|
+
-H "Content-Type: application/json" \
|
|
212
|
+
-d '{
|
|
213
|
+
"metadata": {
|
|
214
|
+
"fabric": "cotton",
|
|
215
|
+
"is_limited": true
|
|
216
|
+
}
|
|
217
|
+
}'
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
```ts
|
|
221
|
+
// fetch example for metadata config
|
|
222
|
+
const res = await fetch("/admin/metadata-config?entity=orders", {
|
|
223
|
+
credentials: "include",
|
|
200
224
|
})
|
|
225
|
+
const data = await res.json()
|
|
201
226
|
```
|
|
202
227
|
|
|
203
|
-
|
|
228
|
+
---
|
|
204
229
|
|
|
205
|
-
|
|
230
|
+
## Services
|
|
206
231
|
|
|
207
|
-
|
|
208
|
-
```typescript
|
|
209
|
-
entities: {
|
|
210
|
-
customers: {
|
|
211
|
-
descriptors: [
|
|
212
|
-
{ key: "preferred_language", type: "text" }
|
|
213
|
-
]
|
|
214
|
-
}
|
|
215
|
-
}
|
|
216
|
-
```
|
|
232
|
+
No custom backend service classes are defined in this plugin source.
|
|
217
233
|
|
|
218
|
-
|
|
219
|
-
- Copy `src/admin/widget-templates/generic-metadata-widget.template.tsx` into `src/admin/widgets/`
|
|
220
|
-
- Update the zone to match your entity's admin zone
|
|
221
|
-
- The universal widget will automatically detect the entity type
|
|
222
|
-
|
|
223
|
-
## Configuration Options
|
|
224
|
-
|
|
225
|
-
### Entity Configuration
|
|
226
|
-
|
|
227
|
-
Each entity in the configuration supports:
|
|
228
|
-
|
|
229
|
-
- `descriptors`: Array of metadata field definitions
|
|
230
|
-
- `key`: Unique identifier for the field
|
|
231
|
-
- `label`: Display label (optional, defaults to key)
|
|
232
|
-
- `type`: Field type (see [Field Type Reference](#field-type-reference) below)
|
|
233
|
-
- `required`: Whether the field must have a value (default: `false`)
|
|
234
|
-
- `default_value`: Default value when no value is set (optional)
|
|
235
|
-
- `validation`: Validation rules — `{ min?: number, max?: number, regex?: string }` (optional)
|
|
236
|
-
- `options`: For `select`, `multiselect`, `radio`, `checkbox` — array of `{ value: string, label?: string }`
|
|
237
|
-
- `filterable`: Whether the field can be used for filtering (default: `false`)
|
|
238
|
-
- `expose_client_helpers`: Expose client-side helper functions (default: `false`)
|
|
239
|
-
- `filterable`: Enable filtering for this entity (default: `false`)
|
|
240
|
-
- `widget_zone`: Custom widget zone override (optional)
|
|
241
|
-
- `api_endpoint`: Custom API endpoint override (optional)
|
|
242
|
-
|
|
243
|
-
### Field Type Reference
|
|
244
|
-
|
|
245
|
-
| Type | Use Case | Options/Validation |
|
|
246
|
-
|------|-----------|-------------------|
|
|
247
|
-
| `text` | Short single-line text | — |
|
|
248
|
-
| `textarea` | Multi-line text (product description) | — |
|
|
249
|
-
| `richtext` | Formatted content (HTML) | — |
|
|
250
|
-
| `markdown` | Markdown content | — |
|
|
251
|
-
| `number` | Decimal numbers | min, max, regex |
|
|
252
|
-
| `integer` | Whole numbers | min, max, regex |
|
|
253
|
-
| `float` | Decimal numbers | min, max, regex |
|
|
254
|
-
| `bool` | Boolean toggle | — |
|
|
255
|
-
| `date` | Date only (sale start) | — |
|
|
256
|
-
| `time` | Time only | — |
|
|
257
|
-
| `datetime` | Date and time (scheduled publish) | — |
|
|
258
|
-
| `select` | Single option dropdown | options required |
|
|
259
|
-
| `multiselect` | Multiple options (tags) | options required |
|
|
260
|
-
| `radio` | Single choice (UX alternative to select) | options required |
|
|
261
|
-
| `checkbox` | Multiple checkboxes | options required |
|
|
262
|
-
| `image` | Image URL (product badge) | — |
|
|
263
|
-
| `video` | Video URL (demo video) | — |
|
|
264
|
-
| `audio` | Audio URL | — |
|
|
265
|
-
| `file` | Generic file URL | — |
|
|
266
|
-
| `url` | Valid URL | — |
|
|
267
|
-
| `email` | Email address | — |
|
|
268
|
-
| `phone` | Phone number | — |
|
|
269
|
-
| `color` | Color (hex or rgb) | — |
|
|
270
|
-
| `json` | Arbitrary JSON | — |
|
|
271
|
-
| `object` | JSON object | — |
|
|
272
|
-
| `array` | JSON array | — |
|
|
273
|
-
| `relation` | Entity ID reference | — |
|
|
274
|
-
|
|
275
|
-
## API
|
|
276
|
-
|
|
277
|
-
The plugin provides admin API endpoints for metadata management:
|
|
278
|
-
|
|
279
|
-
- `GET /admin/metadata-config?entity={entityType}` - Get metadata descriptors for an entity
|
|
280
|
-
- Metadata is managed through the standard Medusa entity APIs with metadata fields
|
|
281
|
-
|
|
282
|
-
## Examples
|
|
283
|
-
|
|
284
|
-
### Basic Configuration
|
|
285
|
-
|
|
286
|
-
```typescript
|
|
287
|
-
{
|
|
288
|
-
entities: {
|
|
289
|
-
products: {
|
|
290
|
-
descriptors: [
|
|
291
|
-
{ key: "brand", type: "text", filterable: true },
|
|
292
|
-
{ key: "warranty_years", type: "number" },
|
|
293
|
-
],
|
|
294
|
-
},
|
|
295
|
-
},
|
|
296
|
-
}
|
|
297
|
-
```
|
|
234
|
+
> ⚠️ Note: Most logic is implemented as configuration utilities (`src/config/*`) and shared metadata helpers (`src/shared/metadata/utils.ts`) consumed by admin UI.
|
|
298
235
|
|
|
299
|
-
|
|
236
|
+
---
|
|
300
237
|
|
|
301
|
-
|
|
302
|
-
{
|
|
303
|
-
entities: {
|
|
304
|
-
products: {
|
|
305
|
-
descriptors: [
|
|
306
|
-
{ key: "brand", label: "Brand Name", type: "text", filterable: true },
|
|
307
|
-
{ key: "warranty_years", label: "Warranty Period", type: "number" },
|
|
308
|
-
{ key: "has_warranty", label: "Has Warranty", type: "bool" },
|
|
309
|
-
{ key: "manual_pdf", label: "Manual PDF", type: "file" },
|
|
310
|
-
],
|
|
311
|
-
expose_client_helpers: true,
|
|
312
|
-
filterable: true,
|
|
313
|
-
widget_zone: "product.details.after", // Optional override
|
|
314
|
-
},
|
|
315
|
-
},
|
|
316
|
-
}
|
|
317
|
-
```
|
|
238
|
+
## Workflows & Steps (Medusa v2)
|
|
318
239
|
|
|
319
|
-
|
|
240
|
+
No custom workflows or steps are defined in this plugin source.
|
|
320
241
|
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
242
|
+
The plugin calls Medusa core workflow `updateProductVariantsWorkflow` in `POST /admin/product-variants/:id`.
|
|
243
|
+
|
|
244
|
+
---
|
|
245
|
+
|
|
246
|
+
## Subscribers / Event Hooks
|
|
247
|
+
|
|
248
|
+
No runtime subscribers/event handlers are defined in this plugin source (only template/readme scaffolding under `src/subscribers`).
|
|
249
|
+
|
|
250
|
+
---
|
|
251
|
+
|
|
252
|
+
## Admin UI / Widgets
|
|
253
|
+
|
|
254
|
+
### Universal Components
|
|
255
|
+
|
|
256
|
+
- **`UniversalMetadataWidget` (`src/admin/components/universal-metadata-widget.tsx`)**
|
|
257
|
+
- Detects entity type from widget zone; falls back to data-shape signals.
|
|
258
|
+
- Loads descriptors via `useMetadataConfig`.
|
|
259
|
+
- Renders `MetadataTableWidget` only when descriptors exist.
|
|
260
|
+
|
|
261
|
+
- **`MetadataTableWidget` (`src/admin/components/metadata-table.tsx`)**
|
|
262
|
+
- Renders typed controls per descriptor.
|
|
263
|
+
- Performs descriptor-based validation.
|
|
264
|
+
- Uploads media/file fields through `POST /admin/uploads` and stores URL in metadata value.
|
|
265
|
+
- Saves metadata by resolving entity endpoint (`resolveApiEndpoint`) and calling `POST`.
|
|
266
|
+
- Invalidates/refetches React Query cache using resolved query keys.
|
|
267
|
+
|
|
268
|
+
### Registered Metadata Widgets (wrappers)
|
|
269
|
+
|
|
270
|
+
Each file is a minimal wrapper around `UniversalMetadataWidget` with a fixed zone:
|
|
271
|
+
|
|
272
|
+
| Entity | Zone |
|
|
273
|
+
|---|---|
|
|
274
|
+
| `products` | `product.details.after` |
|
|
275
|
+
| `orders` | `order.details.after` |
|
|
276
|
+
| `categories` | `product_category.details.after` |
|
|
277
|
+
| `collections` | `product_collection.details.after` |
|
|
278
|
+
| `customers` | `customer.details.after` |
|
|
279
|
+
| `regions` | `region.details.after` |
|
|
280
|
+
| `sales_channels` | `sales_channel.details.after` |
|
|
281
|
+
| `stores` | `store.details.after` |
|
|
282
|
+
| `promotions` | `promotion.details.after` |
|
|
283
|
+
| `campaigns` | `campaign.details.after` |
|
|
284
|
+
| `price_lists` | `price_list.details.after` |
|
|
285
|
+
| `shipping_profiles` | `shipping_profile.details.after` |
|
|
286
|
+
| `inventory_items` | `inventory_item.details.after` |
|
|
287
|
+
| `product_variants` | `product_variant.details.after` |
|
|
288
|
+
|
|
289
|
+
### Additional Widget
|
|
290
|
+
|
|
291
|
+
- **`hide-default-metadata` (`src/admin/widgets/hide-default-metadata.tsx`)**
|
|
292
|
+
- **Zone:** `product.details.side.before`
|
|
293
|
+
- **Purpose:** DOM-level hiding of default Medusa metadata panel to avoid UI duplication.
|
|
294
|
+
- **Interaction:** none (automatic MutationObserver behavior).
|
|
295
|
+
|
|
296
|
+
> ⚠️ Note: This widget hides DOM elements by structure/class heuristics and may need adjustment if Admin DOM structure changes in future Medusa releases.
|
|
297
|
+
|
|
298
|
+
---
|
|
299
|
+
|
|
300
|
+
## Models & Entities
|
|
301
|
+
|
|
302
|
+
No custom database models/entities are defined in this plugin source.
|
|
303
|
+
|
|
304
|
+
The plugin operates on existing Medusa entities by reading/writing their `metadata` field via admin APIs.
|
|
305
|
+
|
|
306
|
+
---
|
|
307
|
+
|
|
308
|
+
## Use Cases & Examples
|
|
309
|
+
|
|
310
|
+
1. **Product enrichment without code changes**
|
|
311
|
+
- Add new product metadata fields (brand, care instructions, support URLs) via plugin options.
|
|
312
|
+
- Use: `entities.products.descriptors` + `product.details.after` widget.
|
|
313
|
+
|
|
314
|
+
2. **Operational order annotations**
|
|
315
|
+
- Add structured metadata to orders (source channel, routing note, internal tags).
|
|
316
|
+
- Use: `entities.orders.descriptors` + metadata table UI.
|
|
317
|
+
|
|
318
|
+
3. **Per-entity metadata governance**
|
|
319
|
+
- Make fields required and validated (`min/max/regex`) to standardize admin data entry.
|
|
320
|
+
- Use: descriptor `required` and `validation`.
|
|
321
|
+
|
|
322
|
+
4. **Variant-level custom attributes**
|
|
323
|
+
- Persist metadata on product variants and update through variant route workflow.
|
|
324
|
+
- Use: `POST /admin/product-variants/:id`.
|
|
325
|
+
|
|
326
|
+
5. **File/media metadata links**
|
|
327
|
+
- Upload file/image/video/audio in metadata form and store uploaded URL in metadata.
|
|
328
|
+
- Use: file/media descriptor types in metadata table.
|
|
329
|
+
|
|
330
|
+
---
|
|
331
|
+
|
|
332
|
+
## Troubleshooting
|
|
333
|
+
|
|
334
|
+
### Metadata widget doesn’t appear
|
|
335
|
+
|
|
336
|
+
- **Cause:** no descriptors configured for that entity.
|
|
337
|
+
- **Fix:** add `entities.<entityType>.descriptors` in plugin options; rebuild/restart app.
|
|
338
|
+
|
|
339
|
+
### “Unable to load metadata configuration”
|
|
340
|
+
|
|
341
|
+
- **Cause:** admin can’t reach `/admin/metadata-config` or plugin not loaded.
|
|
342
|
+
- **Fix:** verify plugin registration in `medusa-config.ts`, rebuild plugin, restart Medusa server.
|
|
343
|
+
|
|
344
|
+
### “No API endpoint configured for <entityType>”
|
|
360
345
|
|
|
361
|
-
|
|
346
|
+
- **Cause:** entity type lacks mapping in registry and no `api_endpoint` override configured.
|
|
347
|
+
- **Fix:** set `api_endpoint` (and optionally `widget_zone`) for that entity in plugin options.
|
|
362
348
|
|
|
363
|
-
|
|
364
|
-
- `npm run dev` - Run in development/watch mode
|
|
349
|
+
### Save fails with backend error
|
|
365
350
|
|
|
366
|
-
|
|
351
|
+
- **Cause:** invalid payload, endpoint mismatch, or authorization issue.
|
|
352
|
+
- **Fix:** verify resolved endpoint, admin auth/session, and descriptor/value shape.
|
|
367
353
|
|
|
368
|
-
|
|
354
|
+
### File upload fails in metadata field
|
|
369
355
|
|
|
370
|
-
|
|
356
|
+
- **Cause:** `/admin/uploads` request fails or no URL returned.
|
|
357
|
+
- **Fix:** confirm uploads endpoint availability and permissions; inspect server response message shown in toast.
|
|
371
358
|
|
|
372
|
-
|
|
359
|
+
### Default and custom metadata sections both visible
|
|
373
360
|
|
|
374
|
-
|
|
361
|
+
- **Cause:** hide widget not active for current zone/page or DOM structure mismatch.
|
|
362
|
+
- **Fix:** verify `hide-default-metadata` widget registration and adjust selector logic if Admin markup changed.
|
|
375
363
|
|
|
376
|
-
|
|
364
|
+
---
|
|
377
365
|
|
|
378
|
-
## Other channels
|
|
379
366
|
|
|
380
|
-
- [GitHub Issues](https://github.com/medusajs/medusa/issues)
|
|
381
|
-
- [Twitter](https://twitter.com/medusajs)
|
|
382
|
-
- [LinkedIn](https://www.linkedin.com/company/medusajs)
|
|
383
|
-
- [Medusa Blog](https://medusajs.com/blog/)
|