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.
@@ -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 hasValue = currentValue !== void 0 && currentValue !== null && currentValue !== "";
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 base = originalMetadata && typeof originalMetadata === "object" ? { ...originalMetadata } : {};
491
+ const result = {};
483
492
  descriptors.forEach((descriptor) => {
484
493
  const coerced = coerceMetadataValue(descriptor, values[descriptor.key]);
485
- if (coerced === void 0) {
486
- delete base[descriptor.key];
487
- } else {
488
- base[descriptor.key] = coerced;
494
+ if (coerced !== void 0) {
495
+ result[descriptor.key] = coerced;
489
496
  }
490
497
  });
491
- return base;
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 || value === "") return void 0;
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 num = typeof value === "number" ? value : Number(String(value).trim());
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 str = String(value).trim();
700
- if (!str) return void 0;
710
+ const str2 = String(value).trim();
711
+ if (!str2) return void 0;
701
712
  try {
702
- return JSON.parse(str);
713
+ return JSON.parse(str2);
703
714
  } catch {
704
715
  return void 0;
705
716
  }
706
717
  }
707
- const trimmed = String(value).trim();
708
- if (!trimmed) return void 0;
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: "Changes are stored on the entity metadata object. Clearing a field removes the corresponding key on save." }),
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 metadata"
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 hasValue = currentValue !== void 0 && currentValue !== null && currentValue !== "";
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 base = originalMetadata && typeof originalMetadata === "object" ? { ...originalMetadata } : {};
490
+ const result = {};
482
491
  descriptors.forEach((descriptor) => {
483
492
  const coerced = coerceMetadataValue(descriptor, values[descriptor.key]);
484
- if (coerced === void 0) {
485
- delete base[descriptor.key];
486
- } else {
487
- base[descriptor.key] = coerced;
493
+ if (coerced !== void 0) {
494
+ result[descriptor.key] = coerced;
488
495
  }
489
496
  });
490
- return base;
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 || value === "") return void 0;
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 num = typeof value === "number" ? value : Number(String(value).trim());
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 str = String(value).trim();
699
- if (!str) return void 0;
709
+ const str2 = String(value).trim();
710
+ if (!str2) return void 0;
700
711
  try {
701
- return JSON.parse(str);
712
+ return JSON.parse(str2);
702
713
  } catch {
703
714
  return void 0;
704
715
  }
705
716
  }
706
- const trimmed = String(value).trim();
707
- if (!trimmed) return void 0;
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: "Changes are stored on the entity metadata object. Clearing a field removes the corresponding key on save." }),
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 metadata"
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
- function buildMetadataPayload({ descriptors, values, originalMetadata, }) {
97
- const base = originalMetadata && typeof originalMetadata === "object"
98
- ? { ...originalMetadata }
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 === undefined) {
103
- delete base[descriptor.key];
104
- }
105
- else {
106
- base[descriptor.key] = coerced;
114
+ if (coerced !== undefined) {
115
+ result[descriptor.key] = coerced;
107
116
  }
108
117
  });
