strapi-plugin-bulk-updater 1.4.2 → 1.4.3
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/dist/_chunks/{BulkUpdater-D4v5fP-1.mjs → BulkUpdater-CbQk_OQG.mjs} +435 -85
- package/dist/_chunks/BulkUpdater-CbQk_OQG.mjs.map +1 -0
- package/dist/_chunks/{BulkUpdater-L2FdlJfh.js → BulkUpdater-mSvmiLwc.js} +434 -84
- package/dist/_chunks/BulkUpdater-mSvmiLwc.js.map +1 -0
- package/dist/admin/index.js +1 -1
- package/dist/admin/index.mjs +1 -1
- package/dist/server/index.js +278 -63
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +278 -63
- package/dist/server/index.mjs.map +1 -1
- package/package.json +3 -3
- package/dist/_chunks/BulkUpdater-D4v5fP-1.mjs.map +0 -1
- package/dist/_chunks/BulkUpdater-L2FdlJfh.js.map +0 -1
package/dist/admin/index.js
CHANGED
|
@@ -68,7 +68,7 @@ const index = {
|
|
|
68
68
|
id: `${PLUGIN_ID}.plugin.name`,
|
|
69
69
|
defaultMessage: "Bulk Attribute Updater"
|
|
70
70
|
},
|
|
71
|
-
Component: () => Promise.resolve().then(() => require("../_chunks/BulkUpdater-
|
|
71
|
+
Component: () => Promise.resolve().then(() => require("../_chunks/BulkUpdater-mSvmiLwc.js")),
|
|
72
72
|
permissions: [],
|
|
73
73
|
position: 3
|
|
74
74
|
});
|
package/dist/admin/index.mjs
CHANGED
|
@@ -65,7 +65,7 @@ const index = {
|
|
|
65
65
|
id: `${PLUGIN_ID}.plugin.name`,
|
|
66
66
|
defaultMessage: "Bulk Attribute Updater"
|
|
67
67
|
},
|
|
68
|
-
Component: () => import("../_chunks/BulkUpdater-
|
|
68
|
+
Component: () => import("../_chunks/BulkUpdater-CbQk_OQG.mjs"),
|
|
69
69
|
permissions: [],
|
|
70
70
|
position: 3
|
|
71
71
|
});
|
package/dist/server/index.js
CHANGED
|
@@ -911,9 +911,72 @@ function discoverComponentAttributes(strapi, compUid, prefix, currentDepth, maxD
|
|
|
911
911
|
}
|
|
912
912
|
return Array.from(new Set(discoveredAttrs));
|
|
913
913
|
}
|
|
914
|
+
function parseDynamicZonePath(path) {
|
|
915
|
+
if (!path) return { cleanPath: "", rootKey: "", subPath: "" };
|
|
916
|
+
const bracketMatch = path.match(/^([^.[]+)\[([^\]]+)\]\.(.+)$/);
|
|
917
|
+
if (bracketMatch) {
|
|
918
|
+
const rootKey = bracketMatch[1];
|
|
919
|
+
const selector = bracketMatch[2];
|
|
920
|
+
const subPath = bracketMatch[3];
|
|
921
|
+
const cleanPath = `${rootKey}.${subPath}`;
|
|
922
|
+
if (/^\d+$/.test(selector)) {
|
|
923
|
+
return { cleanPath, rootKey, subPath, targetIndex: parseInt(selector, 10) };
|
|
924
|
+
}
|
|
925
|
+
return { cleanPath, rootKey, subPath, targetComponentUid: selector };
|
|
926
|
+
}
|
|
927
|
+
const parts = path.split(".");
|
|
928
|
+
return {
|
|
929
|
+
cleanPath: path,
|
|
930
|
+
rootKey: parts[0] || "",
|
|
931
|
+
subPath: parts.slice(1).join(".")
|
|
932
|
+
};
|
|
933
|
+
}
|
|
934
|
+
function formatComponentName(compUid) {
|
|
935
|
+
if (!compUid) return "Component";
|
|
936
|
+
const name = compUid.includes(".") ? compUid.split(".")[1] : compUid;
|
|
937
|
+
return name.split(/[-_]/).map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join(" ");
|
|
938
|
+
}
|
|
939
|
+
function getAllNestedValues(obj, path) {
|
|
940
|
+
if (!obj || !path) return [];
|
|
941
|
+
const parsed = parseDynamicZonePath(path);
|
|
942
|
+
const parts = parsed.cleanPath.split(".");
|
|
943
|
+
const [head, ...tail] = parts;
|
|
944
|
+
const rootTarget = obj[head];
|
|
945
|
+
if (Array.isArray(rootTarget)) {
|
|
946
|
+
const results = [];
|
|
947
|
+
rootTarget.forEach((item, idx) => {
|
|
948
|
+
if (!item || typeof item !== "object") return;
|
|
949
|
+
if (parsed.targetIndex !== void 0 && idx !== parsed.targetIndex) return;
|
|
950
|
+
if (parsed.targetComponentUid && item.__component !== parsed.targetComponentUid) return;
|
|
951
|
+
const subVal = tail.length > 0 ? getDeepProperty(item, tail.join(".")) : item;
|
|
952
|
+
if (subVal !== void 0) {
|
|
953
|
+
results.push({
|
|
954
|
+
index: idx,
|
|
955
|
+
componentUid: item.__component,
|
|
956
|
+
componentName: formatComponentName(item.__component),
|
|
957
|
+
value: subVal,
|
|
958
|
+
path: `${head}[#${idx}${item.__component ? ` ${formatComponentName(item.__component)}` : ""}].${tail.join(".")}`
|
|
959
|
+
});
|
|
960
|
+
}
|
|
961
|
+
});
|
|
962
|
+
return results;
|
|
963
|
+
}
|
|
964
|
+
const singleVal = getDeepProperty(obj, parsed.cleanPath);
|
|
965
|
+
if (singleVal !== void 0) {
|
|
966
|
+
return [
|
|
967
|
+
{
|
|
968
|
+
index: 0,
|
|
969
|
+
value: singleVal,
|
|
970
|
+
path: parsed.cleanPath
|
|
971
|
+
}
|
|
972
|
+
];
|
|
973
|
+
}
|
|
974
|
+
return [];
|
|
975
|
+
}
|
|
914
976
|
function isDeepComponentField(contentType, allComponents, attribute) {
|
|
915
|
-
if (!attribute || !attribute.includes(".")) return false;
|
|
916
|
-
const
|
|
977
|
+
if (!attribute || !attribute.includes(".") && !attribute.includes("[")) return false;
|
|
978
|
+
const parsed = parseDynamicZonePath(attribute);
|
|
979
|
+
const parts = parsed.cleanPath.split(".");
|
|
917
980
|
function checkPath(currentSchema, pathParts) {
|
|
918
981
|
if (pathParts.length === 0) return true;
|
|
919
982
|
if (!currentSchema || !currentSchema.attributes) return false;
|
|
@@ -929,6 +992,10 @@ function isDeepComponentField(contentType, allComponents, attribute) {
|
|
|
929
992
|
}
|
|
930
993
|
if (attrDef.type === "dynamiczone") {
|
|
931
994
|
const compUids = Array.isArray(attrDef.components) ? attrDef.components : [];
|
|
995
|
+
if (parsed.targetComponentUid) {
|
|
996
|
+
const comp = allComponents[parsed.targetComponentUid];
|
|
997
|
+
return comp ? checkPath(comp, tail) : false;
|
|
998
|
+
}
|
|
932
999
|
return compUids.some((compUid) => {
|
|
933
1000
|
const comp = allComponents[compUid];
|
|
934
1001
|
return checkPath(comp, tail);
|
|
@@ -940,8 +1007,9 @@ function isDeepComponentField(contentType, allComponents, attribute) {
|
|
|
940
1007
|
}
|
|
941
1008
|
function getLeafAttributeSchema(contentType, allComponents, attribute) {
|
|
942
1009
|
if (!attribute) return null;
|
|
943
|
-
|
|
944
|
-
|
|
1010
|
+
const parsed = parseDynamicZonePath(attribute);
|
|
1011
|
+
if (!parsed.cleanPath.includes(".")) return contentType?.attributes?.[parsed.cleanPath] || null;
|
|
1012
|
+
const parts = parsed.cleanPath.split(".");
|
|
945
1013
|
function resolveLeaf(currentSchema, pathParts) {
|
|
946
1014
|
if (!currentSchema || !currentSchema.attributes) return null;
|
|
947
1015
|
const [head, ...tail] = pathParts;
|
|
@@ -955,6 +1023,9 @@ function getLeafAttributeSchema(contentType, allComponents, attribute) {
|
|
|
955
1023
|
}
|
|
956
1024
|
if (attrDef.type === "dynamiczone") {
|
|
957
1025
|
const compUids = Array.isArray(attrDef.components) ? attrDef.components : [];
|
|
1026
|
+
if (parsed.targetComponentUid) {
|
|
1027
|
+
return resolveLeaf(allComponents[parsed.targetComponentUid], tail);
|
|
1028
|
+
}
|
|
958
1029
|
for (const compUid of compUids) {
|
|
959
1030
|
const found = resolveLeaf(allComponents[compUid], tail);
|
|
960
1031
|
if (found) return found;
|
|
@@ -964,22 +1035,28 @@ function getLeafAttributeSchema(contentType, allComponents, attribute) {
|
|
|
964
1035
|
}
|
|
965
1036
|
return resolveLeaf(contentType, parts);
|
|
966
1037
|
}
|
|
967
|
-
function setDeepProperty(obj, pathParts, value) {
|
|
1038
|
+
function setDeepProperty(obj, pathParts, value, options) {
|
|
968
1039
|
if (pathParts.length === 0) return value;
|
|
969
1040
|
const [head, ...tail] = pathParts;
|
|
970
1041
|
if (Array.isArray(obj)) {
|
|
971
1042
|
if (/^\d+$/.test(head)) {
|
|
972
1043
|
const idx = parseInt(head, 10);
|
|
973
1044
|
const copy = [...obj];
|
|
974
|
-
copy[idx] = setDeepProperty(copy[idx] || {}, tail, value);
|
|
1045
|
+
copy[idx] = setDeepProperty(copy[idx] || {}, tail, value, options);
|
|
975
1046
|
return copy;
|
|
976
1047
|
}
|
|
977
|
-
return obj.map((item) => {
|
|
1048
|
+
return obj.map((item, idx) => {
|
|
978
1049
|
if (!item || typeof item !== "object") return item;
|
|
1050
|
+
if (options?.targetIndexes && options.targetIndexes.length > 0) {
|
|
1051
|
+
if (!options.targetIndexes.includes(idx)) return item;
|
|
1052
|
+
}
|
|
1053
|
+
if (options?.targetComponentUid) {
|
|
1054
|
+
if (item.__component !== options.targetComponentUid) return item;
|
|
1055
|
+
}
|
|
979
1056
|
if (head in item || tail.length > 0 && typeof item[head] === "object") {
|
|
980
1057
|
return {
|
|
981
1058
|
...item,
|
|
982
|
-
[head]: setDeepProperty(item[head], tail, value)
|
|
1059
|
+
[head]: setDeepProperty(item[head], tail, value, options)
|
|
983
1060
|
};
|
|
984
1061
|
}
|
|
985
1062
|
return item;
|
|
@@ -991,16 +1068,17 @@ function setDeepProperty(obj, pathParts, value) {
|
|
|
991
1068
|
} else {
|
|
992
1069
|
const subTarget = current[head];
|
|
993
1070
|
if (Array.isArray(subTarget)) {
|
|
994
|
-
current[head] = setDeepProperty(subTarget, tail, value);
|
|
1071
|
+
current[head] = setDeepProperty(subTarget, tail, value, options);
|
|
995
1072
|
} else {
|
|
996
|
-
current[head] = setDeepProperty(subTarget || {}, tail, value);
|
|
1073
|
+
current[head] = setDeepProperty(subTarget || {}, tail, value, options);
|
|
997
1074
|
}
|
|
998
1075
|
}
|
|
999
1076
|
return current;
|
|
1000
1077
|
}
|
|
1001
1078
|
function getDeepProperty(obj, path) {
|
|
1002
1079
|
if (!obj || !path) return void 0;
|
|
1003
|
-
const
|
|
1080
|
+
const parsed = parseDynamicZonePath(path);
|
|
1081
|
+
const parts = parsed.cleanPath.split(".");
|
|
1004
1082
|
function extract(current, remainingParts) {
|
|
1005
1083
|
if (current === void 0 || current === null) return void 0;
|
|
1006
1084
|
if (remainingParts.length === 0) return current;
|
|
@@ -1009,7 +1087,10 @@ function getDeepProperty(obj, path) {
|
|
|
1009
1087
|
if (/^\d+$/.test(head)) {
|
|
1010
1088
|
return extract(current[parseInt(head, 10)], tail);
|
|
1011
1089
|
}
|
|
1012
|
-
for (
|
|
1090
|
+
for (let idx = 0; idx < current.length; idx++) {
|
|
1091
|
+
const item = current[idx];
|
|
1092
|
+
if (parsed.targetIndex !== void 0 && idx !== parsed.targetIndex) continue;
|
|
1093
|
+
if (parsed.targetComponentUid && item?.__component !== parsed.targetComponentUid) continue;
|
|
1013
1094
|
const found = extract(item?.[head], tail);
|
|
1014
1095
|
if (found !== void 0 && found !== null) return found;
|
|
1015
1096
|
}
|
|
@@ -1174,7 +1255,12 @@ async function executeBatchInternal(strapi, {
|
|
|
1174
1255
|
for (const item of selectedEntries) {
|
|
1175
1256
|
if (!item.uid || !item.documentId) continue;
|
|
1176
1257
|
const key = `${item.uid}@@@${item.documentId}`;
|
|
1177
|
-
targetsMap.set(key, {
|
|
1258
|
+
targetsMap.set(key, {
|
|
1259
|
+
uid: item.uid,
|
|
1260
|
+
documentId: item.documentId,
|
|
1261
|
+
dynamicZoneIndexes: item.dynamicZoneIndexes,
|
|
1262
|
+
targetComponentUid: item.targetComponentUid
|
|
1263
|
+
});
|
|
1178
1264
|
}
|
|
1179
1265
|
if (targetsMap.size === 0) {
|
|
1180
1266
|
throw new Error("No collections or entries were selected for update.");
|
|
@@ -1233,10 +1319,13 @@ async function executeBatchInternal(strapi, {
|
|
|
1233
1319
|
try {
|
|
1234
1320
|
const currentEntry = await getDocumentDeduplicated(target.uid, target.documentId);
|
|
1235
1321
|
const entryLabel = currentEntry?.name || currentEntry?.title || currentEntry?.email || `Entry #${target.documentId}`;
|
|
1236
|
-
const
|
|
1322
|
+
const parsed = parseDynamicZonePath(attribute);
|
|
1323
|
+
const isNested = attribute.includes(".") || attribute.includes("[");
|
|
1237
1324
|
const isComponentNested = isNested && isDeepComponentField(contentType, strapi.components, attribute);
|
|
1238
|
-
const parts = isNested ?
|
|
1239
|
-
const rootKey =
|
|
1325
|
+
const parts = isNested ? parsed.cleanPath.split(".") : [];
|
|
1326
|
+
const rootKey = parsed.rootKey;
|
|
1327
|
+
const targetComponentUid = target.targetComponentUid || parsed.targetComponentUid;
|
|
1328
|
+
const targetIndexes = target.dynamicZoneIndexes;
|
|
1240
1329
|
const attrDef = contentType?.attributes?.[attribute];
|
|
1241
1330
|
const hasAttribute = Boolean(attrDef) || isComponentNested;
|
|
1242
1331
|
if (hasAttribute) {
|
|
@@ -1249,12 +1338,25 @@ async function executeBatchInternal(strapi, {
|
|
|
1249
1338
|
const currentEntryWithPopulate = await strapi.documents(target.uid).findOne(findOneArgs);
|
|
1250
1339
|
const isRootDz = contentType?.attributes?.[rootKey]?.type === "dynamiczone";
|
|
1251
1340
|
const existingRoot = currentEntryWithPopulate?.[rootKey] || (isRootDz ? [] : {});
|
|
1252
|
-
|
|
1341
|
+
let affectedMatches = [];
|
|
1342
|
+
if (isRootDz && Array.isArray(existingRoot)) {
|
|
1343
|
+
affectedMatches = getAllNestedValues({ [rootKey]: existingRoot }, attribute);
|
|
1344
|
+
if (targetIndexes && targetIndexes.length > 0) {
|
|
1345
|
+
affectedMatches = affectedMatches.filter((m) => targetIndexes.includes(m.index));
|
|
1346
|
+
}
|
|
1347
|
+
if (targetComponentUid) {
|
|
1348
|
+
affectedMatches = affectedMatches.filter((m) => m.componentUid === targetComponentUid);
|
|
1349
|
+
}
|
|
1350
|
+
}
|
|
1351
|
+
const currentVal2 = isRootDz ? affectedMatches.length > 0 ? affectedMatches.map((m) => m.value).join(", ") : getDeepProperty(existingRoot, parts.slice(1).join(".")) : getDeepProperty(existingRoot, parts.slice(1).join("."));
|
|
1253
1352
|
let newValue2 = value;
|
|
1254
1353
|
if (regexObj && typeof currentVal2 === "string") {
|
|
1255
1354
|
newValue2 = currentVal2.replace(regexObj, value);
|
|
1256
1355
|
}
|
|
1257
|
-
const updatedRoot = setDeepProperty(existingRoot, parts.slice(1), newValue2
|
|
1356
|
+
const updatedRoot = setDeepProperty(existingRoot, parts.slice(1), newValue2, {
|
|
1357
|
+
targetIndexes,
|
|
1358
|
+
targetComponentUid
|
|
1359
|
+
});
|
|
1258
1360
|
await strapi.documents(target.uid).update({
|
|
1259
1361
|
documentId: target.documentId,
|
|
1260
1362
|
data: {
|
|
@@ -1278,6 +1380,14 @@ async function executeBatchInternal(strapi, {
|
|
|
1278
1380
|
userId: currentUser?.id,
|
|
1279
1381
|
statusOverride: publishOnApproval && isDraftAndPublishComp ? "published" : void 0
|
|
1280
1382
|
});
|
|
1383
|
+
const dzDiffs = isRootDz && affectedMatches.length > 0 ? affectedMatches.map((m) => ({
|
|
1384
|
+
index: m.index,
|
|
1385
|
+
componentUid: m.componentUid,
|
|
1386
|
+
componentName: m.componentName,
|
|
1387
|
+
attribute: `${rootKey}[#${m.index} ${m.componentName}].${parts.slice(1).join(".")}`,
|
|
1388
|
+
oldValue: m.value,
|
|
1389
|
+
newValue: regexObj && typeof m.value === "string" ? m.value.replace(regexObj, value) : value
|
|
1390
|
+
})) : [];
|
|
1281
1391
|
return {
|
|
1282
1392
|
uid: target.uid,
|
|
1283
1393
|
collectionName: displayName,
|
|
@@ -1287,7 +1397,8 @@ async function executeBatchInternal(strapi, {
|
|
|
1287
1397
|
oldValue: currentVal2 ?? null,
|
|
1288
1398
|
newValue: newValue2,
|
|
1289
1399
|
status: "updated",
|
|
1290
|
-
message: `Successfully updated nested field ${attribute}
|
|
1400
|
+
message: isRootDz ? `Successfully updated ${affectedMatches.length} dynamic zone item(s) in ${attribute}` : `Successfully updated nested field ${attribute}`,
|
|
1401
|
+
dynamicZoneDiffs: dzDiffs
|
|
1291
1402
|
};
|
|
1292
1403
|
}
|
|
1293
1404
|
if (attrDef.type === "relation") {
|
|
@@ -1316,13 +1427,13 @@ async function executeBatchInternal(strapi, {
|
|
|
1316
1427
|
newDisplay = "(cleared / unlinked)";
|
|
1317
1428
|
} else {
|
|
1318
1429
|
try {
|
|
1319
|
-
const
|
|
1320
|
-
if (
|
|
1321
|
-
mode =
|
|
1322
|
-
targetDocIds = Array.isArray(
|
|
1323
|
-
newDisplay =
|
|
1324
|
-
} else if (Array.isArray(
|
|
1325
|
-
targetDocIds =
|
|
1430
|
+
const parsed2 = JSON.parse(value);
|
|
1431
|
+
if (parsed2 && typeof parsed2 === "object" && parsed2.mode) {
|
|
1432
|
+
mode = parsed2.mode;
|
|
1433
|
+
targetDocIds = Array.isArray(parsed2.documentIds) ? parsed2.documentIds : parsed2.documentId ? [parsed2.documentId] : [];
|
|
1434
|
+
newDisplay = parsed2.label || targetDocIds.join(", ") || `[${mode}]`;
|
|
1435
|
+
} else if (Array.isArray(parsed2)) {
|
|
1436
|
+
targetDocIds = parsed2;
|
|
1326
1437
|
newDisplay = targetDocIds.join(", ");
|
|
1327
1438
|
} else {
|
|
1328
1439
|
targetDocIds = [value];
|
|
@@ -1466,6 +1577,26 @@ async function executeBatchInternal(strapi, {
|
|
|
1466
1577
|
...r,
|
|
1467
1578
|
isLive: r.status === "updated"
|
|
1468
1579
|
}));
|
|
1580
|
+
const flattenedDiffs = [];
|
|
1581
|
+
for (const r of results) {
|
|
1582
|
+
if (r.dynamicZoneDiffs && r.dynamicZoneDiffs.length > 0) {
|
|
1583
|
+
for (const dz of r.dynamicZoneDiffs) {
|
|
1584
|
+
flattenedDiffs.push({
|
|
1585
|
+
uid: r.uid,
|
|
1586
|
+
collectionName: r.collectionName,
|
|
1587
|
+
documentId: r.documentId,
|
|
1588
|
+
label: `${r.label} [Block #${dz.index} (${dz.componentName})]`,
|
|
1589
|
+
attribute: dz.attribute,
|
|
1590
|
+
oldValue: dz.oldValue,
|
|
1591
|
+
newValue: dz.newValue,
|
|
1592
|
+
status: "updated",
|
|
1593
|
+
message: `Updated ${dz.attribute}`
|
|
1594
|
+
});
|
|
1595
|
+
}
|
|
1596
|
+
} else {
|
|
1597
|
+
flattenedDiffs.push(r);
|
|
1598
|
+
}
|
|
1599
|
+
}
|
|
1469
1600
|
const batchSummary = {
|
|
1470
1601
|
batchId,
|
|
1471
1602
|
attribute,
|
|
@@ -1477,7 +1608,7 @@ async function executeBatchInternal(strapi, {
|
|
|
1477
1608
|
};
|
|
1478
1609
|
await strapi.plugin("bulk-updater").service("audit").recordBatch(
|
|
1479
1610
|
batchSummary,
|
|
1480
|
-
|
|
1611
|
+
flattenedDiffs,
|
|
1481
1612
|
currentUser
|
|
1482
1613
|
);
|
|
1483
1614
|
return {
|
|
@@ -1745,6 +1876,19 @@ const bulkUpdaterService = ({ strapi }) => {
|
|
|
1745
1876
|
colAttributesMeta
|
|
1746
1877
|
);
|
|
1747
1878
|
nestedComponentAttrs.push(...compAttrs);
|
|
1879
|
+
const scopedAttrs = discoverComponentAttributes(
|
|
1880
|
+
strapi,
|
|
1881
|
+
compUid,
|
|
1882
|
+
`${attrKey}[${compUid}]`,
|
|
1883
|
+
1,
|
|
1884
|
+
5,
|
|
1885
|
+
systemFields,
|
|
1886
|
+
allContentTypes,
|
|
1887
|
+
relationsByAttr,
|
|
1888
|
+
allRelationsMeta,
|
|
1889
|
+
colAttributesMeta
|
|
1890
|
+
);
|
|
1891
|
+
nestedComponentAttrs.push(...scopedAttrs);
|
|
1748
1892
|
}
|
|
1749
1893
|
return false;
|
|
1750
1894
|
}
|
|
@@ -1959,13 +2103,20 @@ const bulkUpdaterService = ({ strapi }) => {
|
|
|
1959
2103
|
const attrs = contentType.attributes || {};
|
|
1960
2104
|
let colHasAttribute = false;
|
|
1961
2105
|
let isNestedAttr = false;
|
|
2106
|
+
let isRootDz = false;
|
|
1962
2107
|
let parts = [];
|
|
1963
2108
|
if (targetFilterAttr) {
|
|
1964
|
-
|
|
2109
|
+
const parsed = parseDynamicZonePath(targetFilterAttr);
|
|
2110
|
+
if (parsed.rootKey && contentType.attributes?.[parsed.rootKey]?.type === "dynamiczone") {
|
|
2111
|
+
isRootDz = true;
|
|
2112
|
+
colHasAttribute = true;
|
|
2113
|
+
isNestedAttr = true;
|
|
2114
|
+
parts = parsed.cleanPath.split(".");
|
|
2115
|
+
} else if (targetFilterAttr.includes(".") || targetFilterAttr.includes("[")) {
|
|
1965
2116
|
isNestedAttr = isDeepComponentField(contentType, strapi.components, targetFilterAttr);
|
|
1966
2117
|
if (isNestedAttr) {
|
|
1967
2118
|
colHasAttribute = true;
|
|
1968
|
-
parts =
|
|
2119
|
+
parts = parsed.cleanPath.split(".");
|
|
1969
2120
|
}
|
|
1970
2121
|
} else if (attrs[targetFilterAttr]) {
|
|
1971
2122
|
colHasAttribute = true;
|
|
@@ -2022,8 +2173,11 @@ const bulkUpdaterService = ({ strapi }) => {
|
|
|
2022
2173
|
}
|
|
2023
2174
|
if (condition !== void 0) {
|
|
2024
2175
|
if (isNestedAttr) {
|
|
2025
|
-
|
|
2026
|
-
|
|
2176
|
+
if (isRootDz) ;
|
|
2177
|
+
else {
|
|
2178
|
+
const deepFilter = buildDeepFilter(parts, condition);
|
|
2179
|
+
Object.assign(filters, deepFilter);
|
|
2180
|
+
}
|
|
2027
2181
|
} else {
|
|
2028
2182
|
if (normOp === "empty" && isStringLike) {
|
|
2029
2183
|
filters.$or = [
|
|
@@ -2097,39 +2251,100 @@ const bulkUpdaterService = ({ strapi }) => {
|
|
|
2097
2251
|
} else {
|
|
2098
2252
|
sortClause["createdAt"] = "desc";
|
|
2099
2253
|
}
|
|
2100
|
-
|
|
2101
|
-
|
|
2102
|
-
|
|
2103
|
-
|
|
2104
|
-
|
|
2105
|
-
|
|
2106
|
-
|
|
2107
|
-
|
|
2108
|
-
}
|
|
2109
|
-
const [entries, totalEntries] = await Promise.all([
|
|
2110
|
-
strapi.documents(uid).findMany(findManyArgs),
|
|
2111
|
-
strapi.documents(uid).count({
|
|
2112
|
-
filters: Object.keys(filters).length > 0 ? filters : void 0
|
|
2113
|
-
})
|
|
2114
|
-
]);
|
|
2115
|
-
const totalPages = Math.ceil(totalEntries / limit);
|
|
2116
|
-
result = {
|
|
2117
|
-
uid,
|
|
2118
|
-
displayName: contentType.info?.displayName || uid,
|
|
2119
|
-
isSingleType: false,
|
|
2120
|
-
draftAndPublish: Boolean(contentType.options?.draftAndPublish),
|
|
2121
|
-
entries: (entries || []).map((entry) => ({
|
|
2122
|
-
id: entry.id,
|
|
2123
|
-
documentId: entry.documentId,
|
|
2124
|
-
...entry
|
|
2125
|
-
})),
|
|
2126
|
-
pagination: {
|
|
2127
|
-
page: currentPage,
|
|
2128
|
-
pageSize: limit,
|
|
2129
|
-
total: totalEntries,
|
|
2130
|
-
pageCount: totalPages
|
|
2254
|
+
if (isRootDz && normOp && normOp !== "none") {
|
|
2255
|
+
const findManyArgs = {
|
|
2256
|
+
limit: 500,
|
|
2257
|
+
filters: Object.keys(filters).length > 0 ? filters : void 0,
|
|
2258
|
+
sort: sortClause
|
|
2259
|
+
};
|
|
2260
|
+
if (populateOption) {
|
|
2261
|
+
findManyArgs.populate = populateOption;
|
|
2131
2262
|
}
|
|
2132
|
-
|
|
2263
|
+
const rawEntries = await strapi.documents(uid).findMany(findManyArgs);
|
|
2264
|
+
const qVal = (filterQuery || "").trim().toLowerCase();
|
|
2265
|
+
const passesDzFilter = (entry) => {
|
|
2266
|
+
const matches = getAllNestedValues(entry, targetFilterAttr);
|
|
2267
|
+
if (normOp === "empty") {
|
|
2268
|
+
return matches.length === 0 || matches.every((m) => m.value === void 0 || m.value === null || String(m.value).trim() === "");
|
|
2269
|
+
}
|
|
2270
|
+
if (normOp === "notempty") {
|
|
2271
|
+
return matches.some((m) => m.value !== void 0 && m.value !== null && String(m.value).trim() !== "");
|
|
2272
|
+
}
|
|
2273
|
+
return matches.some((m) => {
|
|
2274
|
+
if (m.value === void 0 || m.value === null) return false;
|
|
2275
|
+
const valStr = String(m.value).toLowerCase();
|
|
2276
|
+
switch (normOp) {
|
|
2277
|
+
case "equals":
|
|
2278
|
+
return valStr === qVal;
|
|
2279
|
+
case "notequals":
|
|
2280
|
+
return valStr !== qVal;
|
|
2281
|
+
case "contains":
|
|
2282
|
+
return valStr.includes(qVal);
|
|
2283
|
+
case "notcontains":
|
|
2284
|
+
return !valStr.includes(qVal);
|
|
2285
|
+
case "startswith":
|
|
2286
|
+
return valStr.startsWith(qVal);
|
|
2287
|
+
case "endswith":
|
|
2288
|
+
return valStr.endsWith(qVal);
|
|
2289
|
+
default:
|
|
2290
|
+
return true;
|
|
2291
|
+
}
|
|
2292
|
+
});
|
|
2293
|
+
};
|
|
2294
|
+
const matchedEntries = (rawEntries || []).filter(passesDzFilter);
|
|
2295
|
+
const totalEntries = matchedEntries.length;
|
|
2296
|
+
const paginatedEntries = matchedEntries.slice(start, start + limit);
|
|
2297
|
+
result = {
|
|
2298
|
+
uid,
|
|
2299
|
+
displayName: contentType.info?.displayName || uid,
|
|
2300
|
+
isSingleType: false,
|
|
2301
|
+
draftAndPublish: Boolean(contentType.options?.draftAndPublish),
|
|
2302
|
+
entries: paginatedEntries.map((entry) => ({
|
|
2303
|
+
id: entry.id,
|
|
2304
|
+
documentId: entry.documentId,
|
|
2305
|
+
...entry
|
|
2306
|
+
})),
|
|
2307
|
+
pagination: {
|
|
2308
|
+
page: currentPage,
|
|
2309
|
+
pageSize: limit,
|
|
2310
|
+
total: totalEntries,
|
|
2311
|
+
pageCount: Math.ceil(totalEntries / limit) || 1
|
|
2312
|
+
}
|
|
2313
|
+
};
|
|
2314
|
+
} else {
|
|
2315
|
+
const findManyArgs = {
|
|
2316
|
+
start,
|
|
2317
|
+
limit,
|
|
2318
|
+
filters: Object.keys(filters).length > 0 ? filters : void 0,
|
|
2319
|
+
sort: sortClause
|
|
2320
|
+
};
|
|
2321
|
+
if (populateOption) {
|
|
2322
|
+
findManyArgs.populate = populateOption;
|
|
2323
|
+
}
|
|
2324
|
+
const [entries, totalEntries] = await Promise.all([
|
|
2325
|
+
strapi.documents(uid).findMany(findManyArgs),
|
|
2326
|
+
strapi.documents(uid).count({
|
|
2327
|
+
filters: Object.keys(filters).length > 0 ? filters : void 0
|
|
2328
|
+
})
|
|
2329
|
+
]);
|
|
2330
|
+
result = {
|
|
2331
|
+
uid,
|
|
2332
|
+
displayName: contentType.info?.displayName || uid,
|
|
2333
|
+
isSingleType: false,
|
|
2334
|
+
draftAndPublish: Boolean(contentType.options?.draftAndPublish),
|
|
2335
|
+
entries: (entries || []).map((entry) => ({
|
|
2336
|
+
id: entry.id,
|
|
2337
|
+
documentId: entry.documentId,
|
|
2338
|
+
...entry
|
|
2339
|
+
})),
|
|
2340
|
+
pagination: {
|
|
2341
|
+
page: currentPage,
|
|
2342
|
+
pageSize: limit,
|
|
2343
|
+
total: totalEntries,
|
|
2344
|
+
pageCount: Math.ceil(totalEntries / limit) || 1
|
|
2345
|
+
}
|
|
2346
|
+
};
|
|
2347
|
+
}
|
|
2133
2348
|
}
|
|
2134
2349
|
if (queryCache.size >= MAX_QUERY_CACHE_SIZE) {
|
|
2135
2350
|
const toDelete = Array.from(queryCache.keys()).slice(0, 100);
|