strapi-plugin-bulk-updater 1.1.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -1
- package/dist/_chunks/{BulkUpdater-BSZP0U18.mjs → BulkUpdater-BDszahRM.mjs} +145 -87
- package/dist/_chunks/BulkUpdater-BDszahRM.mjs.map +1 -0
- package/dist/_chunks/{BulkUpdater-BRcMQGP3.js → BulkUpdater-DCrCPKSe.js} +143 -85
- package/dist/_chunks/BulkUpdater-DCrCPKSe.js.map +1 -0
- package/dist/admin/index.js +1 -1
- package/dist/admin/index.mjs +1 -1
- package/dist/server/index.js +319 -63
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +319 -63
- package/dist/server/index.mjs.map +1 -1
- package/package.json +1 -1
- package/dist/_chunks/BulkUpdater-BRcMQGP3.js.map +0 -1
- package/dist/_chunks/BulkUpdater-BSZP0U18.mjs.map +0 -1
package/dist/server/index.js
CHANGED
|
@@ -224,7 +224,7 @@ const bulkUpdaterController = ({ strapi: strapi2 }) => ({
|
|
|
224
224
|
return;
|
|
225
225
|
}
|
|
226
226
|
}
|
|
227
|
-
ctx.body = data;
|
|
227
|
+
ctx.body = { success: true, ...data };
|
|
228
228
|
} catch (err) {
|
|
229
229
|
ctx.status = 500;
|
|
230
230
|
ctx.body = { success: false, error: err.message };
|
|
@@ -673,9 +673,69 @@ async function executeBatchInternal(strapi2, {
|
|
|
673
673
|
try {
|
|
674
674
|
const currentEntry = await getDocumentDeduplicated(target.uid, target.documentId);
|
|
675
675
|
const entryLabel = currentEntry?.name || currentEntry?.title || currentEntry?.email || `Entry #${target.documentId}`;
|
|
676
|
+
const isNested = attribute.includes(".");
|
|
677
|
+
let isComponentNested = false;
|
|
678
|
+
let parentKey = "";
|
|
679
|
+
let childKey = "";
|
|
680
|
+
if (isNested) {
|
|
681
|
+
const parts = attribute.split(".");
|
|
682
|
+
parentKey = parts[0];
|
|
683
|
+
childKey = parts[1];
|
|
684
|
+
const parentAttrDef = contentType?.attributes?.[parentKey];
|
|
685
|
+
if (parentAttrDef?.type === "component" && !parentAttrDef.repeatable && parentAttrDef.component) {
|
|
686
|
+
const compSchema = strapi2.components[parentAttrDef.component];
|
|
687
|
+
if (compSchema?.attributes?.[childKey]) {
|
|
688
|
+
isComponentNested = true;
|
|
689
|
+
}
|
|
690
|
+
}
|
|
691
|
+
}
|
|
676
692
|
const attrDef = contentType?.attributes?.[attribute];
|
|
677
|
-
const hasAttribute = Boolean(attrDef);
|
|
693
|
+
const hasAttribute = Boolean(attrDef) || isComponentNested;
|
|
678
694
|
if (hasAttribute) {
|
|
695
|
+
if (isComponentNested) {
|
|
696
|
+
const currentEntryWithPopulate = await strapi2.documents(target.uid).findOne({
|
|
697
|
+
documentId: target.documentId,
|
|
698
|
+
populate: [parentKey]
|
|
699
|
+
});
|
|
700
|
+
const existingParent = currentEntryWithPopulate?.[parentKey] || {};
|
|
701
|
+
const currentVal2 = existingParent?.[childKey];
|
|
702
|
+
let newValue2 = value;
|
|
703
|
+
if (regexObj && typeof currentVal2 === "string") {
|
|
704
|
+
newValue2 = currentVal2.replace(regexObj, value);
|
|
705
|
+
}
|
|
706
|
+
const updatedParent = {
|
|
707
|
+
...existingParent,
|
|
708
|
+
[childKey]: newValue2
|
|
709
|
+
};
|
|
710
|
+
await strapi2.documents(target.uid).update({
|
|
711
|
+
documentId: target.documentId,
|
|
712
|
+
data: {
|
|
713
|
+
[parentKey]: updatedParent
|
|
714
|
+
}
|
|
715
|
+
});
|
|
716
|
+
const isDraftAndPublishComp = Boolean(contentType?.options?.draftAndPublish);
|
|
717
|
+
if (publishOnApproval && isDraftAndPublishComp) {
|
|
718
|
+
try {
|
|
719
|
+
await strapi2.documents(target.uid).publish({
|
|
720
|
+
documentId: target.documentId
|
|
721
|
+
});
|
|
722
|
+
} catch (publishErr) {
|
|
723
|
+
strapi2.log.warn(`[bulk-updater] Failed to auto-publish ${target.uid}/${target.documentId}:`, publishErr);
|
|
724
|
+
}
|
|
725
|
+
}
|
|
726
|
+
invalidateCollectionCache(target.uid);
|
|
727
|
+
return {
|
|
728
|
+
uid: target.uid,
|
|
729
|
+
collectionName: displayName,
|
|
730
|
+
documentId: target.documentId,
|
|
731
|
+
label: entryLabel,
|
|
732
|
+
attribute,
|
|
733
|
+
oldValue: currentVal2 ?? null,
|
|
734
|
+
newValue: newValue2,
|
|
735
|
+
status: "updated",
|
|
736
|
+
message: `Successfully updated nested field ${attribute}`
|
|
737
|
+
};
|
|
738
|
+
}
|
|
679
739
|
if (attrDef.type === "relation") {
|
|
680
740
|
const isMulti = attrDef.relation === "oneToMany" || attrDef.relation === "manyToMany";
|
|
681
741
|
const currentEntryWithPopulate = await strapi2.documents(target.uid).findOne({
|
|
@@ -917,9 +977,24 @@ const bulkUpdaterService = ({ strapi: strapi2 }) => {
|
|
|
917
977
|
const isSingleType = contentType.kind === "singleType";
|
|
918
978
|
const rawAttrs = contentType.attributes || {};
|
|
919
979
|
const relationsByAttr = {};
|
|
980
|
+
const nestedComponentAttrs = [];
|
|
920
981
|
const validAttrs = Object.keys(rawAttrs).filter((attrKey) => {
|
|
921
982
|
if (systemFields.includes(attrKey)) return false;
|
|
922
|
-
if (rawAttrs[attrKey].type === "
|
|
983
|
+
if (rawAttrs[attrKey].type === "dynamiczone") return false;
|
|
984
|
+
if (rawAttrs[attrKey].type === "component") {
|
|
985
|
+
const compDef = rawAttrs[attrKey];
|
|
986
|
+
if (!compDef.repeatable && compDef.component) {
|
|
987
|
+
const componentSchema = strapi2.components[compDef.component];
|
|
988
|
+
if (componentSchema && componentSchema.attributes) {
|
|
989
|
+
for (const [subKey, subAttr] of Object.entries(componentSchema.attributes)) {
|
|
990
|
+
if (systemFields.includes(subKey)) continue;
|
|
991
|
+
if (["component", "dynamiczone", "relation"].includes(subAttr.type)) continue;
|
|
992
|
+
nestedComponentAttrs.push(`${attrKey}.${subKey}`);
|
|
993
|
+
}
|
|
994
|
+
}
|
|
995
|
+
}
|
|
996
|
+
return false;
|
|
997
|
+
}
|
|
923
998
|
if (rawAttrs[attrKey].type === "relation") {
|
|
924
999
|
const rel = rawAttrs[attrKey];
|
|
925
1000
|
const targetUid = rel.target;
|
|
@@ -939,7 +1014,8 @@ const bulkUpdaterService = ({ strapi: strapi2 }) => {
|
|
|
939
1014
|
}
|
|
940
1015
|
return true;
|
|
941
1016
|
});
|
|
942
|
-
validAttrs
|
|
1017
|
+
const allColAttrs = [...validAttrs, ...nestedComponentAttrs];
|
|
1018
|
+
allColAttrs.forEach((attr) => allAttributesSet.add(attr));
|
|
943
1019
|
metaByUid[uid] = {
|
|
944
1020
|
uid,
|
|
945
1021
|
kind: contentType.kind,
|
|
@@ -947,7 +1023,7 @@ const bulkUpdaterService = ({ strapi: strapi2 }) => {
|
|
|
947
1023
|
singularName: contentType.info?.singularName || uid,
|
|
948
1024
|
pluralName: contentType.info?.pluralName || uid,
|
|
949
1025
|
displayName: contentType.info?.displayName || uid,
|
|
950
|
-
attributes:
|
|
1026
|
+
attributes: allColAttrs,
|
|
951
1027
|
relations: relationsByAttr
|
|
952
1028
|
};
|
|
953
1029
|
}
|
|
@@ -976,8 +1052,17 @@ const bulkUpdaterService = ({ strapi: strapi2 }) => {
|
|
|
976
1052
|
let entries = [];
|
|
977
1053
|
let totalCount = 0;
|
|
978
1054
|
try {
|
|
1055
|
+
const ctAttrs = allContentTypes[uid]?.attributes || {};
|
|
979
1056
|
const relKeys = Object.keys(meta.relations || {});
|
|
980
|
-
const
|
|
1057
|
+
const compKeys = Object.keys(ctAttrs).filter((k) => ctAttrs[k].type === "component");
|
|
1058
|
+
const populateOptionObj = {};
|
|
1059
|
+
relKeys.forEach((k) => {
|
|
1060
|
+
populateOptionObj[k] = true;
|
|
1061
|
+
});
|
|
1062
|
+
compKeys.forEach((k) => {
|
|
1063
|
+
populateOptionObj[k] = true;
|
|
1064
|
+
});
|
|
1065
|
+
const populateOption = Object.keys(populateOptionObj).length > 0 ? populateOptionObj : void 0;
|
|
981
1066
|
if (meta.isSingleType) {
|
|
982
1067
|
const singleDoc = await strapi2.documents(uid).findFirst({
|
|
983
1068
|
populate: populateOption
|
|
@@ -1055,7 +1140,7 @@ const bulkUpdaterService = ({ strapi: strapi2 }) => {
|
|
|
1055
1140
|
if (!contentType) {
|
|
1056
1141
|
throw new Error(`Collection with UID "${uid}" does not exist.`);
|
|
1057
1142
|
}
|
|
1058
|
-
const limit = Math.min(Math.max(Number(pageSize) || 10, 1),
|
|
1143
|
+
const limit = Math.min(Math.max(Number(pageSize) || 10, 1), 500);
|
|
1059
1144
|
const currentPage = Math.max(Number(page) || 1, 1);
|
|
1060
1145
|
const start = (currentPage - 1) * limit;
|
|
1061
1146
|
const isSingleType = contentType.kind === "singleType";
|
|
@@ -1071,8 +1156,118 @@ const bulkUpdaterService = ({ strapi: strapi2 }) => {
|
|
|
1071
1156
|
};
|
|
1072
1157
|
}
|
|
1073
1158
|
let result;
|
|
1159
|
+
const filters2 = {};
|
|
1160
|
+
const attrs = contentType.attributes || {};
|
|
1161
|
+
let colHasAttribute = false;
|
|
1162
|
+
let isNestedAttr = false;
|
|
1163
|
+
let parentKey = "";
|
|
1164
|
+
let childKey = "";
|
|
1165
|
+
if (attribute) {
|
|
1166
|
+
if (attribute.includes(".")) {
|
|
1167
|
+
[parentKey, childKey] = attribute.split(".");
|
|
1168
|
+
if (attrs[parentKey]?.type === "component" && !attrs[parentKey].repeatable && attrs[parentKey].component) {
|
|
1169
|
+
const compSchema = strapi2.components[attrs[parentKey].component];
|
|
1170
|
+
if (compSchema?.attributes?.[childKey]) {
|
|
1171
|
+
colHasAttribute = true;
|
|
1172
|
+
isNestedAttr = true;
|
|
1173
|
+
}
|
|
1174
|
+
}
|
|
1175
|
+
} else if (attrs[attribute]) {
|
|
1176
|
+
colHasAttribute = true;
|
|
1177
|
+
}
|
|
1178
|
+
}
|
|
1179
|
+
const normOp = (filterOperator || "").toLowerCase().replace(/_/g, "");
|
|
1180
|
+
if (normOp && normOp !== "none") {
|
|
1181
|
+
if (!colHasAttribute) {
|
|
1182
|
+
result = {
|
|
1183
|
+
uid,
|
|
1184
|
+
displayName: contentType.info?.displayName || uid,
|
|
1185
|
+
isSingleType,
|
|
1186
|
+
entries: [],
|
|
1187
|
+
pagination: {
|
|
1188
|
+
page: 1,
|
|
1189
|
+
pageSize: limit,
|
|
1190
|
+
total: 0,
|
|
1191
|
+
pageCount: 0
|
|
1192
|
+
}
|
|
1193
|
+
};
|
|
1194
|
+
queryCache.set(cacheKey, { signature, data: result, timestamp: Date.now() });
|
|
1195
|
+
return { ...result, cached: false, etag };
|
|
1196
|
+
}
|
|
1197
|
+
let condition = void 0;
|
|
1198
|
+
const q = (filterQuery || "").trim();
|
|
1199
|
+
if (normOp === "empty") {
|
|
1200
|
+
condition = { $or: [{ $null: true }, { $eq: "" }] };
|
|
1201
|
+
} else if (normOp === "notempty") {
|
|
1202
|
+
condition = { $and: [{ $notNull: true }, { $ne: "" }] };
|
|
1203
|
+
} else if (q !== "") {
|
|
1204
|
+
switch (normOp) {
|
|
1205
|
+
case "equals":
|
|
1206
|
+
condition = { $containsi: q };
|
|
1207
|
+
break;
|
|
1208
|
+
case "notequals":
|
|
1209
|
+
condition = { $notContainsi: q };
|
|
1210
|
+
break;
|
|
1211
|
+
case "contains":
|
|
1212
|
+
condition = { $containsi: q };
|
|
1213
|
+
break;
|
|
1214
|
+
case "notcontains":
|
|
1215
|
+
condition = { $notContainsi: q };
|
|
1216
|
+
break;
|
|
1217
|
+
case "startswith":
|
|
1218
|
+
condition = { $startsWith: q };
|
|
1219
|
+
break;
|
|
1220
|
+
case "endswith":
|
|
1221
|
+
condition = { $endsWith: q };
|
|
1222
|
+
break;
|
|
1223
|
+
}
|
|
1224
|
+
}
|
|
1225
|
+
if (condition !== void 0) {
|
|
1226
|
+
if (isNestedAttr) {
|
|
1227
|
+
filters2[parentKey] = {
|
|
1228
|
+
[childKey]: condition
|
|
1229
|
+
};
|
|
1230
|
+
} else {
|
|
1231
|
+
if (normOp === "empty") {
|
|
1232
|
+
filters2.$or = [
|
|
1233
|
+
{ [attribute]: { $null: true } },
|
|
1234
|
+
{ [attribute]: { $eq: "" } }
|
|
1235
|
+
];
|
|
1236
|
+
} else if (normOp === "notempty") {
|
|
1237
|
+
filters2[attribute] = { $notNull: true, $ne: "" };
|
|
1238
|
+
} else {
|
|
1239
|
+
filters2[attribute] = condition;
|
|
1240
|
+
}
|
|
1241
|
+
}
|
|
1242
|
+
}
|
|
1243
|
+
}
|
|
1244
|
+
if (search && search.trim() !== "") {
|
|
1245
|
+
const q = search.trim();
|
|
1246
|
+
const searchableAttrs = Object.keys(attrs).filter(
|
|
1247
|
+
(k) => ["string", "text", "email", "uid"].includes(attrs[k]?.type)
|
|
1248
|
+
);
|
|
1249
|
+
if (searchableAttrs.length > 0) {
|
|
1250
|
+
const orList = searchableAttrs.slice(0, 6).map((k) => ({
|
|
1251
|
+
[k]: { $containsi: q }
|
|
1252
|
+
}));
|
|
1253
|
+
if (Object.keys(filters2).length > 0) {
|
|
1254
|
+
const existingFilters = { ...filters2 };
|
|
1255
|
+
Object.keys(filters2).forEach((k) => delete filters2[k]);
|
|
1256
|
+
filters2.$and = [existingFilters, { $or: orList }];
|
|
1257
|
+
} else {
|
|
1258
|
+
filters2.$or = orList;
|
|
1259
|
+
}
|
|
1260
|
+
}
|
|
1261
|
+
}
|
|
1074
1262
|
if (isSingleType) {
|
|
1075
|
-
|
|
1263
|
+
let singleDoc = null;
|
|
1264
|
+
try {
|
|
1265
|
+
singleDoc = await strapi2.documents(uid).findFirst({
|
|
1266
|
+
filters: Object.keys(filters2).length > 0 ? filters2 : void 0
|
|
1267
|
+
});
|
|
1268
|
+
} catch {
|
|
1269
|
+
singleDoc = null;
|
|
1270
|
+
}
|
|
1076
1271
|
result = {
|
|
1077
1272
|
uid,
|
|
1078
1273
|
displayName: contentType.info?.displayName || uid,
|
|
@@ -1086,55 +1281,23 @@ const bulkUpdaterService = ({ strapi: strapi2 }) => {
|
|
|
1086
1281
|
}
|
|
1087
1282
|
};
|
|
1088
1283
|
} else {
|
|
1089
|
-
const filters2 = {};
|
|
1090
|
-
if (attribute && filterOperator && filterQuery !== void 0 && filterQuery !== "") {
|
|
1091
|
-
switch (filterOperator) {
|
|
1092
|
-
case "equals":
|
|
1093
|
-
filters2[attribute] = { $eq: filterQuery };
|
|
1094
|
-
break;
|
|
1095
|
-
case "notEquals":
|
|
1096
|
-
filters2[attribute] = { $ne: filterQuery };
|
|
1097
|
-
break;
|
|
1098
|
-
case "contains":
|
|
1099
|
-
filters2[attribute] = { $containsi: filterQuery };
|
|
1100
|
-
break;
|
|
1101
|
-
case "notContains":
|
|
1102
|
-
filters2[attribute] = { $notContainsi: filterQuery };
|
|
1103
|
-
break;
|
|
1104
|
-
case "startsWith":
|
|
1105
|
-
filters2[attribute] = { $startsWith: filterQuery };
|
|
1106
|
-
break;
|
|
1107
|
-
case "endsWith":
|
|
1108
|
-
filters2[attribute] = { $endsWith: filterQuery };
|
|
1109
|
-
break;
|
|
1110
|
-
case "empty":
|
|
1111
|
-
filters2[attribute] = { $null: true };
|
|
1112
|
-
break;
|
|
1113
|
-
case "notEmpty":
|
|
1114
|
-
filters2[attribute] = { $notNull: true };
|
|
1115
|
-
break;
|
|
1116
|
-
}
|
|
1117
|
-
}
|
|
1118
|
-
if (search && search.trim() !== "") {
|
|
1119
|
-
const stringAttrs = Object.keys(contentType.attributes || {}).filter(
|
|
1120
|
-
(k) => contentType.attributes[k].type === "string" || contentType.attributes[k].type === "text" || contentType.attributes[k].type === "email"
|
|
1121
|
-
);
|
|
1122
|
-
if (stringAttrs.length > 0) {
|
|
1123
|
-
filters2.$or = stringAttrs.slice(0, 5).map((attr) => ({
|
|
1124
|
-
[attr]: { $containsi: search.trim() }
|
|
1125
|
-
}));
|
|
1126
|
-
}
|
|
1127
|
-
}
|
|
1128
1284
|
const sortClause = {};
|
|
1129
|
-
if (sortField &&
|
|
1285
|
+
if (sortField && sortField.includes(".")) {
|
|
1286
|
+
const [parent, child] = sortField.split(".");
|
|
1287
|
+
if (contentType.attributes?.[parent]?.type === "component") {
|
|
1288
|
+
sortClause[parent] = { [child]: sortOrder };
|
|
1289
|
+
} else {
|
|
1290
|
+
sortClause["createdAt"] = "desc";
|
|
1291
|
+
}
|
|
1292
|
+
} else if (sortField && contentType.attributes?.[sortField]) {
|
|
1130
1293
|
sortClause[sortField] = sortOrder;
|
|
1131
1294
|
} else {
|
|
1132
1295
|
sortClause["createdAt"] = "desc";
|
|
1133
1296
|
}
|
|
1134
|
-
const
|
|
1135
|
-
(k) => contentType.attributes[k].type === "relation"
|
|
1297
|
+
const populateAttrs = Object.keys(contentType.attributes || {}).filter(
|
|
1298
|
+
(k) => contentType.attributes[k].type === "relation" || contentType.attributes[k].type === "component"
|
|
1136
1299
|
);
|
|
1137
|
-
const populateOption =
|
|
1300
|
+
const populateOption = populateAttrs.length > 0 ? populateAttrs.reduce((acc, k) => ({ ...acc, [k]: true }), {}) : void 0;
|
|
1138
1301
|
const [entries, totalEntries] = await Promise.all([
|
|
1139
1302
|
strapi2.documents(uid).findMany({
|
|
1140
1303
|
start,
|
|
@@ -1473,6 +1636,9 @@ const bulkUpdaterService = ({ strapi: strapi2 }) => {
|
|
|
1473
1636
|
modelsCache.clear();
|
|
1474
1637
|
staticSchemaCache = null;
|
|
1475
1638
|
}
|
|
1639
|
+
},
|
|
1640
|
+
invalidateCollectionCache(uid) {
|
|
1641
|
+
invalidateCollectionCache(uid);
|
|
1476
1642
|
}
|
|
1477
1643
|
};
|
|
1478
1644
|
};
|
|
@@ -1734,12 +1900,41 @@ const auditService = ({ strapi: strapi2 }) => ({
|
|
|
1734
1900
|
} else {
|
|
1735
1901
|
rollbackPayload = item.oldValue;
|
|
1736
1902
|
}
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1903
|
+
if (item.attribute.includes(".")) {
|
|
1904
|
+
const [parentKey, childKey] = item.attribute.split(".");
|
|
1905
|
+
const ct2 = strapi2.contentTypes[item.uid];
|
|
1906
|
+
if (ct2?.attributes?.[parentKey]?.type === "component") {
|
|
1907
|
+
const currentDoc = await strapi2.documents(item.uid).findOne({
|
|
1908
|
+
documentId: item.documentId,
|
|
1909
|
+
populate: [parentKey]
|
|
1910
|
+
});
|
|
1911
|
+
const currentParent = currentDoc?.[parentKey] || {};
|
|
1912
|
+
const restoredParent = {
|
|
1913
|
+
...currentParent,
|
|
1914
|
+
[childKey]: rollbackPayload
|
|
1915
|
+
};
|
|
1916
|
+
await strapi2.documents(item.uid).update({
|
|
1917
|
+
documentId: item.documentId,
|
|
1918
|
+
data: {
|
|
1919
|
+
[parentKey]: restoredParent
|
|
1920
|
+
}
|
|
1921
|
+
});
|
|
1922
|
+
} else {
|
|
1923
|
+
await strapi2.documents(item.uid).update({
|
|
1924
|
+
documentId: item.documentId,
|
|
1925
|
+
data: {
|
|
1926
|
+
[item.attribute]: rollbackPayload
|
|
1927
|
+
}
|
|
1928
|
+
});
|
|
1741
1929
|
}
|
|
1742
|
-
}
|
|
1930
|
+
} else {
|
|
1931
|
+
await strapi2.documents(item.uid).update({
|
|
1932
|
+
documentId: item.documentId,
|
|
1933
|
+
data: {
|
|
1934
|
+
[item.attribute]: rollbackPayload
|
|
1935
|
+
}
|
|
1936
|
+
});
|
|
1937
|
+
}
|
|
1743
1938
|
const ct = strapi2.contentTypes[item.uid];
|
|
1744
1939
|
if (ct?.options?.draftAndPublish) {
|
|
1745
1940
|
try {
|
|
@@ -1750,7 +1945,10 @@ const auditService = ({ strapi: strapi2 }) => ({
|
|
|
1750
1945
|
}
|
|
1751
1946
|
}
|
|
1752
1947
|
try {
|
|
1753
|
-
strapi2.plugin("bulk-updater").service("bulkUpdater")
|
|
1948
|
+
const bulkService = strapi2.plugin("bulk-updater").service("bulkUpdater");
|
|
1949
|
+
if (bulkService?.invalidateCache) {
|
|
1950
|
+
bulkService.invalidateCache(item.uid);
|
|
1951
|
+
}
|
|
1754
1952
|
} catch {
|
|
1755
1953
|
}
|
|
1756
1954
|
revertedCount++;
|
|
@@ -2130,10 +2328,24 @@ ${sampleRow.map(escapeCsvValue).join(",")}
|
|
|
2130
2328
|
const attrs = ct.attributes || {};
|
|
2131
2329
|
const excluded = ["createdBy", "updatedBy", "localizations"];
|
|
2132
2330
|
const exportFields = ["documentId"];
|
|
2331
|
+
const compFieldsToPopulate = [];
|
|
2133
2332
|
for (const [attrName, attrDef] of Object.entries(attrs)) {
|
|
2134
2333
|
if (excluded.includes(attrName)) continue;
|
|
2135
|
-
if (["
|
|
2136
|
-
if (attrDef.type === "
|
|
2334
|
+
if (["dynamiczone", "media", "relation"].includes(attrDef.type)) continue;
|
|
2335
|
+
if (attrDef.type === "component") {
|
|
2336
|
+
if (!attrDef.repeatable && attrDef.component) {
|
|
2337
|
+
const comp = strapi2.components[attrDef.component];
|
|
2338
|
+
if (comp?.attributes) {
|
|
2339
|
+
compFieldsToPopulate.push(attrName);
|
|
2340
|
+
for (const [subKey, subDef] of Object.entries(comp.attributes)) {
|
|
2341
|
+
if (excluded.includes(subKey)) continue;
|
|
2342
|
+
if (["component", "dynamiczone", "media", "relation"].includes(subDef.type)) continue;
|
|
2343
|
+
exportFields.push(`${attrName}.${subKey}`);
|
|
2344
|
+
}
|
|
2345
|
+
}
|
|
2346
|
+
}
|
|
2347
|
+
continue;
|
|
2348
|
+
}
|
|
2137
2349
|
exportFields.push(attrName);
|
|
2138
2350
|
}
|
|
2139
2351
|
const filters2 = {};
|
|
@@ -2177,16 +2389,25 @@ ${sampleRow.map(escapeCsvValue).join(",")}
|
|
|
2177
2389
|
}
|
|
2178
2390
|
}
|
|
2179
2391
|
}
|
|
2392
|
+
const populateOption = compFieldsToPopulate.length > 0 ? compFieldsToPopulate.reduce((acc, k) => ({ ...acc, [k]: true }), {}) : void 0;
|
|
2180
2393
|
const entries = await strapi2.documents(uid).findMany({
|
|
2181
2394
|
filters: Object.keys(filters2).length > 0 ? filters2 : void 0,
|
|
2182
2395
|
limit: options.limit || 5e3,
|
|
2183
|
-
sort: { createdAt: "desc" }
|
|
2396
|
+
sort: { createdAt: "desc" },
|
|
2397
|
+
populate: populateOption
|
|
2184
2398
|
});
|
|
2185
2399
|
const lines = [];
|
|
2186
2400
|
lines.push(exportFields.map(escapeCsvValue).join(","));
|
|
2187
2401
|
for (const entry of entries || []) {
|
|
2188
2402
|
const rowValues = exportFields.map((field) => {
|
|
2189
|
-
|
|
2403
|
+
let val;
|
|
2404
|
+
if (field.includes(".")) {
|
|
2405
|
+
const [parent, child] = field.split(".");
|
|
2406
|
+
val = entry[parent]?.[child];
|
|
2407
|
+
} else {
|
|
2408
|
+
val = entry[field];
|
|
2409
|
+
}
|
|
2410
|
+
return escapeCsvValue(val);
|
|
2190
2411
|
});
|
|
2191
2412
|
lines.push(rowValues.join(","));
|
|
2192
2413
|
}
|
|
@@ -2272,6 +2493,29 @@ ${sampleRow.map(escapeCsvValue).join(",")}
|
|
|
2272
2493
|
const payload = {};
|
|
2273
2494
|
for (const [key, rawVal] of Object.entries(row)) {
|
|
2274
2495
|
if (key === "documentId" || key === "id") continue;
|
|
2496
|
+
if (key.includes(".")) {
|
|
2497
|
+
const [parent, child] = key.split(".");
|
|
2498
|
+
const parentDef = attrs[parent];
|
|
2499
|
+
if (parentDef?.type === "component" && !parentDef.repeatable && parentDef.component) {
|
|
2500
|
+
const comp = strapi2.components[parentDef.component];
|
|
2501
|
+
const childDef = comp?.attributes?.[child];
|
|
2502
|
+
if (childDef) {
|
|
2503
|
+
if (!payload[parent]) payload[parent] = {};
|
|
2504
|
+
let val = rawVal;
|
|
2505
|
+
if (rawVal === "" || rawVal === null || rawVal === void 0) {
|
|
2506
|
+
val = null;
|
|
2507
|
+
} else if (childDef.type === "integer" || childDef.type === "biginteger") {
|
|
2508
|
+
val = parseInt(rawVal, 10);
|
|
2509
|
+
} else if (childDef.type === "float" || childDef.type === "decimal") {
|
|
2510
|
+
val = parseFloat(rawVal);
|
|
2511
|
+
} else if (childDef.type === "boolean") {
|
|
2512
|
+
val = rawVal.toLowerCase() === "true" || rawVal === "1";
|
|
2513
|
+
}
|
|
2514
|
+
payload[parent][child] = val;
|
|
2515
|
+
}
|
|
2516
|
+
}
|
|
2517
|
+
continue;
|
|
2518
|
+
}
|
|
2275
2519
|
const attrDef = attrs[key];
|
|
2276
2520
|
if (!attrDef) continue;
|
|
2277
2521
|
if (rawVal === "" || rawVal === null || rawVal === void 0) {
|
|
@@ -2323,9 +2567,15 @@ ${sampleRow.map(escapeCsvValue).join(",")}
|
|
|
2323
2567
|
});
|
|
2324
2568
|
continue;
|
|
2325
2569
|
}
|
|
2570
|
+
const mergedPayload = { ...payload };
|
|
2571
|
+
for (const key of Object.keys(payload)) {
|
|
2572
|
+
if (attrs[key]?.type === "component" && typeof payload[key] === "object" && payload[key] !== null) {
|
|
2573
|
+
mergedPayload[key] = { ...existing[key] || {}, ...payload[key] };
|
|
2574
|
+
}
|
|
2575
|
+
}
|
|
2326
2576
|
await strapi2.documents(uid).update({
|
|
2327
2577
|
documentId: docId,
|
|
2328
|
-
data:
|
|
2578
|
+
data: mergedPayload
|
|
2329
2579
|
});
|
|
2330
2580
|
if (publish && ct.options?.draftAndPublish) {
|
|
2331
2581
|
try {
|
|
@@ -2352,9 +2602,15 @@ ${sampleRow.map(escapeCsvValue).join(",")}
|
|
|
2352
2602
|
documentId: docId
|
|
2353
2603
|
});
|
|
2354
2604
|
if (existing) {
|
|
2605
|
+
const mergedPayload = { ...payload };
|
|
2606
|
+
for (const key of Object.keys(payload)) {
|
|
2607
|
+
if (attrs[key]?.type === "component" && typeof payload[key] === "object" && payload[key] !== null) {
|
|
2608
|
+
mergedPayload[key] = { ...existing[key] || {}, ...payload[key] };
|
|
2609
|
+
}
|
|
2610
|
+
}
|
|
2355
2611
|
await strapi2.documents(uid).update({
|
|
2356
2612
|
documentId: docId,
|
|
2357
|
-
data:
|
|
2613
|
+
data: mergedPayload
|
|
2358
2614
|
});
|
|
2359
2615
|
if (publish && ct.options?.draftAndPublish) {
|
|
2360
2616
|
try {
|