109
- return base;
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 || value === "")
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 num = typeof value === "number" ? value : Number(String(value).trim());
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 trimmed = String(value).trim();
372
- if (!trimmed)
373
- return undefined;
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
- <p align="center">
2
- <a href="https://www.medusajs.com">
3
- <picture>
4
- <source media="(prefers-color-scheme: dark)" srcset="https://user-images.githubusercontent.com/59018053/229103275-b5e482bb-4601-46e6-8142-244f531cebdb.svg">
5
- <source media="(prefers-color-scheme: light)" srcset="https://user-images.githubusercontent.com/59018053/229103726-e5b529a3-9b3f-4970-8a1f-c6af37f087bf.svg">
6
- <img alt="Medusa logo" src="https://user-images.githubusercontent.com/59018053/229103726-e5b529a3-9b3f-4970-8a1f-c6af37f087bf.svg">
7
- </picture>
8
- </a>
9
- </p>
10
- <h1 align="center">
11
- Medusa Dynamic Metadata
12
- </h1>
13
-
14
- <h4 align="center">
15
- <a href="https://docs.medusajs.com">Documentation</a> |
16
- <a href="https://www.medusajs.com">Website</a>
17
- </h4>
18
-
19
- <p align="center">
20
- Building blocks for digital commerce
21
- </p>
22
- <p align="center">
23
- <a href="https://github.com/medusajs/medusa/blob/master/CONTRIBUTING.md">
24
- <img src="https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat" alt="PRs welcome!" />
25
- </a>
26
- <a href="https://www.producthunt.com/posts/medusa"><img src="https://img.shields.io/badge/Product%20Hunt-%231%20Product%20of%20the%20Day-%23DA552E" alt="Product Hunt"></a>
27
- <a href="https://discord.gg/xpCwq3Kfn8">
28
- <img src="https://img.shields.io/badge/chat-on%20discord-7289DA.svg" alt="Discord Chat" />
29
- </a>
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
- ### Configuration
82
-
83
- Add the plugin to your `medusa-config.ts`:
37
+ ### Register in `medusa-config.ts`
84
38
 
85
- ```typescript
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
- ### Widget Files
61
+ ### Database Migrations
126
62
 
127
- The plugin includes minimal wrapper widget files for all 14 supported entities listed above. Each wrapper:
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
- 1. Specifies the widget zone (required by Medusa's widget system)
130
- 2. Delegates to the universal `UniversalMetadataWidget` component
131
- 3. Automatically detects the entity type at runtime
65
+ ---
132
66
 
133
- **Note:** If an entity is not configured in your `medusa-config.ts`, the admin hook will treat that as "no descriptors" and the widget will not render for that entity (no error is shown). This prevents widgets from appearing for entities you don't intend to manage metadata for, such as `regions`.
67
+ ## Configuration (`config.ts` / plugin options)
134
68
 
135
- **For entities not in the supported list**: Only entities with valid admin detail pages can have metadata widgets. If you need to add support for a new entity that has a detail page in Medusa's admin, create a minimal wrapper widget file using the template in `src/admin/widget-templates/generic-metadata-widget.template.tsx` (copy it into `src/admin/widgets/`; do not leave the template inside `widgets/` or it will register as a duplicate widget).
69
+ Defined in `src/config/metadata-options.ts`.
136
70
 
137
- ### Building the Plugin
71
+ ### Root Options
138
72
 
139
- ```bash
140
- npm run build
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
- This builds the plugin with all extensions.
77
+ ### Entity Metadata Config
144
78
 
145
- ### Development
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
- ```bash
148
- npm run dev
149
- ```
87
+ ### Metadata Descriptor Fields
150
88
 
151
- This runs the plugin in watch mode for development.
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
- ## How It Works
100
+ ### Supported `MetadataFieldType` Values
154
101
 
155
- ### Architecture Flow
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
- Configuration (medusa-config.ts)
159
-
160
- Plugin Initialization
161
-
162
- Widget Files (minimal wrappers with zones)
163
-
164
- UniversalMetadataWidget (runtime entity detection)
165
-
166
- MetadataTableWidget (UI component)
167
-
168
- API Endpoints (save/load metadata)
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
- ### Universal Widget Architecture
143
+ ---
172
144
 
173
- The plugin uses a single universal widget component (`UniversalMetadataWidget`) that works for all entity types:
145
+ ## Environment Variables
174
146
 
175
- 1. **Runtime Entity Detection**: The widget automatically detects the entity type using:
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
- 2. **Configuration Loading**: Fetches metadata descriptors from `/admin/metadata-config?entity={entityType}` based on detected entity type
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
- 3. **Dynamic Rendering**: Renders appropriate form fields based on the descriptors (text, number, date, select, multiselect, color, JSON, etc.)
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
- 4. **Metadata Management**: Saves metadata through standard Medusa entity API endpoints
155
+ ---
184
156
 
