strapi-plugin-bulk-updater 1.3.8 → 1.3.9

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.
@@ -3617,15 +3617,18 @@ function extractHeadingsFromRichText(content) {
3617
3617
  }
3618
3618
  return counts;
3619
3619
  }
3620
+ function cleanKey(str2) {
3621
+ return (str2 || "").replace(/[-_]/g, "").toLowerCase().trim();
3622
+ }
3620
3623
  function matchesPath(normalizedPath, leafKey, targetField) {
3621
3624
  if (!targetField) return false;
3622
- const pLower = (normalizedPath || "").toLowerCase().trim();
3623
- const kLower = (leafKey || "").toLowerCase().trim();
3624
- const tLower = targetField.toLowerCase().trim();
3625
- if (!tLower.includes(".")) {
3626
- return kLower === tLower || pLower === tLower || pLower.endsWith(`.${tLower}`);
3625
+ const pClean = cleanKey(normalizedPath);
3626
+ const kClean = cleanKey(leafKey);
3627
+ const tClean = cleanKey(targetField);
3628
+ if (!tClean.includes(".")) {
3629
+ return kClean === tClean || pClean === tClean || pClean.endsWith(`.${tClean}`);
3627
3630
  }
3628
- return pLower === tLower || pLower.endsWith(`.${tLower}`) || pLower.endsWith(tLower);
3631
+ return pClean === tClean || pClean.endsWith(`.${tClean}`) || pClean.endsWith(tClean) || pClean.includes(`.${tClean}`);
3629
3632
  }
3630
3633
  const validationRulesService = ({ strapi: strapi2 }) => ({
3631
3634
  async getStore() {
@@ -3739,8 +3742,9 @@ const validationRulesService = ({ strapi: strapi2 }) => ({
3739
3742
  function componentHasField(compUid, targetField2) {
3740
3743
  const comp = allComponents[compUid];
3741
3744
  if (!comp?.attributes) return false;
3745
+ if (matchesPath(compUid, compUid, targetField2)) return true;
3742
3746
  for (const [attrName, attrDef] of Object.entries(comp.attributes)) {
3743
- if (matchesPath(attrName, attrName, targetField2)) return true;
3747
+ if (matchesPath(attrName, attrName, targetField2) || matchesPath(`${compUid}.${attrName}`, attrName, targetField2)) return true;
3744
3748
  if (attrDef.type === "component" && attrDef.component) {
3745
3749
  if (componentHasField(attrDef.component, targetField2)) return true;
3746
3750
  }
@@ -3763,7 +3767,7 @@ const validationRulesService = ({ strapi: strapi2 }) => ({
3763
3767
  }
3764
3768
  } else if (attrDef.type === "dynamiczone" && Array.isArray(attrDef.components)) {
3765
3769
  const matchingComp = attrDef.components.some(
3766
- (compUid) => componentHasField(compUid, targetField)
3770
+ (compUid) => componentHasField(compUid, targetField) || matchesPath(`${attrKey}.${compUid}`, compUid, targetField)
3767
3771
  );
3768
3772
  if (matchingComp) {
3769
3773
  hasField = true;
@@ -3808,11 +3812,15 @@ const validationRulesService = ({ strapi: strapi2 }) => ({
3808
3812
  for (const entry of entries) {
3809
3813
  let traverse = function(obj, currentPath = "") {
3810
3814
  if (!obj || typeof obj !== "object") return;
3815
+ const compName = typeof obj.__component === "string" ? obj.__component : "";
3811
3816
  for (const key of Object.keys(obj)) {
3817
+ if (key === "__component") continue;
3812
3818
  const val = obj[key];
3813
3819
  const newPath = currentPath ? `${currentPath}.${key}` : key;
3814
3820
  const normalizedPath = newPath.replace(/\.\d+/g, "");
3815
- if (matchesPath(normalizedPath, key, targetField) && typeof val === "string" && val.trim()) {
3821
+ const compPath = compName ? (currentPath ? `${currentPath}.${compName}.${key}` : `${compName}.${key}`).replace(/\.\d+/g, "") : "";
3822
+ const isMatch = matchesPath(normalizedPath, key, targetField) || (compPath ? matchesPath(compPath, key, targetField) : false);
3823
+ if (isMatch && typeof val === "string" && val.trim()) {
3816
3824
  const lower = val.toLowerCase().trim();
3817
3825
  structuredCounts[lower] = (structuredCounts[lower] || 0) + 1;
3818
3826
  }
@@ -34145,12 +34153,16 @@ const index = {
34145
34153
  if (data && typeof data === "object") {
34146
34154
  let scanDataTree = function(obj, currentPath = "") {
34147
34155
  if (!obj || typeof obj !== "object") return;
34156
+ const compName = typeof obj.__component === "string" ? obj.__component : "";
34148
34157
  for (const key of Object.keys(obj)) {
34158
+ if (key === "__component") continue;
34149
34159
  const val = obj[key];
34150
34160
  const newPath = currentPath ? `${currentPath}.${key}` : key;
34151
34161
  const normalizedPath = newPath.replace(/\.\d+/g, "");
34162
+ const compPath = compName ? (currentPath ? `${currentPath}.${compName}.${key}` : `${compName}.${key}`).replace(/\.\d+/g, "") : "";
34152
34163
  for (const rule of effectiveRules) {
34153
- if (matchesPath(normalizedPath, key, rule.targetField) && typeof val === "string" && val.trim()) {
34164
+ const isMatch = matchesPath(normalizedPath, key, rule.targetField) || (compPath ? matchesPath(compPath, key, rule.targetField) : false);
34165
+ if (isMatch && typeof val === "string" && val.trim()) {
34154
34166
  const lowerVal = val.toLowerCase().trim();
34155
34167
  structuredCounts[rule.id] = structuredCounts[rule.id] || {};
34156
34168
  structuredCounts[rule.id][lowerVal] = (structuredCounts[rule.id][lowerVal] || 0) + 1;