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