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.
@@ -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({ documentId })
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 isApprovedComp = isDraftAndPublishComp && Boolean(currentEntry?.publishedAt) && currentEntry?.status !== "modified";
1700
- const shouldPublishComp = isDraftAndPublishComp && Boolean(publishOnApproval) && (publishStrategy === "all" ? true : isApprovedComp);
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
- await strapi.documents(target.uid).publish({
1704
- documentId: target.documentId
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 isApprovedRel = isDraftAndPublishRel && Boolean(currentEntry?.publishedAt) && currentEntry?.status !== "modified";
1799
- const shouldPublishRel = isDraftAndPublishRel && Boolean(publishOnApproval) && (publishStrategy === "all" ? true : isApprovedRel);
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
- await strapi.documents(target.uid).publish({
1803
- documentId: target.documentId
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 isApprovedScalar = isDraftAndPublishScalar && Boolean(currentEntry?.publishedAt) && currentEntry?.status !== "modified";
1844
- const shouldPublishScalar = isDraftAndPublishScalar && Boolean(publishOnApproval) && (publishStrategy === "all" ? true : isApprovedScalar);
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
- await strapi.documents(target.uid).publish({
1848
- documentId: target.documentId
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 = [row.locale, row.Locale, row["locale"], row["Locale"]];
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.documentId || current.name || current.title) {
5333
- return current.name || current.title || current.documentId;
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
- return item.name || item.title || item.documentId || JSON.stringify(item);
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 (docLocale) queryArgs.locale = docLocale;
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 (docLocale) queryArgs.locale = docLocale;
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
- const parsedInt = parseInt(rawVal, 10);
5439
- currentTarget[part] = isNaN(parsedInt) ? null : parsedInt;
5777
+ currentTarget[part] = parseNumberValue(rawVal, true);
5440
5778
  } else if (leafDef.type === "float" || leafDef.type === "decimal") {
5441
- const parsedFloat = parseFloat(rawVal);
5442
- currentTarget[part] = isNaN(parsedFloat) ? null : parsedFloat;
5779
+ currentTarget[part] = parseNumberValue(rawVal, false);
5443
5780
  } else if (leafDef.type === "boolean") {
5444
- currentTarget[part] = rawVal.toLowerCase() === "true" || rawVal === "1";
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
- const parsedInt = parseInt(rawVal, 10);
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
- const parsedFloat = parseFloat(rawVal);
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.toLowerCase() === "true" || rawVal === "1";
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 (rowLocale) findSingleArgs.locale = rowLocale;
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, rowLocale);
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 (rowLocale) updateArgs.locale = rowLocale;
6031
+ if (effectiveLocale) updateArgs.locale = effectiveLocale;
5697
6032
  await strapi.documents(uid).update(updateArgs);
5698
- const isApproved = isDraftAndPublish && Boolean(existing?.publishedAt) && existing?.status !== "modified";
5699
- const shouldPublish = isDraftAndPublish && Boolean(publish) && (publishStrategy === "all" || options.unreviewedConsent ? true : isApproved);
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 (rowLocale) pubArgs.locale = rowLocale;
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, rowLocale);
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 (rowLocale) updateArgs.locale = rowLocale;
6095
+ if (effectiveLocale) updateArgs.locale = effectiveLocale;
5752
6096
  await strapi.documents(uid).update(updateArgs);
5753
- const isApproved = isDraftAndPublish && Boolean(existing?.publishedAt) && existing?.status !== "modified";
5754
- const shouldPublish = isDraftAndPublish && Boolean(publish) && (publishStrategy === "all" || options.unreviewedConsent ? true : isApproved);
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 (rowLocale) pubArgs.locale = rowLocale;
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 (rowLocale) createArgs.locale = rowLocale;
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 shouldPublishNew = isDraftAndPublish && Boolean(publish) && (publishStrategy === "all" || options.unreviewedConsent ? true : false);
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 (rowLocale) pubArgs.locale = rowLocale;
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, rowLocale);
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 (rowLocale) updateArgs.locale = rowLocale;
6202
+ if (effectiveLocale) updateArgs.locale = effectiveLocale;
5849
6203
  await strapi.documents(uid).update(updateArgs);
5850
- const isApproved = isDraftAndPublish && Boolean(existing?.publishedAt) && existing?.status !== "modified";
5851
- const shouldPublish = isDraftAndPublish && Boolean(publish) && (publishStrategy === "all" || options.unreviewedConsent ? true : isApproved);
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 (rowLocale) pubArgs.locale = rowLocale;
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 (rowLocale) createArgs.locale = rowLocale;
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 shouldPublishNew = isDraftAndPublish && Boolean(publish) && (publishStrategy === "all" || options.unreviewedConsent ? true : false);
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 (rowLocale) pubArgs.locale = rowLocale;
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, rowLocale);
6860
+ existing = await findExistingDocument(strapi, uid, docId, effectiveLocale);
6495
6861
  }
6496
6862
  if (existing && isDraftAndPublish) {
6497
6863
  lifecycleStats.totalChecked++;
6498
- const isApproved = Boolean(existing.publishedAt) && existing.status !== "modified";
6499
- if (isApproved) {
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 (existing.status === "modified") {
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 (rowLocale) findSingleArgs.locale = rowLocale;
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, rowLocale);
7049
+ existing = await findExistingDocument(strapi, uid, docId, effectiveLocale);
6671
7050
  }
6672
7051
  if (mode === "update" && (!docId || !existing)) {
6673
7052
  skippedCount++;