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