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.mjs
CHANGED
|
@@ -211,7 +211,7 @@ const bulkUpdaterController = ({ strapi: strapi2 }) => ({
|
|
|
211
211
|
return;
|
|
212
212
|
}
|
|
213
213
|
}
|
|
214
|
-
ctx.body = data;
|
|
214
|
+
ctx.body = { success: true, ...data };
|
|
215
215
|
} catch (err) {
|
|
216
216
|
ctx.status = 500;
|
|
217
217
|
ctx.body = { success: false, error: err.message };
|
|
@@ -660,9 +660,69 @@ async function executeBatchInternal(strapi2, {
|
|
|
660
660
|
try {
|
|
661
661
|
const currentEntry = await getDocumentDeduplicated(target.uid, target.documentId);
|
|
662
662
|
const entryLabel = currentEntry?.name || currentEntry?.title || currentEntry?.email || `Entry #${target.documentId}`;
|
|
663
|
+
const isNested = attribute.includes(".");
|
|
664
|
+
let isComponentNested = false;
|
|
665
|
+
let parentKey = "";
|
|
666
|
+
let childKey = "";
|
|
667
|
+
if (isNested) {
|
|
668
|
+
const parts = attribute.split(".");
|
|
669
|
+
parentKey = parts[0];
|
|
670
|
+
childKey = parts[1];
|
|
671
|
+
const parentAttrDef = contentType?.attributes?.[parentKey];
|
|
672
|
+
if (parentAttrDef?.type === "component" && !parentAttrDef.repeatable && parentAttrDef.component) {
|
|
673
|
+
const compSchema = strapi2.components[parentAttrDef.component];
|
|
674
|
+
if (compSchema?.attributes?.[childKey]) {
|
|
675
|
+
isComponentNested = true;
|
|
676
|
+
}
|
|
677
|
+
}
|
|
678
|
+
}
|
|
663
679
|
const attrDef = contentType?.attributes?.[attribute];
|
|
664
|
-
const hasAttribute = Boolean(attrDef);
|
|
680
|
+
const hasAttribute = Boolean(attrDef) || isComponentNested;
|
|
665
681
|
if (hasAttribute) {
|
|
682
|
+
if (isComponentNested) {
|
|
683
|
+
const currentEntryWithPopulate = await strapi2.documents(target.uid).findOne({
|
|
684
|
+
documentId: target.documentId,
|
|
685
|
+
populate: [parentKey]
|
|
686
|
+
});
|
|
687
|
+
const existingParent = currentEntryWithPopulate?.[parentKey] || {};
|
|
688
|
+
const currentVal2 = existingParent?.[childKey];
|
|
689
|
+
let newValue2 = value;
|
|
690
|
+
if (regexObj && typeof currentVal2 === "string") {
|
|
691
|
+
newValue2 = currentVal2.replace(regexObj, value);
|
|
692
|
+
}
|
|
693
|
+
const updatedParent = {
|
|
694
|
+
...existingParent,
|
|
695
|
+
[childKey]: newValue2
|
|
696
|
+
};
|
|
697
|
+
await strapi2.documents(target.uid).update({
|
|
698
|
+
documentId: target.documentId,
|
|
699
|
+
data: {
|
|
700
|
+
[parentKey]: updatedParent
|
|
701
|
+
}
|
|
702
|
+
});
|
|
703
|
+
const isDraftAndPublishComp = Boolean(contentType?.options?.draftAndPublish);
|
|
704
|
+
if (publishOnApproval && isDraftAndPublishComp) {
|
|
705
|
+
try {
|
|
706
|
+
await strapi2.documents(target.uid).publish({
|
|
707
|
+
documentId: target.documentId
|
|
708
|
+
});
|
|
709
|
+
} catch (publishErr) {
|
|
710
|
+
strapi2.log.warn(`[bulk-updater] Failed to auto-publish ${target.uid}/${target.documentId}:`, publishErr);
|
|
711
|
+
}
|
|
712
|
+
}
|
|
713
|
+
invalidateCollectionCache(target.uid);
|
|
714
|
+
return {
|
|
715
|
+
uid: target.uid,
|
|
716
|
+
collectionName: displayName,
|
|
717
|
+
documentId: target.documentId,
|
|
718
|
+
label: entryLabel,
|
|
719
|
+
attribute,
|
|
720
|
+
oldValue: currentVal2 ?? null,
|
|
721
|
+
newValue: newValue2,
|
|
722
|
+
status: "updated",
|
|
723
|
+
message: `Successfully updated nested field ${attribute}`
|
|
724
|
+
};
|
|
725
|
+
}
|
|
666
726
|
if (attrDef.type === "relation") {
|
|
667
727
|
const isMulti = attrDef.relation === "oneToMany" || attrDef.relation === "manyToMany";
|
|
668
728
|
const currentEntryWithPopulate = await strapi2.documents(target.uid).findOne({
|
|
@@ -904,9 +964,24 @@ const bulkUpdaterService = ({ strapi: strapi2 }) => {
|
|
|
904
964
|
const isSingleType = contentType.kind === "singleType";
|
|
905
965
|
const rawAttrs = contentType.attributes || {};
|
|
906
966
|
const relationsByAttr = {};
|
|
967
|
+
const nestedComponentAttrs = [];
|
|
907
968
|
const validAttrs = Object.keys(rawAttrs).filter((attrKey) => {
|
|
908
969
|
if (systemFields.includes(attrKey)) return false;
|
|
909
|
-
if (rawAttrs[attrKey].type === "
|
|
970
|
+
if (rawAttrs[attrKey].type === "dynamiczone") return false;
|
|
971
|
+
if (rawAttrs[attrKey].type === "component") {
|
|
972
|
+
const compDef = rawAttrs[attrKey];
|
|
973
|
+
if (!compDef.repeatable && compDef.component) {
|
|
974
|
+
const componentSchema = strapi2.components[compDef.component];
|
|
975
|
+
if (componentSchema && componentSchema.attributes) {
|
|
976
|
+
for (const [subKey, subAttr] of Object.entries(componentSchema.attributes)) {
|
|
977
|
+
if (systemFields.includes(subKey)) continue;
|
|
978
|
+
if (["component", "dynamiczone", "relation"].includes(subAttr.type)) continue;
|
|
979
|
+
nestedComponentAttrs.push(`${attrKey}.${subKey}`);
|
|
980
|
+
}
|
|
981
|
+
}
|
|
982
|
+
}
|
|
983
|
+
return false;
|
|
984
|
+
}
|
|
910
985
|
if (rawAttrs[attrKey].type === "relation") {
|
|
911
986
|
const rel = rawAttrs[attrKey];
|
|
912
987
|
const targetUid = rel.target;
|
|
@@ -926,7 +1001,8 @@ const bulkUpdaterService = ({ strapi: strapi2 }) => {
|
|
|
926
1001
|
}
|
|
927
1002
|
return true;
|
|
928
1003
|
});
|
|
929
|
-
validAttrs
|
|
1004
|
+
const allColAttrs = [...validAttrs, ...nestedComponentAttrs];
|
|
1005
|
+
allColAttrs.forEach((attr) => allAttributesSet.add(attr));
|
|
930
1006
|
metaByUid[uid] = {
|
|
931
1007
|
uid,
|
|
932
1008
|
kind: contentType.kind,
|
|
@@ -934,7 +1010,7 @@ const bulkUpdaterService = ({ strapi: strapi2 }) => {
|
|
|
934
1010
|
singularName: contentType.info?.singularName || uid,
|
|
935
1011
|
pluralName: contentType.info?.pluralName || uid,
|
|
936
1012
|
displayName: contentType.info?.displayName || uid,
|
|
937
|
-
attributes:
|
|
1013
|
+
attributes: allColAttrs,
|
|
938
1014
|
relations: relationsByAttr
|
|
939
1015
|
};
|
|
940
1016
|
}
|
|
@@ -963,8 +1039,17 @@ const bulkUpdaterService = ({ strapi: strapi2 }) => {
|
|
|
963
1039
|
let entries = [];
|
|
964
1040
|
let totalCount = 0;
|
|
965
1041
|
try {
|
|
1042
|
+
const ctAttrs = allContentTypes[uid]?.attributes || {};
|
|
966
1043
|
const relKeys = Object.keys(meta.relations || {});
|
|
967
|
-
const
|
|
1044
|
+
const compKeys = Object.keys(ctAttrs).filter((k) => ctAttrs[k].type === "component");
|
|
1045
|
+
const populateOptionObj = {};
|
|
1046
|
+
relKeys.forEach((k) => {
|
|
1047
|
+
populateOptionObj[k] = true;
|
|
1048
|
+
});
|
|
1049
|
+
compKeys.forEach((k) => {
|
|
1050
|
+
populateOptionObj[k] = true;
|
|
1051
|
+
});
|
|
1052
|
+
const populateOption = Object.keys(populateOptionObj).length > 0 ? populateOptionObj : void 0;
|
|
968
1053
|
if (meta.isSingleType) {
|
|
969
1054
|
const singleDoc = await strapi2.documents(uid).findFirst({
|
|
970
1055
|
populate: populateOption
|
|
@@ -1042,7 +1127,7 @@ const bulkUpdaterService = ({ strapi: strapi2 }) => {
|
|
|
1042
1127
|
if (!contentType) {
|
|
1043
1128
|
throw new Error(`Collection with UID "${uid}" does not exist.`);
|
|
1044
1129
|
}
|
|
1045
|
-
const limit = Math.min(Math.max(Number(pageSize) || 10, 1),
|
|
1130
|
+
const limit = Math.min(Math.max(Number(pageSize) || 10, 1), 500);
|
|
1046
1131
|
const currentPage = Math.max(Number(page) || 1, 1);
|
|
1047
1132
|
const start = (currentPage - 1) * limit;
|
|
1048
1133
|
const isSingleType = contentType.kind === "singleType";
|
|
@@ -1058,8 +1143,118 @@ const bulkUpdaterService = ({ strapi: strapi2 }) => {
|
|
|
1058
1143
|
};
|
|
1059
1144
|
}
|
|
1060
1145
|
let result;
|
|
1146
|
+
const filters2 = {};
|
|
1147
|
+
const attrs = contentType.attributes || {};
|
|
1148
|
+
let colHasAttribute = false;
|
|
1149
|
+
let isNestedAttr = false;
|
|
1150
|
+
let parentKey = "";
|
|
1151
|
+
let childKey = "";
|
|
1152
|
+
if (attribute) {
|
|
1153
|
+
if (attribute.includes(".")) {
|
|
1154
|
+
[parentKey, childKey] = attribute.split(".");
|
|
1155
|
+
if (attrs[parentKey]?.type === "component" && !attrs[parentKey].repeatable && attrs[parentKey].component) {
|
|
1156
|
+
const compSchema = strapi2.components[attrs[parentKey].component];
|
|
1157
|
+
if (compSchema?.attributes?.[childKey]) {
|
|
1158
|
+
colHasAttribute = true;
|
|
1159
|
+
isNestedAttr = true;
|
|
1160
|
+
}
|
|
1161
|
+
}
|
|
1162
|
+
} else if (attrs[attribute]) {
|
|
1163
|
+
colHasAttribute = true;
|
|
1164
|
+
}
|
|
1165
|
+
}
|
|
1166
|
+
const normOp = (filterOperator || "").toLowerCase().replace(/_/g, "");
|
|
1167
|
+
if (normOp && normOp !== "none") {
|
|
1168
|
+
if (!colHasAttribute) {
|
|
1169
|
+
result = {
|
|
1170
|
+
uid,
|
|
1171
|
+
displayName: contentType.info?.displayName || uid,
|
|
1172
|
+
isSingleType,
|
|
1173
|
+
entries: [],
|
|
1174
|
+
pagination: {
|
|
1175
|
+
page: 1,
|
|
1176
|
+
pageSize: limit,
|
|
1177
|
+
total: 0,
|
|
1178
|
+
pageCount: 0
|
|
1179
|
+
}
|
|
1180
|
+
};
|
|
1181
|
+
queryCache.set(cacheKey, { signature, data: result, timestamp: Date.now() });
|
|
1182
|
+
return { ...result, cached: false, etag };
|
|
1183
|
+
}
|
|
1184
|
+
let condition = void 0;
|
|
1185
|
+
const q = (filterQuery || "").trim();
|
|
1186
|
+
if (normOp === "empty") {
|
|
1187
|
+
condition = { $or: [{ $null: true }, { $eq: "" }] };
|
|
1188
|
+
} else if (normOp === "notempty") {
|
|
1189
|
+
condition = { $and: [{ $notNull: true }, { $ne: "" }] };
|
|
1190
|
+
} else if (q !== "") {
|
|
1191
|
+
switch (normOp) {
|
|
1192
|
+
case "equals":
|
|
1193
|
+
condition = { $containsi: q };
|
|
1194
|
+
break;
|
|
1195
|
+
case "notequals":
|
|
1196
|
+
condition = { $notContainsi: q };
|
|
1197
|
+
break;
|
|
1198
|
+
case "contains":
|
|
1199
|
+
condition = { $containsi: q };
|
|
1200
|
+
break;
|
|
1201
|
+
case "notcontains":
|
|
1202
|
+
condition = { $notContainsi: q };
|
|
1203
|
+
break;
|
|
1204
|
+
case "startswith":
|
|
1205
|
+
condition = { $startsWith: q };
|
|
1206
|
+
break;
|
|
1207
|
+
case "endswith":
|
|
1208
|
+
condition = { $endsWith: q };
|
|
1209
|
+
break;
|
|
1210
|
+
}
|
|
1211
|
+
}
|
|
1212
|
+
if (condition !== void 0) {
|
|
1213
|
+
if (isNestedAttr) {
|
|
1214
|
+
filters2[parentKey] = {
|
|
1215
|
+
[childKey]: condition
|
|
1216
|
+
};
|
|
1217
|
+
} else {
|
|
1218
|
+
if (normOp === "empty") {
|
|
1219
|
+
filters2.$or = [
|
|
1220
|
+
{ [attribute]: { $null: true } },
|
|
1221
|
+
{ [attribute]: { $eq: "" } }
|
|
1222
|
+
];
|
|
1223
|
+
} else if (normOp === "notempty") {
|
|
1224
|
+
filters2[attribute] = { $notNull: true, $ne: "" };
|
|
1225
|
+
} else {
|
|
1226
|
+
filters2[attribute] = condition;
|
|
1227
|
+
}
|
|
1228
|
+
}
|
|
1229
|
+
}
|
|
1230
|
+
}
|
|
1231
|
+
if (search && search.trim() !== "") {
|
|
1232
|
+
const q = search.trim();
|
|
1233
|
+
const searchableAttrs = Object.keys(attrs).filter(
|
|
1234
|
+
(k) => ["string", "text", "email", "uid"].includes(attrs[k]?.type)
|
|
1235
|
+
);
|
|
1236
|
+
if (searchableAttrs.length > 0) {
|
|
1237
|
+
const orList = searchableAttrs.slice(0, 6).map((k) => ({
|
|
1238
|
+
[k]: { $containsi: q }
|
|
1239
|
+
}));
|
|
1240
|
+
if (Object.keys(filters2).length > 0) {
|
|
1241
|
+
const existingFilters = { ...filters2 };
|
|
1242
|
+
Object.keys(filters2).forEach((k) => delete filters2[k]);
|
|
1243
|
+
filters2.$and = [existingFilters, { $or: orList }];
|
|
1244
|
+
} else {
|
|
1245
|
+
filters2.$or = orList;
|
|
1246
|
+
}
|
|
1247
|
+
}
|
|
1248
|
+
}
|
|
1061
1249
|
if (isSingleType) {
|
|
1062
|
-
|
|
1250
|
+
let singleDoc = null;
|
|
1251
|
+
try {
|
|
1252
|
+
singleDoc = await strapi2.documents(uid).findFirst({
|
|
1253
|
+
filters: Object.keys(filters2).length > 0 ? filters2 : void 0
|
|
1254
|
+
});
|
|
1255
|
+
} catch {
|
|
1256
|
+
singleDoc = null;
|
|
1257
|
+
}
|
|
1063
1258
|
result = {
|
|
1064
1259
|
uid,
|
|
1065
1260
|
displayName: contentType.info?.displayName || uid,
|
|
@@ -1073,55 +1268,23 @@ const bulkUpdaterService = ({ strapi: strapi2 }) => {
|
|
|
1073
1268
|
}
|
|
1074
1269
|
};
|
|
1075
1270
|
} else {
|
|
1076
|
-
const filters2 = {};
|
|
1077
|
-
if (attribute && filterOperator && filterQuery !== void 0 && filterQuery !== "") {
|
|
1078
|
-
switch (filterOperator) {
|
|
1079
|
-
case "equals":
|
|
1080
|
-
filters2[attribute] = { $eq: filterQuery };
|
|
1081
|
-
break;
|
|
1082
|
-
case "notEquals":
|
|
1083
|
-
filters2[attribute] = { $ne: filterQuery };
|
|
1084
|
-
break;
|
|
1085
|
-
case "contains":
|
|
1086
|
-
filters2[attribute] = { $containsi: filterQuery };
|
|
1087
|
-
break;
|
|
1088
|
-
case "notContains":
|
|
1089
|
-
filters2[attribute] = { $notContainsi: filterQuery };
|
|
1090
|
-
break;
|
|
1091
|
-
case "startsWith":
|
|
1092
|
-
filters2[attribute] = { $startsWith: filterQuery };
|
|
1093
|
-
break;
|
|
1094
|
-
case "endsWith":
|
|
1095
|
-
filters2[attribute] = { $endsWith: filterQuery };
|
|
1096
|
-
break;
|
|
1097
|
-
case "empty":
|
|
1098
|
-
filters2[attribute] = { $null: true };
|
|
1099
|
-
break;
|
|
1100
|
-
case "notEmpty":
|
|
1101
|
-
filters2[attribute] = { $notNull: true };
|
|
1102
|
-
break;
|
|
1103
|
-
}
|
|
1104
|
-
}
|
|
1105
|
-
if (search && search.trim() !== "") {
|
|
1106
|
-
const stringAttrs = Object.keys(contentType.attributes || {}).filter(
|
|
1107
|
-
(k) => contentType.attributes[k].type === "string" || contentType.attributes[k].type === "text" || contentType.attributes[k].type === "email"
|
|
1108
|
-
);
|
|
1109
|
-
if (stringAttrs.length > 0) {
|
|
1110
|
-
filters2.$or = stringAttrs.slice(0, 5).map((attr) => ({
|
|
1111
|
-
[attr]: { $containsi: search.trim() }
|
|
1112
|
-
}));
|
|
1113
|
-
}
|
|
1114
|
-
}
|
|
1115
1271
|
const sortClause = {};
|
|
1116
|
-
if (sortField &&
|
|
1272
|
+
if (sortField && sortField.includes(".")) {
|
|
1273
|
+
const [parent, child] = sortField.split(".");
|
|
1274
|
+
if (contentType.attributes?.[parent]?.type === "component") {
|
|
1275
|
+
sortClause[parent] = { [child]: sortOrder };
|
|
1276
|
+
} else {
|
|
1277
|
+
sortClause["createdAt"] = "desc";
|
|
1278
|
+
}
|
|
1279
|
+
} else if (sortField && contentType.attributes?.[sortField]) {
|
|
1117
1280
|
sortClause[sortField] = sortOrder;
|
|
1118
1281
|
} else {
|
|
1119
1282
|
sortClause["createdAt"] = "desc";
|
|
1120
1283
|
}
|
|
1121
|
-
const
|
|
1122
|
-
(k) => contentType.attributes[k].type === "relation"
|
|
1284
|
+
const populateAttrs = Object.keys(contentType.attributes || {}).filter(
|
|
1285
|
+
(k) => contentType.attributes[k].type === "relation" || contentType.attributes[k].type === "component"
|
|
1123
1286
|
);
|
|
1124
|
-
const populateOption =
|
|
1287
|
+
const populateOption = populateAttrs.length > 0 ? populateAttrs.reduce((acc, k) => ({ ...acc, [k]: true }), {}) : void 0;
|
|
1125
1288
|
const [entries, totalEntries] = await Promise.all([
|
|
1126
1289
|
strapi2.documents(uid).findMany({
|
|
1127
1290
|
start,
|
|
@@ -1460,6 +1623,9 @@ const bulkUpdaterService = ({ strapi: strapi2 }) => {
|
|
|
1460
1623
|
modelsCache.clear();
|
|
1461
1624
|
staticSchemaCache = null;
|
|
1462
1625
|
}
|
|
1626
|
+
},
|
|
1627
|
+
invalidateCollectionCache(uid) {
|
|
1628
|
+
invalidateCollectionCache(uid);
|
|
1463
1629
|
}
|
|
1464
1630
|
};
|
|
1465
1631
|
};
|
|
@@ -1721,12 +1887,41 @@ const auditService = ({ strapi: strapi2 }) => ({
|
|
|
1721
1887
|
} else {
|
|
1722
1888
|
rollbackPayload = item.oldValue;
|
|
1723
1889
|
}
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1890
|
+
if (item.attribute.includes(".")) {
|
|
1891
|
+
const [parentKey, childKey] = item.attribute.split(".");
|
|
1892
|
+
const ct2 = strapi2.contentTypes[item.uid];
|
|
1893
|
+
if (ct2?.attributes?.[parentKey]?.type === "component") {
|
|
1894
|
+
const currentDoc = await strapi2.documents(item.uid).findOne({
|
|
1895
|
+
documentId: item.documentId,
|
|
1896
|
+
populate: [parentKey]
|
|
1897
|
+
});
|
|
1898
|
+
const currentParent = currentDoc?.[parentKey] || {};
|
|
1899
|
+
const restoredParent = {
|
|
1900
|
+
...currentParent,
|
|
1901
|
+
[childKey]: rollbackPayload
|
|
1902
|
+
};
|
|
1903
|
+
await strapi2.documents(item.uid).update({
|
|
1904
|
+
documentId: item.documentId,
|
|
1905
|
+
data: {
|
|
1906
|
+
[parentKey]: restoredParent
|
|
1907
|
+
}
|
|
1908
|
+
});
|
|
1909
|
+
} else {
|
|
1910
|
+
await strapi2.documents(item.uid).update({
|
|
1911
|
+
documentId: item.documentId,
|
|
1912
|
+
data: {
|
|
1913
|
+
[item.attribute]: rollbackPayload
|
|
1914
|
+
}
|
|
1915
|
+
});
|
|
1728
1916
|
}
|
|
1729
|
-
}
|
|
1917
|
+
} else {
|
|
1918
|
+
await strapi2.documents(item.uid).update({
|
|
1919
|
+
documentId: item.documentId,
|
|
1920
|
+
data: {
|
|
1921
|
+
[item.attribute]: rollbackPayload
|
|
1922
|
+
}
|
|
1923
|
+
});
|
|
1924
|
+
}
|
|
1730
1925
|
const ct = strapi2.contentTypes[item.uid];
|
|
1731
1926
|
if (ct?.options?.draftAndPublish) {
|
|
1732
1927
|
try {
|
|
@@ -1737,7 +1932,10 @@ const auditService = ({ strapi: strapi2 }) => ({
|
|
|
1737
1932
|
}
|
|
1738
1933
|
}
|
|
1739
1934
|
try {
|
|
1740
|
-
strapi2.plugin("bulk-updater").service("bulkUpdater")
|
|
1935
|
+
const bulkService = strapi2.plugin("bulk-updater").service("bulkUpdater");
|
|
1936
|
+
if (bulkService?.invalidateCache) {
|
|
1937
|
+
bulkService.invalidateCache(item.uid);
|
|
1938
|
+
}
|
|
1741
1939
|
} catch {
|
|
1742
1940
|
}
|
|
1743
1941
|
revertedCount++;
|
|
@@ -2117,10 +2315,24 @@ ${sampleRow.map(escapeCsvValue).join(",")}
|
|
|
2117
2315
|
const attrs = ct.attributes || {};
|
|
2118
2316
|
const excluded = ["createdBy", "updatedBy", "localizations"];
|
|
2119
2317
|
const exportFields = ["documentId"];
|
|
2318
|
+
const compFieldsToPopulate = [];
|
|
2120
2319
|
for (const [attrName, attrDef] of Object.entries(attrs)) {
|
|
2121
2320
|
if (excluded.includes(attrName)) continue;
|
|
2122
|
-
if (["
|
|
2123
|
-
if (attrDef.type === "
|
|
2321
|
+
if (["dynamiczone", "media", "relation"].includes(attrDef.type)) continue;
|
|
2322
|
+
if (attrDef.type === "component") {
|
|
2323
|
+
if (!attrDef.repeatable && attrDef.component) {
|
|
2324
|
+
const comp = strapi2.components[attrDef.component];
|
|
2325
|
+
if (comp?.attributes) {
|
|
2326
|
+
compFieldsToPopulate.push(attrName);
|
|
2327
|
+
for (const [subKey, subDef] of Object.entries(comp.attributes)) {
|
|
2328
|
+
if (excluded.includes(subKey)) continue;
|
|
2329
|
+
if (["component", "dynamiczone", "media", "relation"].includes(subDef.type)) continue;
|
|
2330
|
+
exportFields.push(`${attrName}.${subKey}`);
|
|
2331
|
+
}
|
|
2332
|
+
}
|
|
2333
|
+
}
|
|
2334
|
+
continue;
|
|
2335
|
+
}
|
|
2124
2336
|
exportFields.push(attrName);
|
|
2125
2337
|
}
|
|
2126
2338
|
const filters2 = {};
|
|
@@ -2164,16 +2376,25 @@ ${sampleRow.map(escapeCsvValue).join(",")}
|
|
|
2164
2376
|
}
|
|
2165
2377
|
}
|
|
2166
2378
|
}
|
|
2379
|
+
const populateOption = compFieldsToPopulate.length > 0 ? compFieldsToPopulate.reduce((acc, k) => ({ ...acc, [k]: true }), {}) : void 0;
|
|
2167
2380
|
const entries = await strapi2.documents(uid).findMany({
|
|
2168
2381
|
filters: Object.keys(filters2).length > 0 ? filters2 : void 0,
|
|
2169
2382
|
limit: options.limit || 5e3,
|
|
2170
|
-
sort: { createdAt: "desc" }
|
|
2383
|
+
sort: { createdAt: "desc" },
|
|
2384
|
+
populate: populateOption
|
|
2171
2385
|
});
|
|
2172
2386
|
const lines = [];
|
|
2173
2387
|
lines.push(exportFields.map(escapeCsvValue).join(","));
|
|
2174
2388
|
for (const entry of entries || []) {
|
|
2175
2389
|
const rowValues = exportFields.map((field) => {
|
|
2176
|
-
|
|
2390
|
+
let val;
|
|
2391
|
+
if (field.includes(".")) {
|
|
2392
|
+
const [parent, child] = field.split(".");
|
|
2393
|
+
val = entry[parent]?.[child];
|
|
2394
|
+
} else {
|
|
2395
|
+
val = entry[field];
|
|
2396
|
+
}
|
|
2397
|
+
return escapeCsvValue(val);
|
|
2177
2398
|
});
|
|
2178
2399
|
lines.push(rowValues.join(","));
|
|
2179
2400
|
}
|
|
@@ -2259,6 +2480,29 @@ ${sampleRow.map(escapeCsvValue).join(",")}
|
|
|
2259
2480
|
const payload = {};
|
|
2260
2481
|
for (const [key, rawVal] of Object.entries(row)) {
|
|
2261
2482
|
if (key === "documentId" || key === "id") continue;
|
|
2483
|
+
if (key.includes(".")) {
|
|
2484
|
+
const [parent, child] = key.split(".");
|
|
2485
|
+
const parentDef = attrs[parent];
|
|
2486
|
+
if (parentDef?.type === "component" && !parentDef.repeatable && parentDef.component) {
|
|
2487
|
+
const comp = strapi2.components[parentDef.component];
|
|
2488
|
+
const childDef = comp?.attributes?.[child];
|
|
2489
|
+
if (childDef) {
|
|
2490
|
+
if (!payload[parent]) payload[parent] = {};
|
|
2491
|
+
let val = rawVal;
|
|
2492
|
+
if (rawVal === "" || rawVal === null || rawVal === void 0) {
|
|
2493
|
+
val = null;
|
|
2494
|
+
} else if (childDef.type === "integer" || childDef.type === "biginteger") {
|
|
2495
|
+
val = parseInt(rawVal, 10);
|
|
2496
|
+
} else if (childDef.type === "float" || childDef.type === "decimal") {
|
|
2497
|
+
val = parseFloat(rawVal);
|
|
2498
|
+
} else if (childDef.type === "boolean") {
|
|
2499
|
+
val = rawVal.toLowerCase() === "true" || rawVal === "1";
|
|
2500
|
+
}
|
|
2501
|
+
payload[parent][child] = val;
|
|
2502
|
+
}
|
|
2503
|
+
}
|
|
2504
|
+
continue;
|
|
2505
|
+
}
|
|
2262
2506
|
const attrDef = attrs[key];
|
|
2263
2507
|
if (!attrDef) continue;
|
|
2264
2508
|
if (rawVal === "" || rawVal === null || rawVal === void 0) {
|
|
@@ -2310,9 +2554,15 @@ ${sampleRow.map(escapeCsvValue).join(",")}
|
|
|
2310
2554
|
});
|
|
2311
2555
|
continue;
|
|
2312
2556
|
}
|
|
2557
|
+
const mergedPayload = { ...payload };
|
|
2558
|
+
for (const key of Object.keys(payload)) {
|
|
2559
|
+
if (attrs[key]?.type === "component" && typeof payload[key] === "object" && payload[key] !== null) {
|
|
2560
|
+
mergedPayload[key] = { ...existing[key] || {}, ...payload[key] };
|
|
2561
|
+
}
|
|
2562
|
+
}
|
|
2313
2563
|
await strapi2.documents(uid).update({
|
|
2314
2564
|
documentId: docId,
|
|
2315
|
-
data:
|
|
2565
|
+
data: mergedPayload
|
|
2316
2566
|
});
|
|
2317
2567
|
if (publish && ct.options?.draftAndPublish) {
|
|
2318
2568
|
try {
|
|
@@ -2339,9 +2589,15 @@ ${sampleRow.map(escapeCsvValue).join(",")}
|
|
|
2339
2589
|
documentId: docId
|
|
2340
2590
|
});
|
|
2341
2591
|
if (existing) {
|
|
2592
|
+
const mergedPayload = { ...payload };
|
|
2593
|
+
for (const key of Object.keys(payload)) {
|
|
2594
|
+
if (attrs[key]?.type === "component" && typeof payload[key] === "object" && payload[key] !== null) {
|
|
2595
|
+
mergedPayload[key] = { ...existing[key] || {}, ...payload[key] };
|
|
2596
|
+
}
|
|
2597
|
+
}
|
|
2342
2598
|
await strapi2.documents(uid).update({
|
|
2343
2599
|
documentId: docId,
|
|
2344
|
-
data:
|
|
2600
|
+
data: mergedPayload
|
|
2345
2601
|
});
|
|
2346
2602
|
if (publish && ct.options?.draftAndPublish) {
|
|
2347
2603
|
try {
|