185
- ### Widget Structure
157
+ ## REST APIs / Routes
186
158
 
187
- Widget files are minimal wrappers that:
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
- Example widget file:
193
- ```typescript
194
- const Widget = ({ data }) => {
195
- return <UniversalMetadataWidget data={data} zone="product.details.after" />
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
- export const config = defineWidgetConfig({
199
- zone: "product.details.after"
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
- ### Creating Widgets for New Entities
228
+ ---
204
229
 
205
- To add metadata support for a new entity:
230
+ ## Services
206
231
 
207
- 1. **Add configuration** in `medusa-config.ts`:
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
- 2. **Create a minimal widget file** (if zone doesn't match existing patterns):
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
- ### Advanced Configuration
236
+ ---
300
237
 
301
- ```typescript
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
- ### Commerce-Focused Examples
240
+ No custom workflows or steps are defined in this plugin source.
320
241
 
321
- ```typescript
322
- {
323
- entities: {
324
- products: {
325
- descriptors: [
326
- // Sale dates
327
- { key: "sale_start", label: "Sale Start", type: "datetime", required: true },
328
- { key: "sale_end", label: "Sale End", type: "datetime" },
329
- // Multiselect tags
330
- {
331
- key: "tags",
332
- label: "Tags",
333
- type: "multiselect",
334
- options: [
335
- { value: "bestseller", label: "Bestseller" },
336
- { value: "new", label: "New Arrival" },
337
- { value: "sale", label: "On Sale" },
338
- ],
339
- },
340
- // Color customization
341
- { key: "badge_color", label: "Badge Color", type: "color", default_value: "#ff0000" },
342
- // Structured data
343
- {
344
- key: "dimensions",
345
- label: "Dimensions (JSON)",
346
- type: "object",
347
- default_value: { width: 0, height: 0, depth: 0 },
348
- },
349
- // Contact/URL fields
350
- { key: "support_url", label: "Support URL", type: "url" },
351
- { key: "support_email", label: "Support Email", type: "email" },
352
- { key: "support_phone", label: "Support Phone", type: "phone" },
353
- // Relation to another product
354
- { key: "related_product_id", label: "Related Product", type: "relation" },
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
- ## Scripts
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
- - `npm run build` - Build the plugin
364
- - `npm run dev` - Run in development/watch mode
349
+ ### Save fails with backend error
365
350
 
366
- ## What is Medusa
351
+ - **Cause:** invalid payload, endpoint mismatch, or authorization issue.
352
+ - **Fix:** verify resolved endpoint, admin auth/session, and descriptor/value shape.
367
353
 
368
- Medusa is a set of commerce modules and tools that allow you to build rich, reliable, and performant commerce applications without reinventing core commerce logic. The modules can be customized and used to build advanced ecommerce stores, marketplaces, or any product that needs foundational commerce primitives. All modules are open-source and freely available on npm.
354
+ ### File upload fails in metadata field
369
355
 
370
- Learn more about [Medusa’s architecture](https://docs.medusajs.com/learn/introduction/architecture) and [commerce modules](https://docs.medusajs.com/learn/fundamentals/modules/commerce-modules) in the Docs.
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
- ## Community & Contributions
359
+ ### Default and custom metadata sections both visible
373
360
 
374
- The community and core team are available in [GitHub Discussions](https://github.com/medusajs/medusa/discussions), where you can ask for support, discuss roadmap, and share ideas.
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
- Join our [Discord server](https://discord.com/invite/medusajs) to meet other community members.
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/)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "medusa-dynamic-metadata",
3
- "version": "0.0.8",
3
+ "version": "0.0.10",
4
4
  "description": "A starter for Medusa plugins.",
5
5
  "author": "Medusa (https://medusajs.com)",
6
6
  "license": "MIT",