strapi-plugin-bulk-updater 1.5.6 → 1.5.7

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.
@@ -68,7 +68,7 @@ const index = {
68
68
  id: `${PLUGIN_ID}.plugin.name`,
69
69
  defaultMessage: "Bulk Attribute Updater"
70
70
  },
71
- Component: () => Promise.resolve().then(() => require("../_chunks/BulkUpdater-BTWJq8UX.js")),
71
+ Component: () => Promise.resolve().then(() => require("../_chunks/BulkUpdater-KtGgE0LO.js")),
72
72
  permissions: [],
73
73
  position: 3
74
74
  });
@@ -65,7 +65,7 @@ const index = {
65
65
  id: `${PLUGIN_ID}.plugin.name`,
66
66
  defaultMessage: "Bulk Attribute Updater"
67
67
  },
68
- Component: () => import("../_chunks/BulkUpdater-7YA96VJT.mjs"),
68
+ Component: () => import("../_chunks/BulkUpdater-Ci_Uojtf.mjs"),
69
69
  permissions: [],
70
70
  position: 3
71
71
  });
@@ -995,16 +995,48 @@ function formatEntryRecord(entry) {
995
995
  }
996
996
  function extractStageName(val) {
997
997
  if (val === void 0 || val === null) return "";
998
+ if (typeof val === "string") {
999
+ const trimmed = val.trim();
1000
+ if (trimmed.startsWith("{") && trimmed.endsWith("}")) {
1001
+ try {
1002
+ const parsed = JSON.parse(trimmed);
1003
+ if (parsed && typeof parsed === "object") {
1004
+ const fromParsed = extractStageName(parsed);
1005
+ if (fromParsed) return fromParsed;
1006
+ }
1007
+ } catch {
1008
+ }
1009
+ }
1010
+ return trimmed;
1011
+ }
1012
+ if (typeof val === "number") {
1013
+ return String(val);
1014
+ }
998
1015
  if (typeof val === "object") {
999
1016
  const candidateProps = [
1000
1017
  "strapi_stage",
1001
1018
  "strapi_stage.name",
1019
+ "strapi_stage[name]",
1020
+ "strapi_stage.title",
1002
1021
  "strapiStage",
1003
1022
  "Strapi Stage",
1004
1023
  "strapi-stage",
1024
+ "strapi_stage_name",
1005
1025
  "stage",
1006
1026
  "Stage",
1007
- "review_stage"
1027
+ "stage.name",
1028
+ "stage[name]",
1029
+ "stage_name",
1030
+ "Stage Name",
1031
+ "review_stage",
1032
+ "review_stage.name",
1033
+ "review_stage[name]",
1034
+ "Review Stage",
1035
+ "reviewStage",
1036
+ "workflow_stage",
1037
+ "workflow_stage.name",
1038
+ "Workflow Stage",
1039
+ "workflowStage"
1008
1040
  ];
1009
1041
  for (const prop of candidateProps) {
1010
1042
  if (val[prop] !== void 0 && val[prop] !== null) {
@@ -1012,23 +1044,35 @@ function extractStageName(val) {
1012
1044
  if (fromProp) return fromProp;
1013
1045
  }
1014
1046
  }
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;
1047
+ const keys = Object.keys(val);
1048
+ for (const k of keys) {
1049
+ const norm = k.toLowerCase().replace(/[\s_\-\.\[\]]+/g, "");
1050
+ if (norm === "strapistage" || norm === "strapistagename" || norm === "stagename" || norm === "reviewstage" || norm === "reviewstagename" || norm === "workflowstage" || norm === "workflowstagename") {
1051
+ if (val[k] !== void 0 && val[k] !== null) {
1052
+ const fromNorm = extractStageName(val[k]);
1053
+ if (fromNorm) return fromNorm;
1025
1054
  }
1026
- } catch {
1027
1055
  }
1028
1056
  }
1029
- return trimmed;
1057
+ if (val.documentId && !val.color && !val.workflow) {
1058
+ return "";
1059
+ }
1060
+ const candidateStageValues = [
1061
+ val.name,
1062
+ val.title,
1063
+ val.label,
1064
+ val.value,
1065
+ val.stageName,
1066
+ val.stage_name,
1067
+ val.status
1068
+ ];
1069
+ for (const sv of candidateStageValues) {
1070
+ if (sv !== void 0 && sv !== null && typeof sv === "string" && sv.trim()) {
1071
+ return sv.trim();
1072
+ }
1073
+ }
1030
1074
  }
1031
- return String(val).trim();
1075
+ return "";
1032
1076
  }
1033
1077
  function isStageApproved(stageVal) {
1034
1078
  const name = extractStageName(stageVal);
@@ -1038,14 +1082,33 @@ function isStageEditingOrPending(stageVal) {
1038
1082
  const name = extractStageName(stageVal).toLowerCase();
1039
1083
  return name === "editing" || name === "in review" || name === "in_review" || name === "pending review" || name === "pending_review";
1040
1084
  }
1041
- function inspectPreUpdateStatus(entry) {
1085
+ function inspectPreUpdateStatus(entry, publishedCounterpart) {
1042
1086
  if (!entry || typeof entry !== "object") {
1043
1087
  return { hadPublishedVersion: false, isModified: false };
1044
1088
  }
1045
- const isModified = entry.status === "modified";
1046
- const isPublished = entry.status === "published" || Boolean(entry.publishedAt);
1047
- const hadPublishedVersion = isModified || isPublished;
1048
- return { hadPublishedVersion, isModified };
1089
+ const status = String(entry.status || "").toLowerCase();
1090
+ if (status === "published") {
1091
+ return { hadPublishedVersion: true, isModified: false };
1092
+ }
1093
+ if (status === "modified" || status === "modified draft") {
1094
+ return { hadPublishedVersion: true, isModified: true };
1095
+ }
1096
+ if (status === "draft") {
1097
+ return { hadPublishedVersion: false, isModified: false };
1098
+ }
1099
+ if (publishedCounterpart) {
1100
+ const draftUpdatedTime = new Date(entry.updatedAt || entry.updated_at || 0).getTime();
1101
+ const pubUpdatedTime = new Date(publishedCounterpart.updatedAt || publishedCounterpart.updated_at || 0).getTime();
1102
+ const pubPublishedTime = new Date(publishedCounterpart.publishedAt || publishedCounterpart.published_at || 0).getTime();
1103
+ const lastPublishedTime = Math.max(
1104
+ isNaN(pubUpdatedTime) ? 0 : pubUpdatedTime,
1105
+ isNaN(pubPublishedTime) ? 0 : pubPublishedTime
1106
+ );
1107
+ const isModified = !isNaN(draftUpdatedTime) && lastPublishedTime > 0 && draftUpdatedTime > lastPublishedTime;
1108
+ return { hadPublishedVersion: true, isModified };
1109
+ }
1110
+ const hasPubAt = Boolean(entry.publishedAt || entry.published_at);
1111
+ return { hadPublishedVersion: hasPubAt, isModified: false };
1049
1112
  }
1050
1113
  function determineShouldPublish({
1051
1114
  isDraftAndPublish,
@@ -1718,11 +1781,8 @@ async function executeBatchInternal(strapi, {
1718
1781
  const getDocumentDeduplicated = (uid, documentId) => {
1719
1782
  const loaderKey = `${uid}@@@${documentId}`;
1720
1783
  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
- }
1784
+ strapi.contentTypes[uid];
1785
+ const findOneArgs = { documentId, populate: ["strapi_stage", "stage"] };
1726
1786
  documentLoader.set(
1727
1787
  loaderKey,
1728
1788
  strapi.documents(uid).findOne(findOneArgs)
@@ -1732,6 +1792,34 @@ async function executeBatchInternal(strapi, {
1732
1792
  };
1733
1793
  for (let i = 0; i < targets.length; i += CHUNK_SIZE) {
1734
1794
  const chunk = targets.slice(i, i + CHUNK_SIZE);
1795
+ const chunkByUid = /* @__PURE__ */ new Map();
1796
+ for (const t of chunk) {
1797
+ if (t.uid && t.documentId) {
1798
+ if (!chunkByUid.has(t.uid)) chunkByUid.set(t.uid, []);
1799
+ chunkByUid.get(t.uid).push(t.documentId);
1800
+ }
1801
+ }
1802
+ const publishedCounterparts = /* @__PURE__ */ new Map();
1803
+ for (const [colUid, docIds] of chunkByUid.entries()) {
1804
+ const colCt = strapi.contentTypes[colUid];
1805
+ if (colCt?.options?.draftAndPublish && docIds.length > 0) {
1806
+ try {
1807
+ const pubList = await strapi.documents(colUid).findMany({
1808
+ status: "published",
1809
+ filters: { documentId: { $in: docIds } },
1810
+ fields: ["documentId", "updatedAt", "publishedAt"],
1811
+ limit: docIds.length
1812
+ });
1813
+ for (const pub of pubList || []) {
1814
+ if (pub?.documentId) {
1815
+ publishedCounterparts.set(`${colUid}@@@${pub.documentId}`, pub);
1816
+ }
1817
+ }
1818
+ } catch (err) {
1819
+ strapi.log.warn(`[bulk-updater] Failed to pre-fetch published status for ${colUid}:`, err);
1820
+ }
1821
+ }
1822
+ }
1735
1823
  const chunkPromises = chunk.map(async (target) => {
1736
1824
  const contentType = strapi.contentTypes[target.uid];
1737
1825
  const displayName = contentType?.info?.displayName || target.uid;
@@ -1783,7 +1871,24 @@ async function executeBatchInternal(strapi, {
1783
1871
  }
1784
1872
  });
1785
1873
  const isDraftAndPublishComp = Boolean(contentType?.options?.draftAndPublish);
1786
- const { hadPublishedVersion: hadPubComp, isModified: isModComp } = inspectPreUpdateStatus(currentEntry);
1874
+ let pubRecordComp = publishedCounterparts.get(`${target.uid}@@@${target.documentId}`);
1875
+ if (!pubRecordComp && isDraftAndPublishComp && target.documentId) {
1876
+ try {
1877
+ const singlePub = await strapi.documents(target.uid).findMany({
1878
+ status: "published",
1879
+ filters: { documentId: target.documentId },
1880
+ fields: ["documentId", "updatedAt", "publishedAt"],
1881
+ limit: 1
1882
+ });
1883
+ if (singlePub && singlePub.length > 0) {
1884
+ pubRecordComp = singlePub[0];
1885
+ publishedCounterparts.set(`${target.uid}@@@${target.documentId}`, pubRecordComp);
1886
+ }
1887
+ } catch {
1888
+ }
1889
+ }
1890
+ const inspectionTargetComp = target.status || target.publishedAt ? { ...currentEntry, status: target.status, publishedAt: target.publishedAt } : currentEntry;
1891
+ const { hadPublishedVersion: hadPubComp, isModified: isModComp } = inspectPreUpdateStatus(inspectionTargetComp, pubRecordComp);
1787
1892
  const targetStageComp = attribute.toLowerCase() === "strapi_stage" || attribute.toLowerCase() === "stage" ? value : currentEntry?.strapi_stage ?? currentEntry?.stage ?? target?.strapi_stage ?? target?.stage;
1788
1893
  const shouldPublishComp = determineShouldPublish({
1789
1894
  isDraftAndPublish: isDraftAndPublishComp,
@@ -1797,8 +1902,9 @@ async function executeBatchInternal(strapi, {
1797
1902
  if (shouldPublishComp) {
1798
1903
  try {
1799
1904
  const pubArgs = { documentId: target.documentId };
1800
- if (target.locale || currentEntry?.locale) {
1801
- pubArgs.locale = target.locale || currentEntry?.locale;
1905
+ const candLoc = target.locale || currentEntry?.locale;
1906
+ if (Boolean(contentType?.pluginOptions?.i18n?.localized) && candLoc && candLoc !== "null" && candLoc !== "undefined") {
1907
+ pubArgs.locale = candLoc;
1802
1908
  }
1803
1909
  await strapi.documents(target.uid).publish(pubArgs);
1804
1910
  } catch (publishErr) {
@@ -1893,7 +1999,24 @@ async function executeBatchInternal(strapi, {
1893
1999
  }
1894
2000
  });
1895
2001
  const isDraftAndPublishRel = Boolean(contentType?.options?.draftAndPublish);
1896
- const { hadPublishedVersion: hadPubRel, isModified: isModRel } = inspectPreUpdateStatus(currentEntry);
2002
+ let pubRecordRel = publishedCounterparts.get(`${target.uid}@@@${target.documentId}`);
2003
+ if (!pubRecordRel && isDraftAndPublishRel && target.documentId) {
2004
+ try {
2005
+ const singlePub = await strapi.documents(target.uid).findMany({
2006
+ status: "published",
2007
+ filters: { documentId: target.documentId },
2008
+ fields: ["documentId", "updatedAt", "publishedAt"],
2009
+ limit: 1
2010
+ });
2011
+ if (singlePub && singlePub.length > 0) {
2012
+ pubRecordRel = singlePub[0];
2013
+ publishedCounterparts.set(`${target.uid}@@@${target.documentId}`, pubRecordRel);
2014
+ }
2015
+ } catch {
2016
+ }
2017
+ }
2018
+ const inspectionTargetRel = target.status || target.publishedAt ? { ...currentEntry, status: target.status, publishedAt: target.publishedAt } : currentEntry;
2019
+ const { hadPublishedVersion: hadPubRel, isModified: isModRel } = inspectPreUpdateStatus(inspectionTargetRel, pubRecordRel);
1897
2020
  const targetStageRel = attribute.toLowerCase() === "strapi_stage" || attribute.toLowerCase() === "stage" ? value : currentEntry?.strapi_stage ?? currentEntry?.stage ?? target?.strapi_stage ?? target?.stage;
1898
2021
  const shouldPublishRel = determineShouldPublish({
1899
2022
  isDraftAndPublish: isDraftAndPublishRel,
@@ -1907,8 +2030,9 @@ async function executeBatchInternal(strapi, {
1907
2030
  if (shouldPublishRel) {
1908
2031
  try {
1909
2032
  const pubArgs = { documentId: target.documentId };
1910
- if (target.locale || currentEntry?.locale) {
1911
- pubArgs.locale = target.locale || currentEntry?.locale;
2033
+ const candLoc = target.locale || currentEntry?.locale;
2034
+ if (Boolean(contentType?.pluginOptions?.i18n?.localized) && candLoc && candLoc !== "null" && candLoc !== "undefined") {
2035
+ pubArgs.locale = candLoc;
1912
2036
  }
1913
2037
  await strapi.documents(target.uid).publish(pubArgs);
1914
2038
  } catch (publishErr) {
@@ -1949,7 +2073,24 @@ async function executeBatchInternal(strapi, {
1949
2073
  }
1950
2074
  });
1951
2075
  const isDraftAndPublishScalar = Boolean(contentType?.options?.draftAndPublish);
1952
- const { hadPublishedVersion: hadPubScalar, isModified: isModScalar } = inspectPreUpdateStatus(currentEntry);
2076
+ let pubRecordScalar = publishedCounterparts.get(`${target.uid}@@@${target.documentId}`);
2077
+ if (!pubRecordScalar && isDraftAndPublishScalar && target.documentId) {
2078
+ try {
2079
+ const singlePub = await strapi.documents(target.uid).findMany({
2080
+ status: "published",
2081
+ filters: { documentId: target.documentId },
2082
+ fields: ["documentId", "updatedAt", "publishedAt"],
2083
+ limit: 1
2084
+ });
2085
+ if (singlePub && singlePub.length > 0) {
2086
+ pubRecordScalar = singlePub[0];
2087
+ publishedCounterparts.set(`${target.uid}@@@${target.documentId}`, pubRecordScalar);
2088
+ }
2089
+ } catch {
2090
+ }
2091
+ }
2092
+ const inspectionTargetScalar = target.status || target.publishedAt ? { ...currentEntry, status: target.status, publishedAt: target.publishedAt } : currentEntry;
2093
+ const { hadPublishedVersion: hadPubScalar, isModified: isModScalar } = inspectPreUpdateStatus(inspectionTargetScalar, pubRecordScalar);
1953
2094
  const targetStageScalar = attribute.toLowerCase() === "strapi_stage" || attribute.toLowerCase() === "stage" ? value : currentEntry?.strapi_stage ?? currentEntry?.stage ?? target?.strapi_stage ?? target?.stage;
1954
2095
  const shouldPublishScalar = determineShouldPublish({
1955
2096
  isDraftAndPublish: isDraftAndPublishScalar,
@@ -1963,8 +2104,9 @@ async function executeBatchInternal(strapi, {
1963
2104
  if (shouldPublishScalar) {
1964
2105
  try {
1965
2106
  const pubArgs = { documentId: target.documentId };
1966
- if (target.locale || currentEntry?.locale) {
1967
- pubArgs.locale = target.locale || currentEntry?.locale;
2107
+ const candLoc = target.locale || currentEntry?.locale;
2108
+ if (Boolean(contentType?.pluginOptions?.i18n?.localized) && candLoc && candLoc !== "null" && candLoc !== "undefined") {
2109
+ pubArgs.locale = candLoc;
1968
2110
  }
1969
2111
  await strapi.documents(target.uid).publish(pubArgs);
1970
2112
  } catch (publishErr) {
@@ -5338,54 +5480,30 @@ function getEffectiveLocale(ct, rowLocale) {
5338
5480
  }
5339
5481
  return trimmed;
5340
5482
  }
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
- }
5483
+ function resolveStageValue(row, existing) {
5484
+ if (row && typeof row === "object") {
5485
+ const stageNameFromRow = extractStageName(row);
5486
+ if (stageNameFromRow) return stageNameFromRow;
5487
+ }
5488
+ if (existing && typeof existing === "object") {
5489
+ if (existing.strapi_stage !== void 0 && existing.strapi_stage !== null) {
5490
+ return existing.strapi_stage;
5382
5491
  }
5492
+ if (existing.stage !== void 0 && existing.stage !== null) {
5493
+ return existing.stage;
5494
+ }
5495
+ const stageNameFromExisting = extractStageName(existing);
5496
+ if (stageNameFromExisting) return stageNameFromExisting;
5383
5497
  }
5384
- return false;
5498
+ return void 0;
5385
5499
  }
5386
- function isRowInApprovedStage(row) {
5387
- if (!row || typeof row !== "object") return false;
5388
- return isStageApproved(row);
5500
+ function isRowInEditingStage(row, existing) {
5501
+ const stage = resolveStageValue(row, existing);
5502
+ return isStageEditingOrPending(stage);
5503
+ }
5504
+ function isRowInApprovedStage(row, existing) {
5505
+ const stage = resolveStageValue(row, existing);
5506
+ return isStageApproved(stage);
5389
5507
  }
5390
5508
  function extractDetailedErrorMessage(err) {
5391
5509
  if (!err) return "Error processing row";
@@ -5583,7 +5701,7 @@ async function findExistingDocument(strapi, uid, targetDocId, docLocale) {
5583
5701
  try {
5584
5702
  const queryArgs = { documentId: targetDocId };
5585
5703
  if (effectiveLocale) queryArgs.locale = effectiveLocale;
5586
- if (ct?.attributes?.strapi_stage) queryArgs.populate = ["strapi_stage"];
5704
+ queryArgs.populate = ["strapi_stage", "stage"];
5587
5705
  const found = await strapi.documents(uid).findOne(queryArgs);
5588
5706
  if (found) return found;
5589
5707
  } catch {
@@ -5963,6 +6081,25 @@ async function processCsvRows(strapi, ct, uid, rows, startRowNumber, options) {
5963
6081
  errors: [],
5964
6082
  diffs: []
5965
6083
  };
6084
+ const docIdsInChunk = rows.map((r) => extractDocId(r)).filter(Boolean);
6085
+ const publishedCounterparts = /* @__PURE__ */ new Map();
6086
+ if (isDraftAndPublish && docIdsInChunk.length > 0) {
6087
+ try {
6088
+ const pubList = await strapi.documents(uid).findMany({
6089
+ status: "published",
6090
+ filters: { documentId: { $in: docIdsInChunk } },
6091
+ fields: ["documentId", "updatedAt", "publishedAt"],
6092
+ limit: docIdsInChunk.length
6093
+ });
6094
+ for (const pub of pubList || []) {
6095
+ if (pub?.documentId) {
6096
+ publishedCounterparts.set(String(pub.documentId), pub);
6097
+ }
6098
+ }
6099
+ } catch (err) {
6100
+ strapi.log.warn(`[csv] Failed to pre-fetch published status for CSV chunk:`, err);
6101
+ }
6102
+ }
5966
6103
  for (let i = 0; i < rows.length; i++) {
5967
6104
  const rowNumber = startRowNumber + i;
5968
6105
  const row = rows[i];
@@ -6030,8 +6167,24 @@ async function processCsvRows(strapi, ct, uid, rows, startRowNumber, options) {
6030
6167
  };
6031
6168
  if (effectiveLocale) updateArgs.locale = effectiveLocale;
6032
6169
  await strapi.documents(uid).update(updateArgs);
6033
- const { hadPublishedVersion, isModified } = inspectPreUpdateStatus(existing);
6034
- const stageVal = row.strapi_stage ?? row["strapi_stage"] ?? row.stage ?? existing?.strapi_stage;
6170
+ let pubRecord = publishedCounterparts.get(String(resolvedDocId));
6171
+ if (!pubRecord && isDraftAndPublish && resolvedDocId) {
6172
+ try {
6173
+ const singlePub = await strapi.documents(uid).findMany({
6174
+ status: "published",
6175
+ filters: { documentId: resolvedDocId },
6176
+ fields: ["documentId", "updatedAt", "publishedAt"],
6177
+ limit: 1
6178
+ });
6179
+ if (singlePub && singlePub.length > 0) {
6180
+ pubRecord = singlePub[0];
6181
+ publishedCounterparts.set(String(resolvedDocId), pubRecord);
6182
+ }
6183
+ } catch {
6184
+ }
6185
+ }
6186
+ const { hadPublishedVersion, isModified } = inspectPreUpdateStatus(existing, pubRecord);
6187
+ const stageVal = resolveStageValue(row, existing);
6035
6188
  const shouldPublish = determineShouldPublish({
6036
6189
  isDraftAndPublish,
6037
6190
  hadPublishedVersion,
@@ -6044,7 +6197,10 @@ async function processCsvRows(strapi, ct, uid, rows, startRowNumber, options) {
6044
6197
  if (shouldPublish) {
6045
6198
  try {
6046
6199
  const pubArgs = { documentId: resolvedDocId };
6047
- if (effectiveLocale) pubArgs.locale = effectiveLocale;
6200
+ const isLoc = Boolean(ct?.pluginOptions?.i18n?.localized);
6201
+ if (isLoc && effectiveLocale && effectiveLocale !== "null" && effectiveLocale !== "undefined") {
6202
+ pubArgs.locale = effectiveLocale;
6203
+ }
6048
6204
  await strapi.documents(uid).publish(pubArgs);
6049
6205
  } catch (pubErr) {
6050
6206
  strapi.log.warn(`[bulk-updater] Auto-publish failed for ${resolvedDocId}:`, pubErr);
@@ -6094,8 +6250,24 @@ async function processCsvRows(strapi, ct, uid, rows, startRowNumber, options) {
6094
6250
  };
6095
6251
  if (effectiveLocale) updateArgs.locale = effectiveLocale;
6096
6252
  await strapi.documents(uid).update(updateArgs);
6097
- const { hadPublishedVersion, isModified } = inspectPreUpdateStatus(existing);
6098
- const stageVal = row.strapi_stage ?? row["strapi_stage"] ?? row.stage ?? existing?.strapi_stage;
6253
+ let pubRecord = publishedCounterparts.get(String(resolvedDocId));
6254
+ if (!pubRecord && isDraftAndPublish && resolvedDocId) {
6255
+ try {
6256
+ const singlePub = await strapi.documents(uid).findMany({
6257
+ status: "published",
6258
+ filters: { documentId: resolvedDocId },
6259
+ fields: ["documentId", "updatedAt", "publishedAt"],
6260
+ limit: 1
6261
+ });
6262
+ if (singlePub && singlePub.length > 0) {
6263
+ pubRecord = singlePub[0];
6264
+ publishedCounterparts.set(String(resolvedDocId), pubRecord);
6265
+ }
6266
+ } catch {
6267
+ }
6268
+ }
6269
+ const { hadPublishedVersion, isModified } = inspectPreUpdateStatus(existing, pubRecord);
6270
+ const stageVal = resolveStageValue(row, existing);
6099
6271
  const shouldPublish = determineShouldPublish({
6100
6272
  isDraftAndPublish,
6101
6273
  hadPublishedVersion,
@@ -6108,7 +6280,8 @@ async function processCsvRows(strapi, ct, uid, rows, startRowNumber, options) {
6108
6280
  if (shouldPublish) {
6109
6281
  try {
6110
6282
  const pubArgs = { documentId: resolvedDocId };
6111
- if (effectiveLocale) pubArgs.locale = effectiveLocale;
6283
+ const isLoc = Boolean(ct?.pluginOptions?.i18n?.localized);
6284
+ if (isLoc && effectiveLocale && effectiveLocale !== "null" && effectiveLocale !== "undefined") pubArgs.locale = effectiveLocale;
6112
6285
  await strapi.documents(uid).publish(pubArgs);
6113
6286
  } catch (pubErr) {
6114
6287
  strapi.log.warn(`[bulk-updater] Auto-publish failed for ${resolvedDocId}:`, pubErr);
@@ -6150,7 +6323,8 @@ async function processCsvRows(strapi, ct, uid, rows, startRowNumber, options) {
6150
6323
  if (shouldPublishNew && newDocId) {
6151
6324
  try {
6152
6325
  const pubArgs = { documentId: newDocId };
6153
- if (effectiveLocale) pubArgs.locale = effectiveLocale;
6326
+ const isLoc = Boolean(ct?.pluginOptions?.i18n?.localized);
6327
+ if (isLoc && effectiveLocale && effectiveLocale !== "null" && effectiveLocale !== "undefined") pubArgs.locale = effectiveLocale;
6154
6328
  await strapi.documents(uid).publish(pubArgs);
6155
6329
  } catch (pubErr) {
6156
6330
  strapi.log.warn(`[bulk-updater] Auto-publish failed for ${newDocId}:`, pubErr);
@@ -6201,8 +6375,24 @@ async function processCsvRows(strapi, ct, uid, rows, startRowNumber, options) {
6201
6375
  };
6202
6376
  if (effectiveLocale) updateArgs.locale = effectiveLocale;
6203
6377
  await strapi.documents(uid).update(updateArgs);
6204
- const { hadPublishedVersion, isModified } = inspectPreUpdateStatus(existing);
6205
- const stageVal = row.strapi_stage ?? row["strapi_stage"] ?? row.stage ?? existing?.strapi_stage;
6378
+ let pubRecord = publishedCounterparts.get(String(resolvedDocId));
6379
+ if (!pubRecord && isDraftAndPublish && resolvedDocId) {
6380
+ try {
6381
+ const singlePub = await strapi.documents(uid).findMany({
6382
+ status: "published",
6383
+ filters: { documentId: resolvedDocId },
6384
+ fields: ["documentId", "updatedAt", "publishedAt"],
6385
+ limit: 1
6386
+ });
6387
+ if (singlePub && singlePub.length > 0) {
6388
+ pubRecord = singlePub[0];
6389
+ publishedCounterparts.set(String(resolvedDocId), pubRecord);
6390
+ }
6391
+ } catch {
6392
+ }
6393
+ }
6394
+ const { hadPublishedVersion, isModified } = inspectPreUpdateStatus(existing, pubRecord);
6395
+ const stageVal = resolveStageValue(row, existing);
6206
6396
  const shouldPublish = determineShouldPublish({
6207
6397
  isDraftAndPublish,
6208
6398
  hadPublishedVersion,
@@ -6215,7 +6405,8 @@ async function processCsvRows(strapi, ct, uid, rows, startRowNumber, options) {
6215
6405
  if (shouldPublish) {
6216
6406
  try {
6217
6407
  const pubArgs = { documentId: resolvedDocId };
6218
- if (effectiveLocale) pubArgs.locale = effectiveLocale;
6408
+ const isLoc = Boolean(ct?.pluginOptions?.i18n?.localized);
6409
+ if (isLoc && effectiveLocale && effectiveLocale !== "null" && effectiveLocale !== "undefined") pubArgs.locale = effectiveLocale;
6219
6410
  await strapi.documents(uid).publish(pubArgs);
6220
6411
  } catch (pubErr) {
6221
6412
  strapi.log.warn(`[bulk-updater] Auto-publish failed for ${resolvedDocId}:`, pubErr);
@@ -6257,7 +6448,8 @@ async function processCsvRows(strapi, ct, uid, rows, startRowNumber, options) {
6257
6448
  if (shouldPublishNew && newDocId) {
6258
6449
  try {
6259
6450
  const pubArgs = { documentId: newDocId };
6260
- if (effectiveLocale) pubArgs.locale = effectiveLocale;
6451
+ const isLoc = Boolean(ct?.pluginOptions?.i18n?.localized);
6452
+ if (isLoc && effectiveLocale && effectiveLocale !== "null" && effectiveLocale !== "undefined") pubArgs.locale = effectiveLocale;
6261
6453
  await strapi.documents(uid).publish(pubArgs);
6262
6454
  } catch (pubErr) {
6263
6455
  strapi.log.warn(`[bulk-updater] Auto-publish failed for ${newDocId}:`, pubErr);
@@ -6845,6 +7037,25 @@ const csvService = ({ strapi }) => ({
6845
7037
  draft: 0,
6846
7038
  unreviewedCount: 0
6847
7039
  };
7040
+ const docIdsInPreflight = rows.map((r) => extractDocId(r)).filter(Boolean);
7041
+ const publishedCounterparts = /* @__PURE__ */ new Map();
7042
+ if (isDraftAndPublish && docIdsInPreflight.length > 0) {
7043
+ try {
7044
+ const pubList = await strapi.documents(uid).findMany({
7045
+ status: "published",
7046
+ filters: { documentId: { $in: docIdsInPreflight } },
7047
+ fields: ["documentId", "updatedAt", "publishedAt"],
7048
+ limit: docIdsInPreflight.length
7049
+ });
7050
+ for (const pub of pubList || []) {
7051
+ if (pub?.documentId) {
7052
+ publishedCounterparts.set(String(pub.documentId), pub);
7053
+ }
7054
+ }
7055
+ } catch (err) {
7056
+ strapi.log.warn(`[csv] Failed to pre-fetch published status for CSV preflight:`, err);
7057
+ }
7058
+ }
6848
7059
  const errors = [];
6849
7060
  const warnings = [];
6850
7061
  for (let i = 0; i < rows.length; i++) {
@@ -6861,8 +7072,25 @@ const csvService = ({ strapi }) => ({
6861
7072
  }
6862
7073
  if (existing && isDraftAndPublish) {
6863
7074
  lifecycleStats.totalChecked++;
6864
- const { hadPublishedVersion, isModified } = inspectPreUpdateStatus(existing);
6865
- const stageVal = row.strapi_stage ?? row["strapi_stage"] ?? row.stage ?? existing?.strapi_stage;
7075
+ const targetDocId = existing.documentId || docId;
7076
+ let pubRecord = publishedCounterparts.get(String(targetDocId));
7077
+ if (!pubRecord && isDraftAndPublish && targetDocId) {
7078
+ try {
7079
+ const singlePub = await strapi.documents(uid).findMany({
7080
+ status: "published",
7081
+ filters: { documentId: targetDocId },
7082
+ fields: ["documentId", "updatedAt", "publishedAt"],
7083
+ limit: 1
7084
+ });
7085
+ if (singlePub && singlePub.length > 0) {
7086
+ pubRecord = singlePub[0];
7087
+ publishedCounterparts.set(String(targetDocId), pubRecord);
7088
+ }
7089
+ } catch {
7090
+ }
7091
+ }
7092
+ const { hadPublishedVersion, isModified } = inspectPreUpdateStatus(existing, pubRecord);
7093
+ const stageVal = resolveStageValue(row, existing);
6866
7094
  const willPublish = determineShouldPublish({
6867
7095
  isDraftAndPublish,
6868
7096
  hadPublishedVersion,