strapi-plugin-bulk-updater 1.5.4 → 1.5.6
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/server/index.js +501 -122
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +501 -122
- package/dist/server/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/server/index.mjs
CHANGED
|
@@ -990,6 +990,88 @@ function formatEntryRecord(entry) {
|
|
|
990
990
|
}
|
|
991
991
|
return formatted;
|
|
992
992
|
}
|
|
993
|
+
function extractStageName(val) {
|
|
994
|
+
if (val === void 0 || val === null) return "";
|
|
995
|
+
if (typeof val === "object") {
|
|
996
|
+
const candidateProps = [
|
|
997
|
+
"strapi_stage",
|
|
998
|
+
"strapi_stage.name",
|
|
999
|
+
"strapiStage",
|
|
1000
|
+
"Strapi Stage",
|
|
1001
|
+
"strapi-stage",
|
|
1002
|
+
"stage",
|
|
1003
|
+
"Stage",
|
|
1004
|
+
"review_stage"
|
|
1005
|
+
];
|
|
1006
|
+
for (const prop of candidateProps) {
|
|
1007
|
+
if (val[prop] !== void 0 && val[prop] !== null) {
|
|
1008
|
+
const fromProp = extractStageName(val[prop]);
|
|
1009
|
+
if (fromProp) return fromProp;
|
|
1010
|
+
}
|
|
1011
|
+
}
|
|
1012
|
+
return String(val.name || val.title || val.status || val.label || "").trim();
|
|
1013
|
+
}
|
|
1014
|
+
if (typeof val === "string") {
|
|
1015
|
+
const trimmed = val.trim();
|
|
1016
|
+
if (trimmed.startsWith("{") && trimmed.endsWith("}")) {
|
|
1017
|
+
try {
|
|
1018
|
+
const parsed = JSON.parse(trimmed);
|
|
1019
|
+
if (parsed && typeof parsed === "object") {
|
|
1020
|
+
const fromParsed = String(parsed.name || parsed.title || parsed.status || parsed.label || "").trim();
|
|
1021
|
+
if (fromParsed) return fromParsed;
|
|
1022
|
+
}
|
|
1023
|
+
} catch {
|
|
1024
|
+
}
|
|
1025
|
+
}
|
|
1026
|
+
return trimmed;
|
|
1027
|
+
}
|
|
1028
|
+
return String(val).trim();
|
|
1029
|
+
}
|
|
1030
|
+
function isStageApproved(stageVal) {
|
|
1031
|
+
const name = extractStageName(stageVal);
|
|
1032
|
+
return name.toLowerCase() === "approved";
|
|
1033
|
+
}
|
|
1034
|
+
function isStageEditingOrPending(stageVal) {
|
|
1035
|
+
const name = extractStageName(stageVal).toLowerCase();
|
|
1036
|
+
return name === "editing" || name === "in review" || name === "in_review" || name === "pending review" || name === "pending_review";
|
|
1037
|
+
}
|
|
1038
|
+
function inspectPreUpdateStatus(entry) {
|
|
1039
|
+
if (!entry || typeof entry !== "object") {
|
|
1040
|
+
return { hadPublishedVersion: false, isModified: false };
|
|
1041
|
+
}
|
|
1042
|
+
const isModified = entry.status === "modified";
|
|
1043
|
+
const isPublished = entry.status === "published" || Boolean(entry.publishedAt);
|
|
1044
|
+
const hadPublishedVersion = isModified || isPublished;
|
|
1045
|
+
return { hadPublishedVersion, isModified };
|
|
1046
|
+
}
|
|
1047
|
+
function determineShouldPublish({
|
|
1048
|
+
isDraftAndPublish,
|
|
1049
|
+
hadPublishedVersion,
|
|
1050
|
+
isModified = false,
|
|
1051
|
+
stageValue,
|
|
1052
|
+
publish = true,
|
|
1053
|
+
publishStrategy = "safe",
|
|
1054
|
+
unreviewedConsent = false
|
|
1055
|
+
}) {
|
|
1056
|
+
if (!isDraftAndPublish || !publish) {
|
|
1057
|
+
return false;
|
|
1058
|
+
}
|
|
1059
|
+
if (!hadPublishedVersion) {
|
|
1060
|
+
return false;
|
|
1061
|
+
}
|
|
1062
|
+
const isApproved = isStageApproved(stageValue);
|
|
1063
|
+
const isEditingOrPending = isStageEditingOrPending(stageValue);
|
|
1064
|
+
if (isApproved) {
|
|
1065
|
+
return true;
|
|
1066
|
+
}
|
|
1067
|
+
if (isEditingOrPending) {
|
|
1068
|
+
return false;
|
|
1069
|
+
}
|
|
1070
|
+
if (publishStrategy === "all" || unreviewedConsent) {
|
|
1071
|
+
return true;
|
|
1072
|
+
}
|
|
1073
|
+
return hadPublishedVersion && !isModified;
|
|
1074
|
+
}
|
|
993
1075
|
async function populateDocumentLifecycleStatus(strapi, uid, entries) {
|
|
994
1076
|
if (!entries || !Array.isArray(entries) || entries.length === 0) {
|
|
995
1077
|
return entries;
|
|
@@ -1633,9 +1715,14 @@ async function executeBatchInternal(strapi, {
|
|
|
1633
1715
|
const getDocumentDeduplicated = (uid, documentId) => {
|
|
1634
1716
|
const loaderKey = `${uid}@@@${documentId}`;
|
|
1635
1717
|
if (!documentLoader.has(loaderKey)) {
|
|
1718
|
+
const ct = strapi.contentTypes[uid];
|
|
1719
|
+
const findOneArgs = { documentId };
|
|
1720
|
+
if (ct?.attributes?.strapi_stage) {
|
|
1721
|
+
findOneArgs.populate = ["strapi_stage"];
|
|
1722
|
+
}
|
|
1636
1723
|
documentLoader.set(
|
|
1637
1724
|
loaderKey,
|
|
1638
|
-
strapi.documents(uid).findOne(
|
|
1725
|
+
strapi.documents(uid).findOne(findOneArgs)
|
|
1639
1726
|
);
|
|
1640
1727
|
}
|
|
1641
1728
|
return documentLoader.get(loaderKey);
|
|
@@ -1693,13 +1780,24 @@ async function executeBatchInternal(strapi, {
|
|
|
1693
1780
|
}
|
|
1694
1781
|
});
|
|
1695
1782
|
const isDraftAndPublishComp = Boolean(contentType?.options?.draftAndPublish);
|
|
1696
|
-
const
|
|
1697
|
-
const
|
|
1783
|
+
const { hadPublishedVersion: hadPubComp, isModified: isModComp } = inspectPreUpdateStatus(currentEntry);
|
|
1784
|
+
const targetStageComp = attribute.toLowerCase() === "strapi_stage" || attribute.toLowerCase() === "stage" ? value : currentEntry?.strapi_stage ?? currentEntry?.stage ?? target?.strapi_stage ?? target?.stage;
|
|
1785
|
+
const shouldPublishComp = determineShouldPublish({
|
|
1786
|
+
isDraftAndPublish: isDraftAndPublishComp,
|
|
1787
|
+
hadPublishedVersion: hadPubComp,
|
|
1788
|
+
isModified: isModComp,
|
|
1789
|
+
stageValue: targetStageComp,
|
|
1790
|
+
publish: Boolean(publishOnApproval),
|
|
1791
|
+
publishStrategy,
|
|
1792
|
+
unreviewedConsent
|
|
1793
|
+
});
|
|
1698
1794
|
if (shouldPublishComp) {
|
|
1699
1795
|
try {
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1796
|
+
const pubArgs = { documentId: target.documentId };
|
|
1797
|
+
if (target.locale || currentEntry?.locale) {
|
|
1798
|
+
pubArgs.locale = target.locale || currentEntry?.locale;
|
|
1799
|
+
}
|
|
1800
|
+
await strapi.documents(target.uid).publish(pubArgs);
|
|
1703
1801
|
} catch (publishErr) {
|
|
1704
1802
|
strapi.log.warn(`[bulk-updater] Failed to auto-publish ${target.uid}/${target.documentId}:`, publishErr);
|
|
1705
1803
|
}
|
|
@@ -1709,7 +1807,7 @@ async function executeBatchInternal(strapi, {
|
|
|
1709
1807
|
uid: target.uid,
|
|
1710
1808
|
documentId: target.documentId,
|
|
1711
1809
|
userId: currentUser?.id,
|
|
1712
|
-
statusOverride: shouldPublishComp ? "published" : isDraftAndPublishComp ? "draft" : void 0
|
|
1810
|
+
statusOverride: shouldPublishComp ? "published" : isDraftAndPublishComp ? hadPubComp ? "modified" : "draft" : void 0
|
|
1713
1811
|
});
|
|
1714
1812
|
const dzDiffs = isRootDz && affectedMatches.length > 0 ? affectedMatches.map((m) => ({
|
|
1715
1813
|
index: m.index,
|
|
@@ -1792,13 +1890,24 @@ async function executeBatchInternal(strapi, {
|
|
|
1792
1890
|
}
|
|
1793
1891
|
});
|
|
1794
1892
|
const isDraftAndPublishRel = Boolean(contentType?.options?.draftAndPublish);
|
|
1795
|
-
const
|
|
1796
|
-
const
|
|
1893
|
+
const { hadPublishedVersion: hadPubRel, isModified: isModRel } = inspectPreUpdateStatus(currentEntry);
|
|
1894
|
+
const targetStageRel = attribute.toLowerCase() === "strapi_stage" || attribute.toLowerCase() === "stage" ? value : currentEntry?.strapi_stage ?? currentEntry?.stage ?? target?.strapi_stage ?? target?.stage;
|
|
1895
|
+
const shouldPublishRel = determineShouldPublish({
|
|
1896
|
+
isDraftAndPublish: isDraftAndPublishRel,
|
|
1897
|
+
hadPublishedVersion: hadPubRel,
|
|
1898
|
+
isModified: isModRel,
|
|
1899
|
+
stageValue: targetStageRel,
|
|
1900
|
+
publish: Boolean(publishOnApproval),
|
|
1901
|
+
publishStrategy,
|
|
1902
|
+
unreviewedConsent
|
|
1903
|
+
});
|
|
1797
1904
|
if (shouldPublishRel) {
|
|
1798
1905
|
try {
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1906
|
+
const pubArgs = { documentId: target.documentId };
|
|
1907
|
+
if (target.locale || currentEntry?.locale) {
|
|
1908
|
+
pubArgs.locale = target.locale || currentEntry?.locale;
|
|
1909
|
+
}
|
|
1910
|
+
await strapi.documents(target.uid).publish(pubArgs);
|
|
1802
1911
|
} catch (publishErr) {
|
|
1803
1912
|
strapi.log.warn(`[bulk-updater] Failed to auto-publish ${target.uid}/${target.documentId}:`, publishErr);
|
|
1804
1913
|
}
|
|
@@ -1811,7 +1920,7 @@ async function executeBatchInternal(strapi, {
|
|
|
1811
1920
|
uid: target.uid,
|
|
1812
1921
|
documentId: target.documentId,
|
|
1813
1922
|
userId: currentUser?.id,
|
|
1814
|
-
statusOverride: shouldPublishRel ? "published" : isDraftAndPublishRel ? "draft" : void 0
|
|
1923
|
+
statusOverride: shouldPublishRel ? "published" : isDraftAndPublishRel ? hadPubRel ? "modified" : "draft" : void 0
|
|
1815
1924
|
});
|
|
1816
1925
|
return {
|
|
1817
1926
|
uid: target.uid,
|
|
@@ -1837,13 +1946,24 @@ async function executeBatchInternal(strapi, {
|
|
|
1837
1946
|
}
|
|
1838
1947
|
});
|
|
1839
1948
|
const isDraftAndPublishScalar = Boolean(contentType?.options?.draftAndPublish);
|
|
1840
|
-
const
|
|
1841
|
-
const
|
|
1949
|
+
const { hadPublishedVersion: hadPubScalar, isModified: isModScalar } = inspectPreUpdateStatus(currentEntry);
|
|
1950
|
+
const targetStageScalar = attribute.toLowerCase() === "strapi_stage" || attribute.toLowerCase() === "stage" ? value : currentEntry?.strapi_stage ?? currentEntry?.stage ?? target?.strapi_stage ?? target?.stage;
|
|
1951
|
+
const shouldPublishScalar = determineShouldPublish({
|
|
1952
|
+
isDraftAndPublish: isDraftAndPublishScalar,
|
|
1953
|
+
hadPublishedVersion: hadPubScalar,
|
|
1954
|
+
isModified: isModScalar,
|
|
1955
|
+
stageValue: targetStageScalar,
|
|
1956
|
+
publish: Boolean(publishOnApproval),
|
|
1957
|
+
publishStrategy,
|
|
1958
|
+
unreviewedConsent
|
|
1959
|
+
});
|
|
1842
1960
|
if (shouldPublishScalar) {
|
|
1843
1961
|
try {
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
|
|
1962
|
+
const pubArgs = { documentId: target.documentId };
|
|
1963
|
+
if (target.locale || currentEntry?.locale) {
|
|
1964
|
+
pubArgs.locale = target.locale || currentEntry?.locale;
|
|
1965
|
+
}
|
|
1966
|
+
await strapi.documents(target.uid).publish(pubArgs);
|
|
1847
1967
|
} catch (publishErr) {
|
|
1848
1968
|
strapi.log.warn(`[bulk-updater] Failed to auto-publish ${target.uid}/${target.documentId}:`, publishErr);
|
|
1849
1969
|
}
|
|
@@ -1852,7 +1972,7 @@ async function executeBatchInternal(strapi, {
|
|
|
1852
1972
|
uid: target.uid,
|
|
1853
1973
|
documentId: target.documentId,
|
|
1854
1974
|
userId: currentUser?.id,
|
|
1855
|
-
statusOverride: shouldPublishScalar ? "published" : isDraftAndPublishScalar ? "draft" : void 0
|
|
1975
|
+
statusOverride: shouldPublishScalar ? "published" : isDraftAndPublishScalar ? hadPubScalar ? "modified" : "draft" : void 0
|
|
1856
1976
|
});
|
|
1857
1977
|
return {
|
|
1858
1978
|
uid: target.uid,
|
|
@@ -5141,7 +5261,14 @@ const LIFECYCLE_STATUS_WORDS = /* @__PURE__ */ new Set([
|
|
|
5141
5261
|
"published",
|
|
5142
5262
|
"modified",
|
|
5143
5263
|
"supported",
|
|
5144
|
-
"ignored"
|
|
5264
|
+
"ignored",
|
|
5265
|
+
"editing",
|
|
5266
|
+
"in review",
|
|
5267
|
+
"in_review",
|
|
5268
|
+
"ready to publish",
|
|
5269
|
+
"ready_to_publish",
|
|
5270
|
+
"null",
|
|
5271
|
+
"undefined"
|
|
5145
5272
|
]);
|
|
5146
5273
|
function isValidDocId(val) {
|
|
5147
5274
|
if (!val || typeof val !== "string") return false;
|
|
@@ -5177,17 +5304,86 @@ function extractDocId(row) {
|
|
|
5177
5304
|
}
|
|
5178
5305
|
function extractLocale(row) {
|
|
5179
5306
|
if (!row || typeof row !== "object") return void 0;
|
|
5180
|
-
const candidates = [
|
|
5307
|
+
const candidates = [
|
|
5308
|
+
row.locale,
|
|
5309
|
+
row.Locale,
|
|
5310
|
+
row["locale"],
|
|
5311
|
+
row["Locale"],
|
|
5312
|
+
row.strapi_locale,
|
|
5313
|
+
row["strapi_locale"]
|
|
5314
|
+
];
|
|
5181
5315
|
for (const c of candidates) {
|
|
5182
5316
|
if (c !== void 0 && c !== null) {
|
|
5183
5317
|
const str = String(c).trim();
|
|
5184
|
-
if (str && str.toLowerCase() !== "null" && str.toLowerCase() !== "undefined") {
|
|
5318
|
+
if (str && str.toLowerCase() !== "null" && str.toLowerCase() !== "undefined" && str.toLowerCase() !== "[null]" && str.toLowerCase() !== '""') {
|
|
5185
5319
|
return str;
|
|
5186
5320
|
}
|
|
5187
5321
|
}
|
|
5188
5322
|
}
|
|
5189
5323
|
return void 0;
|
|
5190
5324
|
}
|
|
5325
|
+
function getEffectiveLocale(ct, rowLocale) {
|
|
5326
|
+
if (!ct?.pluginOptions?.i18n?.localized) {
|
|
5327
|
+
return void 0;
|
|
5328
|
+
}
|
|
5329
|
+
if (!rowLocale) {
|
|
5330
|
+
return void 0;
|
|
5331
|
+
}
|
|
5332
|
+
const trimmed = rowLocale.trim();
|
|
5333
|
+
if (!trimmed || trimmed.toLowerCase() === "null" || trimmed.toLowerCase() === "undefined" || trimmed.toLowerCase() === "[null]" || trimmed.toLowerCase() === '""') {
|
|
5334
|
+
return void 0;
|
|
5335
|
+
}
|
|
5336
|
+
return trimmed;
|
|
5337
|
+
}
|
|
5338
|
+
function isRowInEditingStage(row) {
|
|
5339
|
+
if (!row || typeof row !== "object") return false;
|
|
5340
|
+
const candidates = [
|
|
5341
|
+
row.strapi_stage,
|
|
5342
|
+
row["strapi_stage"],
|
|
5343
|
+
row.strapiStage,
|
|
5344
|
+
row["Strapi Stage"],
|
|
5345
|
+
row["strapi-stage"],
|
|
5346
|
+
row.stage,
|
|
5347
|
+
row.Stage,
|
|
5348
|
+
row.status,
|
|
5349
|
+
row.Status
|
|
5350
|
+
];
|
|
5351
|
+
for (const c of candidates) {
|
|
5352
|
+
if (c !== void 0 && c !== null) {
|
|
5353
|
+
let stageName = "";
|
|
5354
|
+
if (typeof c === "object") {
|
|
5355
|
+
stageName = String(c.name || c.title || c.status || c.documentId || c.id || "").trim();
|
|
5356
|
+
} else if (typeof c === "string") {
|
|
5357
|
+
const trimmed = c.trim();
|
|
5358
|
+
if (trimmed.startsWith("{") && trimmed.endsWith("}")) {
|
|
5359
|
+
try {
|
|
5360
|
+
const parsed = JSON.parse(trimmed);
|
|
5361
|
+
if (typeof parsed === "object" && parsed !== null) {
|
|
5362
|
+
stageName = String(parsed.name || parsed.title || parsed.status || parsed.documentId || parsed.id || "").trim();
|
|
5363
|
+
}
|
|
5364
|
+
} catch {
|
|
5365
|
+
}
|
|
5366
|
+
}
|
|
5367
|
+
if (!stageName) {
|
|
5368
|
+
stageName = trimmed;
|
|
5369
|
+
}
|
|
5370
|
+
} else {
|
|
5371
|
+
stageName = String(c).trim();
|
|
5372
|
+
}
|
|
5373
|
+
if (stageName) {
|
|
5374
|
+
const s = stageName.toLowerCase();
|
|
5375
|
+
if (s === "editing" || s === "in review" || s === "in_review" || s === "pending review" || s === "pending_review") {
|
|
5376
|
+
return true;
|
|
5377
|
+
}
|
|
5378
|
+
}
|
|
5379
|
+
}
|
|
5380
|
+
}
|
|
5381
|
+
return false;
|
|
5382
|
+
}
|
|
5383
|
+
function isRowInApprovedStage(row) {
|
|
5384
|
+
if (!row || typeof row !== "object") return false;
|
|
5385
|
+
return isStageApproved(row);
|
|
5386
|
+
}
|
|
5191
5387
|
function extractDetailedErrorMessage(err) {
|
|
5192
5388
|
if (!err) return "Error processing row";
|
|
5193
5389
|
const detailsErrors = err.details?.errors || err.error?.details?.errors;
|
|
@@ -5322,19 +5518,26 @@ function getNestedExportValue(entry, path) {
|
|
|
5322
5518
|
}
|
|
5323
5519
|
}
|
|
5324
5520
|
if (current === null || current === void 0) return "";
|
|
5521
|
+
if (Array.isArray(current) && current.length > 0 && current[0]?.type && Array.isArray(current[0]?.children)) {
|
|
5522
|
+
return JSON.stringify(current);
|
|
5523
|
+
}
|
|
5325
5524
|
if (typeof current === "object" && current.url) {
|
|
5326
5525
|
return current.url;
|
|
5327
5526
|
}
|
|
5328
5527
|
if (typeof current === "object" && !Array.isArray(current)) {
|
|
5329
|
-
if (current.
|
|
5330
|
-
return current.name
|
|
5528
|
+
if (current.name && (current.locale === null || !current.documentId)) {
|
|
5529
|
+
return current.name;
|
|
5530
|
+
}
|
|
5531
|
+
if (current.documentId || current.id || current.name || current.title) {
|
|
5532
|
+
return current.documentId || current.id || current.name || current.title;
|
|
5331
5533
|
}
|
|
5332
5534
|
}
|
|
5333
5535
|
if (Array.isArray(current)) {
|
|
5334
5536
|
return current.map((item) => {
|
|
5335
5537
|
if (!item) return "";
|
|
5336
5538
|
if (typeof item === "object") {
|
|
5337
|
-
|
|
5539
|
+
if (item.url) return item.url;
|
|
5540
|
+
return item.documentId || item.id || item.name || item.title || JSON.stringify(item);
|
|
5338
5541
|
}
|
|
5339
5542
|
return String(item);
|
|
5340
5543
|
}).filter(Boolean).join("; ");
|
|
@@ -5362,24 +5565,43 @@ const SYSTEM_FIELD_KEYS = /* @__PURE__ */ new Set([
|
|
|
5362
5565
|
"updatedby",
|
|
5363
5566
|
"localizations",
|
|
5364
5567
|
"locale",
|
|
5365
|
-
"status"
|
|
5568
|
+
"status",
|
|
5569
|
+
"strapistage",
|
|
5570
|
+
"strapi_stage",
|
|
5571
|
+
"strapiassignee",
|
|
5572
|
+
"strapi_assignee",
|
|
5573
|
+
"strapistatus",
|
|
5574
|
+
"strapi_status"
|
|
5366
5575
|
]);
|
|
5367
5576
|
async function findExistingDocument(strapi, uid, targetDocId, docLocale) {
|
|
5368
5577
|
if (!targetDocId) return null;
|
|
5578
|
+
const ct = strapi.contentTypes[uid];
|
|
5579
|
+
const effectiveLocale = getEffectiveLocale(ct, docLocale);
|
|
5369
5580
|
try {
|
|
5370
5581
|
const queryArgs = { documentId: targetDocId };
|
|
5371
|
-
if (
|
|
5582
|
+
if (effectiveLocale) queryArgs.locale = effectiveLocale;
|
|
5583
|
+
if (ct?.attributes?.strapi_stage) queryArgs.populate = ["strapi_stage"];
|
|
5372
5584
|
const found = await strapi.documents(uid).findOne(queryArgs);
|
|
5373
5585
|
if (found) return found;
|
|
5374
5586
|
} catch {
|
|
5375
5587
|
}
|
|
5588
|
+
if (ct?.pluginOptions?.i18n?.localized && !effectiveLocale) {
|
|
5589
|
+
try {
|
|
5590
|
+
const list = await strapi.documents(uid).findMany({
|
|
5591
|
+
filters: { documentId: targetDocId },
|
|
5592
|
+
limit: 1
|
|
5593
|
+
});
|
|
5594
|
+
if (list && list.length > 0) return list[0];
|
|
5595
|
+
} catch {
|
|
5596
|
+
}
|
|
5597
|
+
}
|
|
5376
5598
|
if (/^\d+$/.test(targetDocId)) {
|
|
5377
5599
|
try {
|
|
5378
5600
|
const queryArgs = {
|
|
5379
5601
|
filters: { id: parseInt(targetDocId, 10) },
|
|
5380
5602
|
limit: 1
|
|
5381
5603
|
};
|
|
5382
|
-
if (
|
|
5604
|
+
if (effectiveLocale) queryArgs.locale = effectiveLocale;
|
|
5383
5605
|
const list = await strapi.documents(uid).findMany(queryArgs);
|
|
5384
5606
|
if (list && list.length > 0) return list[0];
|
|
5385
5607
|
} catch {
|
|
@@ -5404,12 +5626,129 @@ function deepMergeComponent(existingVal, newVal) {
|
|
|
5404
5626
|
}
|
|
5405
5627
|
return merged;
|
|
5406
5628
|
}
|
|
5629
|
+
function parseNumberValue(rawVal, isInteger) {
|
|
5630
|
+
const cleanStr = String(rawVal).replace(/[$€£,\s]/g, "");
|
|
5631
|
+
if (isInteger) {
|
|
5632
|
+
const n = parseInt(cleanStr, 10);
|
|
5633
|
+
return isNaN(n) ? null : n;
|
|
5634
|
+
} else {
|
|
5635
|
+
const f = parseFloat(cleanStr);
|
|
5636
|
+
return isNaN(f) ? null : f;
|
|
5637
|
+
}
|
|
5638
|
+
}
|
|
5639
|
+
function parseBooleanValue(rawVal) {
|
|
5640
|
+
const s = String(rawVal).trim().toLowerCase();
|
|
5641
|
+
return s === "true" || s === "1" || s === "yes" || s === "y" || s === "on";
|
|
5642
|
+
}
|
|
5643
|
+
function parseBlocksValue(rawVal) {
|
|
5644
|
+
try {
|
|
5645
|
+
const parsed = JSON.parse(rawVal);
|
|
5646
|
+
if (Array.isArray(parsed)) {
|
|
5647
|
+
return parsed;
|
|
5648
|
+
}
|
|
5649
|
+
} catch {
|
|
5650
|
+
}
|
|
5651
|
+
const trimmed = String(rawVal).trim();
|
|
5652
|
+
if (!trimmed) return [];
|
|
5653
|
+
return [{ type: "paragraph", children: [{ type: "text", text: trimmed }] }];
|
|
5654
|
+
}
|
|
5655
|
+
function parseEnumValue(rawVal, allowedValues) {
|
|
5656
|
+
const trimmed = String(rawVal).trim();
|
|
5657
|
+
if (Array.isArray(allowedValues) && allowedValues.length > 0) {
|
|
5658
|
+
const match = allowedValues.find((v) => v.toLowerCase() === trimmed.toLowerCase());
|
|
5659
|
+
if (match) return match;
|
|
5660
|
+
}
|
|
5661
|
+
return trimmed;
|
|
5662
|
+
}
|
|
5663
|
+
function parseRelationValue(rawVal, relationType) {
|
|
5664
|
+
const isToMany = relationType ? relationType.toLowerCase().endsWith("many") : false;
|
|
5665
|
+
if (rawVal === null || rawVal === void 0) return isToMany ? [] : null;
|
|
5666
|
+
let parsed = rawVal;
|
|
5667
|
+
if (typeof rawVal === "string") {
|
|
5668
|
+
const trimmed = rawVal.trim();
|
|
5669
|
+
if (trimmed.startsWith("{") || trimmed.startsWith("[")) {
|
|
5670
|
+
try {
|
|
5671
|
+
parsed = JSON.parse(trimmed);
|
|
5672
|
+
} catch {
|
|
5673
|
+
}
|
|
5674
|
+
}
|
|
5675
|
+
}
|
|
5676
|
+
if (typeof parsed === "object" && parsed !== null && !Array.isArray(parsed)) {
|
|
5677
|
+
if (parsed.name && (parsed.locale === null || LIFECYCLE_STATUS_WORDS.has(String(parsed.name).trim().toLowerCase()))) {
|
|
5678
|
+
return isToMany ? [] : null;
|
|
5679
|
+
}
|
|
5680
|
+
const docId = parsed.documentId || parsed.id || null;
|
|
5681
|
+
if (docId && isValidDocId(String(docId).trim())) {
|
|
5682
|
+
const validStr = String(docId).trim();
|
|
5683
|
+
return isToMany ? [validStr] : validStr;
|
|
5684
|
+
}
|
|
5685
|
+
return isToMany ? [] : null;
|
|
5686
|
+
}
|
|
5687
|
+
if (Array.isArray(parsed)) {
|
|
5688
|
+
const ids = parsed.map((item) => {
|
|
5689
|
+
if (typeof item === "object" && item !== null) {
|
|
5690
|
+
if (item.name && (item.locale === null || LIFECYCLE_STATUS_WORDS.has(String(item.name).trim().toLowerCase()))) {
|
|
5691
|
+
return null;
|
|
5692
|
+
}
|
|
5693
|
+
const id = item.documentId || item.id;
|
|
5694
|
+
return id && isValidDocId(String(id).trim()) ? String(id).trim() : null;
|
|
5695
|
+
}
|
|
5696
|
+
return isValidDocId(String(item).trim()) ? String(item).trim() : null;
|
|
5697
|
+
}).filter(Boolean);
|
|
5698
|
+
return isToMany ? ids : ids[0] || null;
|
|
5699
|
+
}
|
|
5700
|
+
if (typeof rawVal === "string") {
|
|
5701
|
+
if (rawVal.includes(";") || rawVal.includes(",")) {
|
|
5702
|
+
const parts = rawVal.split(/[;,]/).map((s) => s.trim()).filter((p) => isValidDocId(p));
|
|
5703
|
+
return isToMany ? parts : parts[0] || null;
|
|
5704
|
+
}
|
|
5705
|
+
const trimmed = rawVal.trim();
|
|
5706
|
+
if (isValidDocId(trimmed)) {
|
|
5707
|
+
return isToMany ? [trimmed] : trimmed;
|
|
5708
|
+
}
|
|
5709
|
+
}
|
|
5710
|
+
return isToMany ? [] : null;
|
|
5711
|
+
}
|
|
5712
|
+
function parseMediaValue(rawVal, isMultiple = false) {
|
|
5713
|
+
const trimmed = String(rawVal).trim();
|
|
5714
|
+
if (trimmed.startsWith("[") || trimmed.startsWith("{")) {
|
|
5715
|
+
try {
|
|
5716
|
+
const parsed = JSON.parse(trimmed);
|
|
5717
|
+
if (Array.isArray(parsed)) {
|
|
5718
|
+
const ids = parsed.map((item) => typeof item === "object" && item !== null ? item.id || item.documentId : item).filter(Boolean);
|
|
5719
|
+
return isMultiple ? ids : ids[0] || null;
|
|
5720
|
+
}
|
|
5721
|
+
if (typeof parsed === "number") {
|
|
5722
|
+
return isMultiple ? [parsed] : parsed;
|
|
5723
|
+
}
|
|
5724
|
+
if (typeof parsed === "object" && parsed !== null) {
|
|
5725
|
+
const id = parsed.id || parsed.documentId || parsed;
|
|
5726
|
+
return isMultiple ? [id] : id;
|
|
5727
|
+
}
|
|
5728
|
+
} catch {
|
|
5729
|
+
}
|
|
5730
|
+
}
|
|
5731
|
+
if (rawVal.includes(";") || rawVal.includes(",")) {
|
|
5732
|
+
const parts = rawVal.split(/[;,]/).map((s) => s.trim()).filter(Boolean).map((s) => /^\d+$/.test(s) ? parseInt(s, 10) : s);
|
|
5733
|
+
return isMultiple ? parts : parts[0] || null;
|
|
5734
|
+
}
|
|
5735
|
+
if (/^\d+$/.test(trimmed)) {
|
|
5736
|
+
const numId = parseInt(trimmed, 10);
|
|
5737
|
+
return isMultiple ? [numId] : numId;
|
|
5738
|
+
}
|
|
5739
|
+
if (isValidDocId(trimmed)) {
|
|
5740
|
+
return isMultiple ? [trimmed] : trimmed;
|
|
5741
|
+
}
|
|
5742
|
+
return isMultiple ? [] : null;
|
|
5743
|
+
}
|
|
5407
5744
|
function parseRowToPayload(strapi, attrs, row) {
|
|
5408
5745
|
const payload = {};
|
|
5409
5746
|
for (const [key, rawVal] of Object.entries(row)) {
|
|
5410
5747
|
const normalizedKey = key.toLowerCase().replace(/[\s_-]/g, "");
|
|
5411
5748
|
if (SYSTEM_FIELD_KEYS.has(normalizedKey)) continue;
|
|
5412
5749
|
if (key.includes(".")) {
|
|
5750
|
+
const topPart = key.split(".")[0].toLowerCase().replace(/[\s_-]/g, "");
|
|
5751
|
+
if (SYSTEM_FIELD_KEYS.has(topPart)) continue;
|
|
5413
5752
|
const parts = key.split(".");
|
|
5414
5753
|
let currentAttrs = attrs;
|
|
5415
5754
|
let currentTarget = payload;
|
|
@@ -5428,17 +5767,31 @@ function parseRowToPayload(strapi, attrs, row) {
|
|
|
5428
5767
|
break;
|
|
5429
5768
|
}
|
|
5430
5769
|
if (rawVal === "" || rawVal === null || rawVal === void 0) {
|
|
5431
|
-
if (leafDef.type !== "dynamiczone" && !(leafDef.type === "component" && leafDef.repeatable) && leafDef.type !== "relation") {
|
|
5770
|
+
if (leafDef.type !== "dynamiczone" && !(leafDef.type === "component" && leafDef.repeatable) && leafDef.type !== "relation" && leafDef.type !== "password") {
|
|
5432
5771
|
currentTarget[part] = null;
|
|
5433
5772
|
}
|
|
5434
5773
|
} else if (leafDef.type === "integer" || leafDef.type === "biginteger") {
|
|
5435
|
-
|
|
5436
|
-
currentTarget[part] = isNaN(parsedInt) ? null : parsedInt;
|
|
5774
|
+
currentTarget[part] = parseNumberValue(rawVal, true);
|
|
5437
5775
|
} else if (leafDef.type === "float" || leafDef.type === "decimal") {
|
|
5438
|
-
|
|
5439
|
-
currentTarget[part] = isNaN(parsedFloat) ? null : parsedFloat;
|
|
5776
|
+
currentTarget[part] = parseNumberValue(rawVal, false);
|
|
5440
5777
|
} else if (leafDef.type === "boolean") {
|
|
5441
|
-
currentTarget[part] = rawVal
|
|
5778
|
+
currentTarget[part] = parseBooleanValue(rawVal);
|
|
5779
|
+
} else if (leafDef.type === "blocks") {
|
|
5780
|
+
currentTarget[part] = parseBlocksValue(rawVal);
|
|
5781
|
+
} else if (leafDef.type === "enumeration") {
|
|
5782
|
+
currentTarget[part] = parseEnumValue(rawVal, leafDef.enum);
|
|
5783
|
+
} else if (leafDef.type === "relation") {
|
|
5784
|
+
currentTarget[part] = parseRelationValue(rawVal, leafDef.relation);
|
|
5785
|
+
} else if (leafDef.type === "media") {
|
|
5786
|
+
currentTarget[part] = parseMediaValue(rawVal, Boolean(leafDef.multiple));
|
|
5787
|
+
} else if (leafDef.type === "date" || leafDef.type === "time" || leafDef.type === "datetime" || leafDef.type === "timestamp") {
|
|
5788
|
+
currentTarget[part] = String(rawVal).trim() || null;
|
|
5789
|
+
} else if (leafDef.type === "email" || leafDef.type === "uid") {
|
|
5790
|
+
currentTarget[part] = String(rawVal).trim();
|
|
5791
|
+
} else if (leafDef.type === "password") {
|
|
5792
|
+
if (String(rawVal).trim()) {
|
|
5793
|
+
currentTarget[part] = String(rawVal).trim();
|
|
5794
|
+
}
|
|
5442
5795
|
} else if (leafDef.type === "json") {
|
|
5443
5796
|
try {
|
|
5444
5797
|
currentTarget[part] = JSON.parse(rawVal);
|
|
@@ -5453,19 +5806,6 @@ function parseRowToPayload(strapi, attrs, row) {
|
|
|
5453
5806
|
}
|
|
5454
5807
|
} catch {
|
|
5455
5808
|
}
|
|
5456
|
-
} else if (leafDef.type === "relation") {
|
|
5457
|
-
try {
|
|
5458
|
-
const parsed = JSON.parse(rawVal);
|
|
5459
|
-
if (Array.isArray(parsed) || typeof parsed === "object" && parsed !== null) {
|
|
5460
|
-
currentTarget[part] = parsed;
|
|
5461
|
-
} else if (isValidDocId(rawVal)) {
|
|
5462
|
-
currentTarget[part] = rawVal;
|
|
5463
|
-
}
|
|
5464
|
-
} catch {
|
|
5465
|
-
if (isValidDocId(rawVal)) {
|
|
5466
|
-
currentTarget[part] = rawVal;
|
|
5467
|
-
}
|
|
5468
|
-
}
|
|
5469
5809
|
} else {
|
|
5470
5810
|
currentTarget[part] = rawVal;
|
|
5471
5811
|
}
|
|
@@ -5504,27 +5844,53 @@ function parseRowToPayload(strapi, attrs, row) {
|
|
|
5504
5844
|
}
|
|
5505
5845
|
}
|
|
5506
5846
|
if (!attrDef) continue;
|
|
5847
|
+
if (attrDef?.target?.includes("review-workflow") || attrDef?.target === "admin::review-workflow-stage") {
|
|
5848
|
+
continue;
|
|
5849
|
+
}
|
|
5507
5850
|
if (rawVal === "" || rawVal === null || rawVal === void 0) {
|
|
5508
|
-
if (attrDef.type !== "dynamiczone" && !(attrDef.type === "component" && attrDef.repeatable)) {
|
|
5851
|
+
if (attrDef.type !== "dynamiczone" && !(attrDef.type === "component" && attrDef.repeatable) && attrDef.type !== "relation" && attrDef.type !== "password") {
|
|
5509
5852
|
payload[key] = null;
|
|
5510
5853
|
}
|
|
5511
5854
|
continue;
|
|
5512
5855
|
}
|
|
5513
5856
|
switch (attrDef.type) {
|
|
5514
5857
|
case "integer":
|
|
5515
|
-
case "biginteger":
|
|
5516
|
-
|
|
5517
|
-
payload[key] = isNaN(parsedInt) ? null : parsedInt;
|
|
5858
|
+
case "biginteger":
|
|
5859
|
+
payload[key] = parseNumberValue(rawVal, true);
|
|
5518
5860
|
break;
|
|
5519
|
-
}
|
|
5520
5861
|
case "float":
|
|
5521
|
-
case "decimal":
|
|
5522
|
-
|
|
5523
|
-
payload[key] = isNaN(parsedFloat) ? null : parsedFloat;
|
|
5862
|
+
case "decimal":
|
|
5863
|
+
payload[key] = parseNumberValue(rawVal, false);
|
|
5524
5864
|
break;
|
|
5525
|
-
}
|
|
5526
5865
|
case "boolean":
|
|
5527
|
-
payload[key] = rawVal
|
|
5866
|
+
payload[key] = parseBooleanValue(rawVal);
|
|
5867
|
+
break;
|
|
5868
|
+
case "blocks":
|
|
5869
|
+
payload[key] = parseBlocksValue(rawVal);
|
|
5870
|
+
break;
|
|
5871
|
+
case "enumeration":
|
|
5872
|
+
payload[key] = parseEnumValue(rawVal, attrDef.enum);
|
|
5873
|
+
break;
|
|
5874
|
+
case "relation":
|
|
5875
|
+
payload[key] = parseRelationValue(rawVal, attrDef.relation);
|
|
5876
|
+
break;
|
|
5877
|
+
case "media":
|
|
5878
|
+
payload[key] = parseMediaValue(rawVal, Boolean(attrDef.multiple));
|
|
5879
|
+
break;
|
|
5880
|
+
case "date":
|
|
5881
|
+
case "time":
|
|
5882
|
+
case "datetime":
|
|
5883
|
+
case "timestamp":
|
|
5884
|
+
payload[key] = String(rawVal).trim() || null;
|
|
5885
|
+
break;
|
|
5886
|
+
case "email":
|
|
5887
|
+
case "uid":
|
|
5888
|
+
payload[key] = String(rawVal).trim();
|
|
5889
|
+
break;
|
|
5890
|
+
case "password":
|
|
5891
|
+
if (String(rawVal).trim()) {
|
|
5892
|
+
payload[key] = String(rawVal).trim();
|
|
5893
|
+
}
|
|
5528
5894
|
break;
|
|
5529
5895
|
case "json":
|
|
5530
5896
|
try {
|
|
@@ -5563,39 +5929,6 @@ function parseRowToPayload(strapi, attrs, row) {
|
|
|
5563
5929
|
}
|
|
5564
5930
|
break;
|
|
5565
5931
|
}
|
|
5566
|
-
case "relation": {
|
|
5567
|
-
try {
|
|
5568
|
-
const parsed = JSON.parse(rawVal);
|
|
5569
|
-
if (Array.isArray(parsed) || typeof parsed === "object" && parsed !== null) {
|
|
5570
|
-
payload[key] = parsed;
|
|
5571
|
-
break;
|
|
5572
|
-
}
|
|
5573
|
-
} catch {
|
|
5574
|
-
}
|
|
5575
|
-
if (isValidDocId(rawVal)) {
|
|
5576
|
-
payload[key] = rawVal;
|
|
5577
|
-
} else if (rawVal.includes(";") || rawVal.includes(",")) {
|
|
5578
|
-
const parts = rawVal.split(/[;,]/).map((s) => s.trim()).filter(Boolean);
|
|
5579
|
-
if (parts.length > 0 && parts.every((p) => isValidDocId(p))) {
|
|
5580
|
-
payload[key] = parts;
|
|
5581
|
-
}
|
|
5582
|
-
}
|
|
5583
|
-
break;
|
|
5584
|
-
}
|
|
5585
|
-
case "media": {
|
|
5586
|
-
if (/^\d+$/.test(rawVal.trim())) {
|
|
5587
|
-
payload[key] = parseInt(rawVal.trim(), 10);
|
|
5588
|
-
} else {
|
|
5589
|
-
try {
|
|
5590
|
-
const parsed = JSON.parse(rawVal);
|
|
5591
|
-
if (typeof parsed === "number" || typeof parsed === "object") {
|
|
5592
|
-
payload[key] = parsed;
|
|
5593
|
-
}
|
|
5594
|
-
} catch {
|
|
5595
|
-
}
|
|
5596
|
-
}
|
|
5597
|
-
break;
|
|
5598
|
-
}
|
|
5599
5932
|
default:
|
|
5600
5933
|
payload[key] = rawVal;
|
|
5601
5934
|
}
|
|
@@ -5632,10 +5965,12 @@ async function processCsvRows(strapi, ct, uid, rows, startRowNumber, options) {
|
|
|
5632
5965
|
const row = rows[i];
|
|
5633
5966
|
let docId = extractDocId(row);
|
|
5634
5967
|
const rowLocale = extractLocale(row);
|
|
5968
|
+
const effectiveLocale = getEffectiveLocale(ct, rowLocale);
|
|
5969
|
+
const isEditing = isRowInEditingStage(row);
|
|
5635
5970
|
if (ct.kind === "singleType" && !docId) {
|
|
5636
5971
|
try {
|
|
5637
5972
|
const findSingleArgs = {};
|
|
5638
|
-
if (
|
|
5973
|
+
if (effectiveLocale) findSingleArgs.locale = effectiveLocale;
|
|
5639
5974
|
const singleDoc = await strapi.documents(uid).findFirst(findSingleArgs);
|
|
5640
5975
|
if (singleDoc?.documentId) {
|
|
5641
5976
|
docId = singleDoc.documentId;
|
|
@@ -5654,7 +5989,7 @@ async function processCsvRows(strapi, ct, uid, rows, startRowNumber, options) {
|
|
|
5654
5989
|
});
|
|
5655
5990
|
continue;
|
|
5656
5991
|
}
|
|
5657
|
-
const existing = await findExistingDocument(strapi, uid, docId,
|
|
5992
|
+
const existing = await findExistingDocument(strapi, uid, docId, effectiveLocale);
|
|
5658
5993
|
if (!existing) {
|
|
5659
5994
|
stats.skipped++;
|
|
5660
5995
|
stats.errors.push({
|
|
@@ -5690,14 +6025,23 @@ async function processCsvRows(strapi, ct, uid, rows, startRowNumber, options) {
|
|
|
5690
6025
|
documentId: resolvedDocId,
|
|
5691
6026
|
data: mergedPayload
|
|
5692
6027
|
};
|
|
5693
|
-
if (
|
|
6028
|
+
if (effectiveLocale) updateArgs.locale = effectiveLocale;
|
|
5694
6029
|
await strapi.documents(uid).update(updateArgs);
|
|
5695
|
-
const
|
|
5696
|
-
const
|
|
6030
|
+
const { hadPublishedVersion, isModified } = inspectPreUpdateStatus(existing);
|
|
6031
|
+
const stageVal = row.strapi_stage ?? row["strapi_stage"] ?? row.stage ?? existing?.strapi_stage;
|
|
6032
|
+
const shouldPublish = determineShouldPublish({
|
|
6033
|
+
isDraftAndPublish,
|
|
6034
|
+
hadPublishedVersion,
|
|
6035
|
+
isModified,
|
|
6036
|
+
stageValue: stageVal,
|
|
6037
|
+
publish: Boolean(publish),
|
|
6038
|
+
publishStrategy,
|
|
6039
|
+
unreviewedConsent: options.unreviewedConsent
|
|
6040
|
+
});
|
|
5697
6041
|
if (shouldPublish) {
|
|
5698
6042
|
try {
|
|
5699
6043
|
const pubArgs = { documentId: resolvedDocId };
|
|
5700
|
-
if (
|
|
6044
|
+
if (effectiveLocale) pubArgs.locale = effectiveLocale;
|
|
5701
6045
|
await strapi.documents(uid).publish(pubArgs);
|
|
5702
6046
|
} catch (pubErr) {
|
|
5703
6047
|
strapi.log.warn(`[bulk-updater] Auto-publish failed for ${resolvedDocId}:`, pubErr);
|
|
@@ -5708,7 +6052,7 @@ async function processCsvRows(strapi, ct, uid, rows, startRowNumber, options) {
|
|
|
5708
6052
|
uid,
|
|
5709
6053
|
documentId: resolvedDocId,
|
|
5710
6054
|
userId: user?.id,
|
|
5711
|
-
statusOverride: shouldPublish ? "published" : isDraftAndPublish ? "draft" : void 0
|
|
6055
|
+
statusOverride: shouldPublish ? "published" : isDraftAndPublish ? hadPublishedVersion ? "modified" : "draft" : void 0
|
|
5712
6056
|
});
|
|
5713
6057
|
} catch {
|
|
5714
6058
|
}
|
|
@@ -5731,7 +6075,7 @@ async function processCsvRows(strapi, ct, uid, rows, startRowNumber, options) {
|
|
|
5731
6075
|
} else if (mode === "create_or_override") {
|
|
5732
6076
|
let existing = null;
|
|
5733
6077
|
if (docId) {
|
|
5734
|
-
existing = await findExistingDocument(strapi, uid, docId,
|
|
6078
|
+
existing = await findExistingDocument(strapi, uid, docId, effectiveLocale);
|
|
5735
6079
|
}
|
|
5736
6080
|
if (existing) {
|
|
5737
6081
|
const resolvedDocId = existing.documentId || docId;
|
|
@@ -5745,14 +6089,23 @@ async function processCsvRows(strapi, ct, uid, rows, startRowNumber, options) {
|
|
|
5745
6089
|
documentId: resolvedDocId,
|
|
5746
6090
|
data: mergedPayload
|
|
5747
6091
|
};
|
|
5748
|
-
if (
|
|
6092
|
+
if (effectiveLocale) updateArgs.locale = effectiveLocale;
|
|
5749
6093
|
await strapi.documents(uid).update(updateArgs);
|
|
5750
|
-
const
|
|
5751
|
-
const
|
|
6094
|
+
const { hadPublishedVersion, isModified } = inspectPreUpdateStatus(existing);
|
|
6095
|
+
const stageVal = row.strapi_stage ?? row["strapi_stage"] ?? row.stage ?? existing?.strapi_stage;
|
|
6096
|
+
const shouldPublish = determineShouldPublish({
|
|
6097
|
+
isDraftAndPublish,
|
|
6098
|
+
hadPublishedVersion,
|
|
6099
|
+
isModified,
|
|
6100
|
+
stageValue: stageVal,
|
|
6101
|
+
publish: Boolean(publish),
|
|
6102
|
+
publishStrategy,
|
|
6103
|
+
unreviewedConsent: options.unreviewedConsent
|
|
6104
|
+
});
|
|
5752
6105
|
if (shouldPublish) {
|
|
5753
6106
|
try {
|
|
5754
6107
|
const pubArgs = { documentId: resolvedDocId };
|
|
5755
|
-
if (
|
|
6108
|
+
if (effectiveLocale) pubArgs.locale = effectiveLocale;
|
|
5756
6109
|
await strapi.documents(uid).publish(pubArgs);
|
|
5757
6110
|
} catch (pubErr) {
|
|
5758
6111
|
strapi.log.warn(`[bulk-updater] Auto-publish failed for ${resolvedDocId}:`, pubErr);
|
|
@@ -5763,7 +6116,7 @@ async function processCsvRows(strapi, ct, uid, rows, startRowNumber, options) {
|
|
|
5763
6116
|
uid,
|
|
5764
6117
|
documentId: resolvedDocId,
|
|
5765
6118
|
userId: user?.id,
|
|
5766
|
-
statusOverride: shouldPublish ? "published" : isDraftAndPublish ? "draft" : void 0
|
|
6119
|
+
statusOverride: shouldPublish ? "published" : isDraftAndPublish ? hadPublishedVersion ? "modified" : "draft" : void 0
|
|
5767
6120
|
});
|
|
5768
6121
|
} catch {
|
|
5769
6122
|
}
|
|
@@ -5786,14 +6139,15 @@ async function processCsvRows(strapi, ct, uid, rows, startRowNumber, options) {
|
|
|
5786
6139
|
continue;
|
|
5787
6140
|
}
|
|
5788
6141
|
const createArgs = { data: payload };
|
|
5789
|
-
if (
|
|
6142
|
+
if (effectiveLocale) createArgs.locale = effectiveLocale;
|
|
5790
6143
|
const created = await strapi.documents(uid).create(createArgs);
|
|
5791
6144
|
const newDocId = created?.documentId || docId;
|
|
5792
|
-
const
|
|
6145
|
+
const isApprovedStage = isRowInApprovedStage(row);
|
|
6146
|
+
const shouldPublishNew = !isEditing && !isApprovedStage && isDraftAndPublish && Boolean(publish) && (publishStrategy === "all" || options.unreviewedConsent ? true : false);
|
|
5793
6147
|
if (shouldPublishNew && newDocId) {
|
|
5794
6148
|
try {
|
|
5795
6149
|
const pubArgs = { documentId: newDocId };
|
|
5796
|
-
if (
|
|
6150
|
+
if (effectiveLocale) pubArgs.locale = effectiveLocale;
|
|
5797
6151
|
await strapi.documents(uid).publish(pubArgs);
|
|
5798
6152
|
} catch (pubErr) {
|
|
5799
6153
|
strapi.log.warn(`[bulk-updater] Auto-publish failed for ${newDocId}:`, pubErr);
|
|
@@ -5828,7 +6182,7 @@ async function processCsvRows(strapi, ct, uid, rows, startRowNumber, options) {
|
|
|
5828
6182
|
} else {
|
|
5829
6183
|
let existing = null;
|
|
5830
6184
|
if (docId) {
|
|
5831
|
-
existing = await findExistingDocument(strapi, uid, docId,
|
|
6185
|
+
existing = await findExistingDocument(strapi, uid, docId, effectiveLocale);
|
|
5832
6186
|
}
|
|
5833
6187
|
if (existing) {
|
|
5834
6188
|
const resolvedDocId = existing.documentId || docId;
|
|
@@ -5842,14 +6196,23 @@ async function processCsvRows(strapi, ct, uid, rows, startRowNumber, options) {
|
|
|
5842
6196
|
documentId: resolvedDocId,
|
|
5843
6197
|
data: mergedPayload
|
|
5844
6198
|
};
|
|
5845
|
-
if (
|
|
6199
|
+
if (effectiveLocale) updateArgs.locale = effectiveLocale;
|
|
5846
6200
|
await strapi.documents(uid).update(updateArgs);
|
|
5847
|
-
const
|
|
5848
|
-
const
|
|
6201
|
+
const { hadPublishedVersion, isModified } = inspectPreUpdateStatus(existing);
|
|
6202
|
+
const stageVal = row.strapi_stage ?? row["strapi_stage"] ?? row.stage ?? existing?.strapi_stage;
|
|
6203
|
+
const shouldPublish = determineShouldPublish({
|
|
6204
|
+
isDraftAndPublish,
|
|
6205
|
+
hadPublishedVersion,
|
|
6206
|
+
isModified,
|
|
6207
|
+
stageValue: stageVal,
|
|
6208
|
+
publish: Boolean(publish),
|
|
6209
|
+
publishStrategy,
|
|
6210
|
+
unreviewedConsent: options.unreviewedConsent
|
|
6211
|
+
});
|
|
5849
6212
|
if (shouldPublish) {
|
|
5850
6213
|
try {
|
|
5851
6214
|
const pubArgs = { documentId: resolvedDocId };
|
|
5852
|
-
if (
|
|
6215
|
+
if (effectiveLocale) pubArgs.locale = effectiveLocale;
|
|
5853
6216
|
await strapi.documents(uid).publish(pubArgs);
|
|
5854
6217
|
} catch (pubErr) {
|
|
5855
6218
|
strapi.log.warn(`[bulk-updater] Auto-publish failed for ${resolvedDocId}:`, pubErr);
|
|
@@ -5860,7 +6223,7 @@ async function processCsvRows(strapi, ct, uid, rows, startRowNumber, options) {
|
|
|
5860
6223
|
uid,
|
|
5861
6224
|
documentId: resolvedDocId,
|
|
5862
6225
|
userId: user?.id,
|
|
5863
|
-
statusOverride: shouldPublish ? "published" : isDraftAndPublish ? "draft" : void 0
|
|
6226
|
+
statusOverride: shouldPublish ? "published" : isDraftAndPublish ? hadPublishedVersion ? "modified" : "draft" : void 0
|
|
5864
6227
|
});
|
|
5865
6228
|
} catch {
|
|
5866
6229
|
}
|
|
@@ -5883,14 +6246,15 @@ async function processCsvRows(strapi, ct, uid, rows, startRowNumber, options) {
|
|
|
5883
6246
|
continue;
|
|
5884
6247
|
}
|
|
5885
6248
|
const createArgs = { data: payload };
|
|
5886
|
-
if (
|
|
6249
|
+
if (effectiveLocale) createArgs.locale = effectiveLocale;
|
|
5887
6250
|
const created = await strapi.documents(uid).create(createArgs);
|
|
5888
6251
|
const newDocId = created?.documentId || docId;
|
|
5889
|
-
const
|
|
6252
|
+
const isApprovedStage = isRowInApprovedStage(row);
|
|
6253
|
+
const shouldPublishNew = !isEditing && !isApprovedStage && isDraftAndPublish && Boolean(publish) && (publishStrategy === "all" || options.unreviewedConsent ? true : false);
|
|
5890
6254
|
if (shouldPublishNew && newDocId) {
|
|
5891
6255
|
try {
|
|
5892
6256
|
const pubArgs = { documentId: newDocId };
|
|
5893
|
-
if (
|
|
6257
|
+
if (effectiveLocale) pubArgs.locale = effectiveLocale;
|
|
5894
6258
|
await strapi.documents(uid).publish(pubArgs);
|
|
5895
6259
|
} catch (pubErr) {
|
|
5896
6260
|
strapi.log.warn(`[bulk-updater] Auto-publish failed for ${newDocId}:`, pubErr);
|
|
@@ -6485,22 +6849,36 @@ const csvService = ({ strapi }) => ({
|
|
|
6485
6849
|
const row = rows[i];
|
|
6486
6850
|
const docId = extractDocId(row);
|
|
6487
6851
|
const rowLocale = extractLocale(row);
|
|
6852
|
+
const effectiveLocale = getEffectiveLocale(ct, rowLocale);
|
|
6853
|
+
isRowInEditingStage(row);
|
|
6488
6854
|
let rowHasError = false;
|
|
6489
6855
|
let existing = null;
|
|
6490
6856
|
if (docId) {
|
|
6491
|
-
existing = await findExistingDocument(strapi, uid, docId,
|
|
6857
|
+
existing = await findExistingDocument(strapi, uid, docId, effectiveLocale);
|
|
6492
6858
|
}
|
|
6493
6859
|
if (existing && isDraftAndPublish) {
|
|
6494
6860
|
lifecycleStats.totalChecked++;
|
|
6495
|
-
const
|
|
6496
|
-
|
|
6861
|
+
const { hadPublishedVersion, isModified } = inspectPreUpdateStatus(existing);
|
|
6862
|
+
const stageVal = row.strapi_stage ?? row["strapi_stage"] ?? row.stage ?? existing?.strapi_stage;
|
|
6863
|
+
const willPublish = determineShouldPublish({
|
|
6864
|
+
isDraftAndPublish,
|
|
6865
|
+
hadPublishedVersion,
|
|
6866
|
+
isModified,
|
|
6867
|
+
stageValue: stageVal,
|
|
6868
|
+
publish: true,
|
|
6869
|
+
publishStrategy: options.publishStrategy || "safe",
|
|
6870
|
+
unreviewedConsent: options.unreviewedConsent
|
|
6871
|
+
});
|
|
6872
|
+
if (willPublish) {
|
|
6497
6873
|
lifecycleStats.published++;
|
|
6498
|
-
} else if (
|
|
6874
|
+
} else if (hadPublishedVersion && (isModified || isRowInEditingStage(row))) {
|
|
6499
6875
|
lifecycleStats.modified++;
|
|
6500
6876
|
lifecycleStats.unreviewedCount++;
|
|
6501
|
-
} else {
|
|
6877
|
+
} else if (!hadPublishedVersion) {
|
|
6502
6878
|
lifecycleStats.draft++;
|
|
6503
6879
|
lifecycleStats.unreviewedCount++;
|
|
6880
|
+
} else {
|
|
6881
|
+
lifecycleStats.published++;
|
|
6504
6882
|
}
|
|
6505
6883
|
}
|
|
6506
6884
|
if (mode === "update") {
|
|
@@ -6651,10 +7029,11 @@ const csvService = ({ strapi }) => ({
|
|
|
6651
7029
|
const row = rows[i];
|
|
6652
7030
|
let docId = extractDocId(row);
|
|
6653
7031
|
const rowLocale = extractLocale(row);
|
|
7032
|
+
const effectiveLocale = getEffectiveLocale(ct, rowLocale);
|
|
6654
7033
|
if (ct.kind === "singleType" && !docId) {
|
|
6655
7034
|
try {
|
|
6656
7035
|
const findSingleArgs = {};
|
|
6657
|
-
if (
|
|
7036
|
+
if (effectiveLocale) findSingleArgs.locale = effectiveLocale;
|
|
6658
7037
|
const singleDoc = await strapi.documents(uid).findFirst(findSingleArgs);
|
|
6659
7038
|
if (singleDoc?.documentId) {
|
|
6660
7039
|
docId = singleDoc.documentId;
|
|
@@ -6664,7 +7043,7 @@ const csvService = ({ strapi }) => ({
|
|
|
6664
7043
|
}
|
|
6665
7044
|
let existing = null;
|
|
6666
7045
|
if (docId) {
|
|
6667
|
-
existing = await findExistingDocument(strapi, uid, docId,
|
|
7046
|
+
existing = await findExistingDocument(strapi, uid, docId, effectiveLocale);
|
|
6668
7047
|
}
|
|
6669
7048
|
if (mode === "update" && (!docId || !existing)) {
|
|
6670
7049
|
skippedCount++;
|