strapi-plugin-bulk-updater 1.5.4 → 1.5.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/server/index.js +314 -101
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +314 -101
- package/dist/server/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/server/index.js
CHANGED
|
@@ -5144,7 +5144,14 @@ const LIFECYCLE_STATUS_WORDS = /* @__PURE__ */ new Set([
|
|
|
5144
5144
|
"published",
|
|
5145
5145
|
"modified",
|
|
5146
5146
|
"supported",
|
|
5147
|
-
"ignored"
|
|
5147
|
+
"ignored",
|
|
5148
|
+
"editing",
|
|
5149
|
+
"in review",
|
|
5150
|
+
"in_review",
|
|
5151
|
+
"ready to publish",
|
|
5152
|
+
"ready_to_publish",
|
|
5153
|
+
"null",
|
|
5154
|
+
"undefined"
|
|
5148
5155
|
]);
|
|
5149
5156
|
function isValidDocId(val) {
|
|
5150
5157
|
if (!val || typeof val !== "string") return false;
|
|
@@ -5180,17 +5187,82 @@ function extractDocId(row) {
|
|
|
5180
5187
|
}
|
|
5181
5188
|
function extractLocale(row) {
|
|
5182
5189
|
if (!row || typeof row !== "object") return void 0;
|
|
5183
|
-
const candidates = [
|
|
5190
|
+
const candidates = [
|
|
5191
|
+
row.locale,
|
|
5192
|
+
row.Locale,
|
|
5193
|
+
row["locale"],
|
|
5194
|
+
row["Locale"],
|
|
5195
|
+
row.strapi_locale,
|
|
5196
|
+
row["strapi_locale"]
|
|
5197
|
+
];
|
|
5184
5198
|
for (const c of candidates) {
|
|
5185
5199
|
if (c !== void 0 && c !== null) {
|
|
5186
5200
|
const str = String(c).trim();
|
|
5187
|
-
if (str && str.toLowerCase() !== "null" && str.toLowerCase() !== "undefined") {
|
|
5201
|
+
if (str && str.toLowerCase() !== "null" && str.toLowerCase() !== "undefined" && str.toLowerCase() !== "[null]" && str.toLowerCase() !== '""') {
|
|
5188
5202
|
return str;
|
|
5189
5203
|
}
|
|
5190
5204
|
}
|
|
5191
5205
|
}
|
|
5192
5206
|
return void 0;
|
|
5193
5207
|
}
|
|
5208
|
+
function getEffectiveLocale(ct, rowLocale) {
|
|
5209
|
+
if (!ct?.pluginOptions?.i18n?.localized) {
|
|
5210
|
+
return void 0;
|
|
5211
|
+
}
|
|
5212
|
+
if (!rowLocale) {
|
|
5213
|
+
return void 0;
|
|
5214
|
+
}
|
|
5215
|
+
const trimmed = rowLocale.trim();
|
|
5216
|
+
if (!trimmed || trimmed.toLowerCase() === "null" || trimmed.toLowerCase() === "undefined" || trimmed.toLowerCase() === "[null]" || trimmed.toLowerCase() === '""') {
|
|
5217
|
+
return void 0;
|
|
5218
|
+
}
|
|
5219
|
+
return trimmed;
|
|
5220
|
+
}
|
|
5221
|
+
function isRowInEditingStage(row) {
|
|
5222
|
+
if (!row || typeof row !== "object") return false;
|
|
5223
|
+
const candidates = [
|
|
5224
|
+
row.strapi_stage,
|
|
5225
|
+
row["strapi_stage"],
|
|
5226
|
+
row.strapiStage,
|
|
5227
|
+
row["Strapi Stage"],
|
|
5228
|
+
row["strapi-stage"],
|
|
5229
|
+
row.stage,
|
|
5230
|
+
row.Stage,
|
|
5231
|
+
row.status,
|
|
5232
|
+
row.Status
|
|
5233
|
+
];
|
|
5234
|
+
for (const c of candidates) {
|
|
5235
|
+
if (c !== void 0 && c !== null) {
|
|
5236
|
+
let stageName = "";
|
|
5237
|
+
if (typeof c === "object") {
|
|
5238
|
+
stageName = String(c.name || c.title || c.status || c.documentId || c.id || "").trim();
|
|
5239
|
+
} else if (typeof c === "string") {
|
|
5240
|
+
const trimmed = c.trim();
|
|
5241
|
+
if (trimmed.startsWith("{") && trimmed.endsWith("}")) {
|
|
5242
|
+
try {
|
|
5243
|
+
const parsed = JSON.parse(trimmed);
|
|
5244
|
+
if (typeof parsed === "object" && parsed !== null) {
|
|
5245
|
+
stageName = String(parsed.name || parsed.title || parsed.status || parsed.documentId || parsed.id || "").trim();
|
|
5246
|
+
}
|
|
5247
|
+
} catch {
|
|
5248
|
+
}
|
|
5249
|
+
}
|
|
5250
|
+
if (!stageName) {
|
|
5251
|
+
stageName = trimmed;
|
|
5252
|
+
}
|
|
5253
|
+
} else {
|
|
5254
|
+
stageName = String(c).trim();
|
|
5255
|
+
}
|
|
5256
|
+
if (stageName) {
|
|
5257
|
+
const s = stageName.toLowerCase();
|
|
5258
|
+
if (s === "editing" || s === "in review" || s === "in_review" || s === "pending review" || s === "pending_review") {
|
|
5259
|
+
return true;
|
|
5260
|
+
}
|
|
5261
|
+
}
|
|
5262
|
+
}
|
|
5263
|
+
}
|
|
5264
|
+
return false;
|
|
5265
|
+
}
|
|
5194
5266
|
function extractDetailedErrorMessage(err) {
|
|
5195
5267
|
if (!err) return "Error processing row";
|
|
5196
5268
|
const detailsErrors = err.details?.errors || err.error?.details?.errors;
|
|
@@ -5325,19 +5397,26 @@ function getNestedExportValue(entry, path) {
|
|
|
5325
5397
|
}
|
|
5326
5398
|
}
|
|
5327
5399
|
if (current === null || current === void 0) return "";
|
|
5400
|
+
if (Array.isArray(current) && current.length > 0 && current[0]?.type && Array.isArray(current[0]?.children)) {
|
|
5401
|
+
return JSON.stringify(current);
|
|
5402
|
+
}
|
|
5328
5403
|
if (typeof current === "object" && current.url) {
|
|
5329
5404
|
return current.url;
|
|
5330
5405
|
}
|
|
5331
5406
|
if (typeof current === "object" && !Array.isArray(current)) {
|
|
5332
|
-
if (current.
|
|
5333
|
-
return current.name
|
|
5407
|
+
if (current.name && (current.locale === null || !current.documentId)) {
|
|
5408
|
+
return current.name;
|
|
5409
|
+
}
|
|
5410
|
+
if (current.documentId || current.id || current.name || current.title) {
|
|
5411
|
+
return current.documentId || current.id || current.name || current.title;
|
|
5334
5412
|
}
|
|
5335
5413
|
}
|
|
5336
5414
|
if (Array.isArray(current)) {
|
|
5337
5415
|
return current.map((item) => {
|
|
5338
5416
|
if (!item) return "";
|
|
5339
5417
|
if (typeof item === "object") {
|
|
5340
|
-
|
|
5418
|
+
if (item.url) return item.url;
|
|
5419
|
+
return item.documentId || item.id || item.name || item.title || JSON.stringify(item);
|
|
5341
5420
|
}
|
|
5342
5421
|
return String(item);
|
|
5343
5422
|
}).filter(Boolean).join("; ");
|
|
@@ -5365,24 +5444,42 @@ const SYSTEM_FIELD_KEYS = /* @__PURE__ */ new Set([
|
|
|
5365
5444
|
"updatedby",
|
|
5366
5445
|
"localizations",
|
|
5367
5446
|
"locale",
|
|
5368
|
-
"status"
|
|
5447
|
+
"status",
|
|
5448
|
+
"strapistage",
|
|
5449
|
+
"strapi_stage",
|
|
5450
|
+
"strapiassignee",
|
|
5451
|
+
"strapi_assignee",
|
|
5452
|
+
"strapistatus",
|
|
5453
|
+
"strapi_status"
|
|
5369
5454
|
]);
|
|
5370
5455
|
async function findExistingDocument(strapi, uid, targetDocId, docLocale) {
|
|
5371
5456
|
if (!targetDocId) return null;
|
|
5457
|
+
const ct = strapi.contentTypes[uid];
|
|
5458
|
+
const effectiveLocale = getEffectiveLocale(ct, docLocale);
|
|
5372
5459
|
try {
|
|
5373
5460
|
const queryArgs = { documentId: targetDocId };
|
|
5374
|
-
if (
|
|
5461
|
+
if (effectiveLocale) queryArgs.locale = effectiveLocale;
|
|
5375
5462
|
const found = await strapi.documents(uid).findOne(queryArgs);
|
|
5376
5463
|
if (found) return found;
|
|
5377
5464
|
} catch {
|
|
5378
5465
|
}
|
|
5466
|
+
if (ct?.pluginOptions?.i18n?.localized && !effectiveLocale) {
|
|
5467
|
+
try {
|
|
5468
|
+
const list = await strapi.documents(uid).findMany({
|
|
5469
|
+
filters: { documentId: targetDocId },
|
|
5470
|
+
limit: 1
|
|
5471
|
+
});
|
|
5472
|
+
if (list && list.length > 0) return list[0];
|
|
5473
|
+
} catch {
|
|
5474
|
+
}
|
|
5475
|
+
}
|
|
5379
5476
|
if (/^\d+$/.test(targetDocId)) {
|
|
5380
5477
|
try {
|
|
5381
5478
|
const queryArgs = {
|
|
5382
5479
|
filters: { id: parseInt(targetDocId, 10) },
|
|
5383
5480
|
limit: 1
|
|
5384
5481
|
};
|
|
5385
|
-
if (
|
|
5482
|
+
if (effectiveLocale) queryArgs.locale = effectiveLocale;
|
|
5386
5483
|
const list = await strapi.documents(uid).findMany(queryArgs);
|
|
5387
5484
|
if (list && list.length > 0) return list[0];
|
|
5388
5485
|
} catch {
|
|
@@ -5407,12 +5504,129 @@ function deepMergeComponent(existingVal, newVal) {
|
|
|
5407
5504
|
}
|
|
5408
5505
|
return merged;
|
|
5409
5506
|
}
|
|
5507
|
+
function parseNumberValue(rawVal, isInteger) {
|
|
5508
|
+
const cleanStr = String(rawVal).replace(/[$€£,\s]/g, "");
|
|
5509
|
+
if (isInteger) {
|
|
5510
|
+
const n = parseInt(cleanStr, 10);
|
|
5511
|
+
return isNaN(n) ? null : n;
|
|
5512
|
+
} else {
|
|
5513
|
+
const f = parseFloat(cleanStr);
|
|
5514
|
+
return isNaN(f) ? null : f;
|
|
5515
|
+
}
|
|
5516
|
+
}
|
|
5517
|
+
function parseBooleanValue(rawVal) {
|
|
5518
|
+
const s = String(rawVal).trim().toLowerCase();
|
|
5519
|
+
return s === "true" || s === "1" || s === "yes" || s === "y" || s === "on";
|
|
5520
|
+
}
|
|
5521
|
+
function parseBlocksValue(rawVal) {
|
|
5522
|
+
try {
|
|
5523
|
+
const parsed = JSON.parse(rawVal);
|
|
5524
|
+
if (Array.isArray(parsed)) {
|
|
5525
|
+
return parsed;
|
|
5526
|
+
}
|
|
5527
|
+
} catch {
|
|
5528
|
+
}
|
|
5529
|
+
const trimmed = String(rawVal).trim();
|
|
5530
|
+
if (!trimmed) return [];
|
|
5531
|
+
return [{ type: "paragraph", children: [{ type: "text", text: trimmed }] }];
|
|
5532
|
+
}
|
|
5533
|
+
function parseEnumValue(rawVal, allowedValues) {
|
|
5534
|
+
const trimmed = String(rawVal).trim();
|
|
5535
|
+
if (Array.isArray(allowedValues) && allowedValues.length > 0) {
|
|
5536
|
+
const match = allowedValues.find((v) => v.toLowerCase() === trimmed.toLowerCase());
|
|
5537
|
+
if (match) return match;
|
|
5538
|
+
}
|
|
5539
|
+
return trimmed;
|
|
5540
|
+
}
|
|
5541
|
+
function parseRelationValue(rawVal, relationType) {
|
|
5542
|
+
const isToMany = relationType ? relationType.toLowerCase().endsWith("many") : false;
|
|
5543
|
+
if (rawVal === null || rawVal === void 0) return isToMany ? [] : null;
|
|
5544
|
+
let parsed = rawVal;
|
|
5545
|
+
if (typeof rawVal === "string") {
|
|
5546
|
+
const trimmed = rawVal.trim();
|
|
5547
|
+
if (trimmed.startsWith("{") || trimmed.startsWith("[")) {
|
|
5548
|
+
try {
|
|
5549
|
+
parsed = JSON.parse(trimmed);
|
|
5550
|
+
} catch {
|
|
5551
|
+
}
|
|
5552
|
+
}
|
|
5553
|
+
}
|
|
5554
|
+
if (typeof parsed === "object" && parsed !== null && !Array.isArray(parsed)) {
|
|
5555
|
+
if (parsed.name && (parsed.locale === null || LIFECYCLE_STATUS_WORDS.has(String(parsed.name).trim().toLowerCase()))) {
|
|
5556
|
+
return isToMany ? [] : null;
|
|
5557
|
+
}
|
|
5558
|
+
const docId = parsed.documentId || parsed.id || null;
|
|
5559
|
+
if (docId && isValidDocId(String(docId).trim())) {
|
|
5560
|
+
const validStr = String(docId).trim();
|
|
5561
|
+
return isToMany ? [validStr] : validStr;
|
|
5562
|
+
}
|
|
5563
|
+
return isToMany ? [] : null;
|
|
5564
|
+
}
|
|
5565
|
+
if (Array.isArray(parsed)) {
|
|
5566
|
+
const ids = parsed.map((item) => {
|
|
5567
|
+
if (typeof item === "object" && item !== null) {
|
|
5568
|
+
if (item.name && (item.locale === null || LIFECYCLE_STATUS_WORDS.has(String(item.name).trim().toLowerCase()))) {
|
|
5569
|
+
return null;
|
|
5570
|
+
}
|
|
5571
|
+
const id = item.documentId || item.id;
|
|
5572
|
+
return id && isValidDocId(String(id).trim()) ? String(id).trim() : null;
|
|
5573
|
+
}
|
|
5574
|
+
return isValidDocId(String(item).trim()) ? String(item).trim() : null;
|
|
5575
|
+
}).filter(Boolean);
|
|
5576
|
+
return isToMany ? ids : ids[0] || null;
|
|
5577
|
+
}
|
|
5578
|
+
if (typeof rawVal === "string") {
|
|
5579
|
+
if (rawVal.includes(";") || rawVal.includes(",")) {
|
|
5580
|
+
const parts = rawVal.split(/[;,]/).map((s) => s.trim()).filter((p) => isValidDocId(p));
|
|
5581
|
+
return isToMany ? parts : parts[0] || null;
|
|
5582
|
+
}
|
|
5583
|
+
const trimmed = rawVal.trim();
|
|
5584
|
+
if (isValidDocId(trimmed)) {
|
|
5585
|
+
return isToMany ? [trimmed] : trimmed;
|
|
5586
|
+
}
|
|
5587
|
+
}
|
|
5588
|
+
return isToMany ? [] : null;
|
|
5589
|
+
}
|
|
5590
|
+
function parseMediaValue(rawVal, isMultiple = false) {
|
|
5591
|
+
const trimmed = String(rawVal).trim();
|
|
5592
|
+
if (trimmed.startsWith("[") || trimmed.startsWith("{")) {
|
|
5593
|
+
try {
|
|
5594
|
+
const parsed = JSON.parse(trimmed);
|
|
5595
|
+
if (Array.isArray(parsed)) {
|
|
5596
|
+
const ids = parsed.map((item) => typeof item === "object" && item !== null ? item.id || item.documentId : item).filter(Boolean);
|
|
5597
|
+
return isMultiple ? ids : ids[0] || null;
|
|
5598
|
+
}
|
|
5599
|
+
if (typeof parsed === "number") {
|
|
5600
|
+
return isMultiple ? [parsed] : parsed;
|
|
5601
|
+
}
|
|
5602
|
+
if (typeof parsed === "object" && parsed !== null) {
|
|
5603
|
+
const id = parsed.id || parsed.documentId || parsed;
|
|
5604
|
+
return isMultiple ? [id] : id;
|
|
5605
|
+
}
|
|
5606
|
+
} catch {
|
|
5607
|
+
}
|
|
5608
|
+
}
|
|
5609
|
+
if (rawVal.includes(";") || rawVal.includes(",")) {
|
|
5610
|
+
const parts = rawVal.split(/[;,]/).map((s) => s.trim()).filter(Boolean).map((s) => /^\d+$/.test(s) ? parseInt(s, 10) : s);
|
|
5611
|
+
return isMultiple ? parts : parts[0] || null;
|
|
5612
|
+
}
|
|
5613
|
+
if (/^\d+$/.test(trimmed)) {
|
|
5614
|
+
const numId = parseInt(trimmed, 10);
|
|
5615
|
+
return isMultiple ? [numId] : numId;
|
|
5616
|
+
}
|
|
5617
|
+
if (isValidDocId(trimmed)) {
|
|
5618
|
+
return isMultiple ? [trimmed] : trimmed;
|
|
5619
|
+
}
|
|
5620
|
+
return isMultiple ? [] : null;
|
|
5621
|
+
}
|
|
5410
5622
|
function parseRowToPayload(strapi, attrs, row) {
|
|
5411
5623
|
const payload = {};
|
|
5412
5624
|
for (const [key, rawVal] of Object.entries(row)) {
|
|
5413
5625
|
const normalizedKey = key.toLowerCase().replace(/[\s_-]/g, "");
|
|
5414
5626
|
if (SYSTEM_FIELD_KEYS.has(normalizedKey)) continue;
|
|
5415
5627
|
if (key.includes(".")) {
|
|
5628
|
+
const topPart = key.split(".")[0].toLowerCase().replace(/[\s_-]/g, "");
|
|
5629
|
+
if (SYSTEM_FIELD_KEYS.has(topPart)) continue;
|
|
5416
5630
|
const parts = key.split(".");
|
|
5417
5631
|
let currentAttrs = attrs;
|
|
5418
5632
|
let currentTarget = payload;
|
|
@@ -5431,17 +5645,31 @@ function parseRowToPayload(strapi, attrs, row) {
|
|
|
5431
5645
|
break;
|
|
5432
5646
|
}
|
|
5433
5647
|
if (rawVal === "" || rawVal === null || rawVal === void 0) {
|
|
5434
|
-
if (leafDef.type !== "dynamiczone" && !(leafDef.type === "component" && leafDef.repeatable) && leafDef.type !== "relation") {
|
|
5648
|
+
if (leafDef.type !== "dynamiczone" && !(leafDef.type === "component" && leafDef.repeatable) && leafDef.type !== "relation" && leafDef.type !== "password") {
|
|
5435
5649
|
currentTarget[part] = null;
|
|
5436
5650
|
}
|
|
5437
5651
|
} else if (leafDef.type === "integer" || leafDef.type === "biginteger") {
|
|
5438
|
-
|
|
5439
|
-
currentTarget[part] = isNaN(parsedInt) ? null : parsedInt;
|
|
5652
|
+
currentTarget[part] = parseNumberValue(rawVal, true);
|
|
5440
5653
|
} else if (leafDef.type === "float" || leafDef.type === "decimal") {
|
|
5441
|
-
|
|
5442
|
-
currentTarget[part] = isNaN(parsedFloat) ? null : parsedFloat;
|
|
5654
|
+
currentTarget[part] = parseNumberValue(rawVal, false);
|
|
5443
5655
|
} else if (leafDef.type === "boolean") {
|
|
5444
|
-
currentTarget[part] = rawVal
|
|
5656
|
+
currentTarget[part] = parseBooleanValue(rawVal);
|
|
5657
|
+
} else if (leafDef.type === "blocks") {
|
|
5658
|
+
currentTarget[part] = parseBlocksValue(rawVal);
|
|
5659
|
+
} else if (leafDef.type === "enumeration") {
|
|
5660
|
+
currentTarget[part] = parseEnumValue(rawVal, leafDef.enum);
|
|
5661
|
+
} else if (leafDef.type === "relation") {
|
|
5662
|
+
currentTarget[part] = parseRelationValue(rawVal, leafDef.relation);
|
|
5663
|
+
} else if (leafDef.type === "media") {
|
|
5664
|
+
currentTarget[part] = parseMediaValue(rawVal, Boolean(leafDef.multiple));
|
|
5665
|
+
} else if (leafDef.type === "date" || leafDef.type === "time" || leafDef.type === "datetime" || leafDef.type === "timestamp") {
|
|
5666
|
+
currentTarget[part] = String(rawVal).trim() || null;
|
|
5667
|
+
} else if (leafDef.type === "email" || leafDef.type === "uid") {
|
|
5668
|
+
currentTarget[part] = String(rawVal).trim();
|
|
5669
|
+
} else if (leafDef.type === "password") {
|
|
5670
|
+
if (String(rawVal).trim()) {
|
|
5671
|
+
currentTarget[part] = String(rawVal).trim();
|
|
5672
|
+
}
|
|
5445
5673
|
} else if (leafDef.type === "json") {
|
|
5446
5674
|
try {
|
|
5447
5675
|
currentTarget[part] = JSON.parse(rawVal);
|
|
@@ -5456,19 +5684,6 @@ function parseRowToPayload(strapi, attrs, row) {
|
|
|
5456
5684
|
}
|
|
5457
5685
|
} catch {
|
|
5458
5686
|
}
|
|
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
5687
|
} else {
|
|
5473
5688
|
currentTarget[part] = rawVal;
|
|
5474
5689
|
}
|
|
@@ -5507,27 +5722,53 @@ function parseRowToPayload(strapi, attrs, row) {
|
|
|
5507
5722
|
}
|
|
5508
5723
|
}
|
|
5509
5724
|
if (!attrDef) continue;
|
|
5725
|
+
if (attrDef?.target?.includes("review-workflow") || attrDef?.target === "admin::review-workflow-stage") {
|
|
5726
|
+
continue;
|
|
5727
|
+
}
|
|
5510
5728
|
if (rawVal === "" || rawVal === null || rawVal === void 0) {
|
|
5511
|
-
if (attrDef.type !== "dynamiczone" && !(attrDef.type === "component" && attrDef.repeatable)) {
|
|
5729
|
+
if (attrDef.type !== "dynamiczone" && !(attrDef.type === "component" && attrDef.repeatable) && attrDef.type !== "relation" && attrDef.type !== "password") {
|
|
5512
5730
|
payload[key] = null;
|
|
5513
5731
|
}
|
|
5514
5732
|
continue;
|
|
5515
5733
|
}
|
|
5516
5734
|
switch (attrDef.type) {
|
|
5517
5735
|
case "integer":
|
|
5518
|
-
case "biginteger":
|
|
5519
|
-
|
|
5520
|
-
payload[key] = isNaN(parsedInt) ? null : parsedInt;
|
|
5736
|
+
case "biginteger":
|
|
5737
|
+
payload[key] = parseNumberValue(rawVal, true);
|
|
5521
5738
|
break;
|
|
5522
|
-
}
|
|
5523
5739
|
case "float":
|
|
5524
|
-
case "decimal":
|
|
5525
|
-
|
|
5526
|
-
payload[key] = isNaN(parsedFloat) ? null : parsedFloat;
|
|
5740
|
+
case "decimal":
|
|
5741
|
+
payload[key] = parseNumberValue(rawVal, false);
|
|
5527
5742
|
break;
|
|
5528
|
-
}
|
|
5529
5743
|
case "boolean":
|
|
5530
|
-
payload[key] = rawVal
|
|
5744
|
+
payload[key] = parseBooleanValue(rawVal);
|
|
5745
|
+
break;
|
|
5746
|
+
case "blocks":
|
|
5747
|
+
payload[key] = parseBlocksValue(rawVal);
|
|
5748
|
+
break;
|
|
5749
|
+
case "enumeration":
|
|
5750
|
+
payload[key] = parseEnumValue(rawVal, attrDef.enum);
|
|
5751
|
+
break;
|
|
5752
|
+
case "relation":
|
|
5753
|
+
payload[key] = parseRelationValue(rawVal, attrDef.relation);
|
|
5754
|
+
break;
|
|
5755
|
+
case "media":
|
|
5756
|
+
payload[key] = parseMediaValue(rawVal, Boolean(attrDef.multiple));
|
|
5757
|
+
break;
|
|
5758
|
+
case "date":
|
|
5759
|
+
case "time":
|
|
5760
|
+
case "datetime":
|
|
5761
|
+
case "timestamp":
|
|
5762
|
+
payload[key] = String(rawVal).trim() || null;
|
|
5763
|
+
break;
|
|
5764
|
+
case "email":
|
|
5765
|
+
case "uid":
|
|
5766
|
+
payload[key] = String(rawVal).trim();
|
|
5767
|
+
break;
|
|
5768
|
+
case "password":
|
|
5769
|
+
if (String(rawVal).trim()) {
|
|
5770
|
+
payload[key] = String(rawVal).trim();
|
|
5771
|
+
}
|
|
5531
5772
|
break;
|
|
5532
5773
|
case "json":
|
|
5533
5774
|
try {
|
|
@@ -5566,39 +5807,6 @@ function parseRowToPayload(strapi, attrs, row) {
|
|
|
5566
5807
|
}
|
|
5567
5808
|
break;
|
|
5568
5809
|
}
|
|
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
5810
|
default:
|
|
5603
5811
|
payload[key] = rawVal;
|
|
5604
5812
|
}
|
|
@@ -5635,10 +5843,12 @@ async function processCsvRows(strapi, ct, uid, rows, startRowNumber, options) {
|
|
|
5635
5843
|
const row = rows[i];
|
|
5636
5844
|
let docId = extractDocId(row);
|
|
5637
5845
|
const rowLocale = extractLocale(row);
|
|
5846
|
+
const effectiveLocale = getEffectiveLocale(ct, rowLocale);
|
|
5847
|
+
const isEditing = isRowInEditingStage(row);
|
|
5638
5848
|
if (ct.kind === "singleType" && !docId) {
|
|
5639
5849
|
try {
|
|
5640
5850
|
const findSingleArgs = {};
|
|
5641
|
-
if (
|
|
5851
|
+
if (effectiveLocale) findSingleArgs.locale = effectiveLocale;
|
|
5642
5852
|
const singleDoc = await strapi.documents(uid).findFirst(findSingleArgs);
|
|
5643
5853
|
if (singleDoc?.documentId) {
|
|
5644
5854
|
docId = singleDoc.documentId;
|
|
@@ -5657,7 +5867,7 @@ async function processCsvRows(strapi, ct, uid, rows, startRowNumber, options) {
|
|
|
5657
5867
|
});
|
|
5658
5868
|
continue;
|
|
5659
5869
|
}
|
|
5660
|
-
const existing = await findExistingDocument(strapi, uid, docId,
|
|
5870
|
+
const existing = await findExistingDocument(strapi, uid, docId, effectiveLocale);
|
|
5661
5871
|
if (!existing) {
|
|
5662
5872
|
stats.skipped++;
|
|
5663
5873
|
stats.errors.push({
|
|
@@ -5693,14 +5903,14 @@ async function processCsvRows(strapi, ct, uid, rows, startRowNumber, options) {
|
|
|
5693
5903
|
documentId: resolvedDocId,
|
|
5694
5904
|
data: mergedPayload
|
|
5695
5905
|
};
|
|
5696
|
-
if (
|
|
5906
|
+
if (effectiveLocale) updateArgs.locale = effectiveLocale;
|
|
5697
5907
|
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);
|
|
5908
|
+
const isApproved = !isEditing && isDraftAndPublish && Boolean(existing?.publishedAt) && existing?.status !== "modified";
|
|
5909
|
+
const shouldPublish = !isEditing && isDraftAndPublish && Boolean(publish) && (publishStrategy === "all" || options.unreviewedConsent ? true : isApproved);
|
|
5700
5910
|
if (shouldPublish) {
|
|
5701
5911
|
try {
|
|
5702
5912
|
const pubArgs = { documentId: resolvedDocId };
|
|
5703
|
-
if (
|
|
5913
|
+
if (effectiveLocale) pubArgs.locale = effectiveLocale;
|
|
5704
5914
|
await strapi.documents(uid).publish(pubArgs);
|
|
5705
5915
|
} catch (pubErr) {
|
|
5706
5916
|
strapi.log.warn(`[bulk-updater] Auto-publish failed for ${resolvedDocId}:`, pubErr);
|
|
@@ -5711,7 +5921,7 @@ async function processCsvRows(strapi, ct, uid, rows, startRowNumber, options) {
|
|
|
5711
5921
|
uid,
|
|
5712
5922
|
documentId: resolvedDocId,
|
|
5713
5923
|
userId: user?.id,
|
|
5714
|
-
statusOverride: shouldPublish ? "published" : isDraftAndPublish ? "draft" : void 0
|
|
5924
|
+
statusOverride: shouldPublish ? "published" : isDraftAndPublish ? existing?.publishedAt ? "modified" : "draft" : void 0
|
|
5715
5925
|
});
|
|
5716
5926
|
} catch {
|
|
5717
5927
|
}
|
|
@@ -5734,7 +5944,7 @@ async function processCsvRows(strapi, ct, uid, rows, startRowNumber, options) {
|
|
|
5734
5944
|
} else if (mode === "create_or_override") {
|
|
5735
5945
|
let existing = null;
|
|
5736
5946
|
if (docId) {
|
|
5737
|
-
existing = await findExistingDocument(strapi, uid, docId,
|
|
5947
|
+
existing = await findExistingDocument(strapi, uid, docId, effectiveLocale);
|
|
5738
5948
|
}
|
|
5739
5949
|
if (existing) {
|
|
5740
5950
|
const resolvedDocId = existing.documentId || docId;
|
|
@@ -5748,14 +5958,14 @@ async function processCsvRows(strapi, ct, uid, rows, startRowNumber, options) {
|
|
|
5748
5958
|
documentId: resolvedDocId,
|
|
5749
5959
|
data: mergedPayload
|
|
5750
5960
|
};
|
|
5751
|
-
if (
|
|
5961
|
+
if (effectiveLocale) updateArgs.locale = effectiveLocale;
|
|
5752
5962
|
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);
|
|
5963
|
+
const isApproved = !isEditing && isDraftAndPublish && Boolean(existing?.publishedAt) && existing?.status !== "modified";
|
|
5964
|
+
const shouldPublish = !isEditing && isDraftAndPublish && Boolean(publish) && (publishStrategy === "all" || options.unreviewedConsent ? true : isApproved);
|
|
5755
5965
|
if (shouldPublish) {
|
|
5756
5966
|
try {
|
|
5757
5967
|
const pubArgs = { documentId: resolvedDocId };
|
|
5758
|
-
if (
|
|
5968
|
+
if (effectiveLocale) pubArgs.locale = effectiveLocale;
|
|
5759
5969
|
await strapi.documents(uid).publish(pubArgs);
|
|
5760
5970
|
} catch (pubErr) {
|
|
5761
5971
|
strapi.log.warn(`[bulk-updater] Auto-publish failed for ${resolvedDocId}:`, pubErr);
|
|
@@ -5766,7 +5976,7 @@ async function processCsvRows(strapi, ct, uid, rows, startRowNumber, options) {
|
|
|
5766
5976
|
uid,
|
|
5767
5977
|
documentId: resolvedDocId,
|
|
5768
5978
|
userId: user?.id,
|
|
5769
|
-
statusOverride: shouldPublish ? "published" : isDraftAndPublish ? "draft" : void 0
|
|
5979
|
+
statusOverride: shouldPublish ? "published" : isDraftAndPublish ? existing?.publishedAt ? "modified" : "draft" : void 0
|
|
5770
5980
|
});
|
|
5771
5981
|
} catch {
|
|
5772
5982
|
}
|
|
@@ -5789,14 +5999,14 @@ async function processCsvRows(strapi, ct, uid, rows, startRowNumber, options) {
|
|
|
5789
5999
|
continue;
|
|
5790
6000
|
}
|
|
5791
6001
|
const createArgs = { data: payload };
|
|
5792
|
-
if (
|
|
6002
|
+
if (effectiveLocale) createArgs.locale = effectiveLocale;
|
|
5793
6003
|
const created = await strapi.documents(uid).create(createArgs);
|
|
5794
6004
|
const newDocId = created?.documentId || docId;
|
|
5795
|
-
const shouldPublishNew = isDraftAndPublish && Boolean(publish) && (publishStrategy === "all" || options.unreviewedConsent ? true : false);
|
|
6005
|
+
const shouldPublishNew = !isEditing && isDraftAndPublish && Boolean(publish) && (publishStrategy === "all" || options.unreviewedConsent ? true : false);
|
|
5796
6006
|
if (shouldPublishNew && newDocId) {
|
|
5797
6007
|
try {
|
|
5798
6008
|
const pubArgs = { documentId: newDocId };
|
|
5799
|
-
if (
|
|
6009
|
+
if (effectiveLocale) pubArgs.locale = effectiveLocale;
|
|
5800
6010
|
await strapi.documents(uid).publish(pubArgs);
|
|
5801
6011
|
} catch (pubErr) {
|
|
5802
6012
|
strapi.log.warn(`[bulk-updater] Auto-publish failed for ${newDocId}:`, pubErr);
|
|
@@ -5831,7 +6041,7 @@ async function processCsvRows(strapi, ct, uid, rows, startRowNumber, options) {
|
|
|
5831
6041
|
} else {
|
|
5832
6042
|
let existing = null;
|
|
5833
6043
|
if (docId) {
|
|
5834
|
-
existing = await findExistingDocument(strapi, uid, docId,
|
|
6044
|
+
existing = await findExistingDocument(strapi, uid, docId, effectiveLocale);
|
|
5835
6045
|
}
|
|
5836
6046
|
if (existing) {
|
|
5837
6047
|
const resolvedDocId = existing.documentId || docId;
|
|
@@ -5845,14 +6055,14 @@ async function processCsvRows(strapi, ct, uid, rows, startRowNumber, options) {
|
|
|
5845
6055
|
documentId: resolvedDocId,
|
|
5846
6056
|
data: mergedPayload
|
|
5847
6057
|
};
|
|
5848
|
-
if (
|
|
6058
|
+
if (effectiveLocale) updateArgs.locale = effectiveLocale;
|
|
5849
6059
|
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);
|
|
6060
|
+
const isApproved = !isEditing && isDraftAndPublish && Boolean(existing?.publishedAt) && existing?.status !== "modified";
|
|
6061
|
+
const shouldPublish = !isEditing && isDraftAndPublish && Boolean(publish) && (publishStrategy === "all" || options.unreviewedConsent ? true : isApproved);
|
|
5852
6062
|
if (shouldPublish) {
|
|
5853
6063
|
try {
|
|
5854
6064
|
const pubArgs = { documentId: resolvedDocId };
|
|
5855
|
-
if (
|
|
6065
|
+
if (effectiveLocale) pubArgs.locale = effectiveLocale;
|
|
5856
6066
|
await strapi.documents(uid).publish(pubArgs);
|
|
5857
6067
|
} catch (pubErr) {
|
|
5858
6068
|
strapi.log.warn(`[bulk-updater] Auto-publish failed for ${resolvedDocId}:`, pubErr);
|
|
@@ -5863,7 +6073,7 @@ async function processCsvRows(strapi, ct, uid, rows, startRowNumber, options) {
|
|
|
5863
6073
|
uid,
|
|
5864
6074
|
documentId: resolvedDocId,
|
|
5865
6075
|
userId: user?.id,
|
|
5866
|
-
statusOverride: shouldPublish ? "published" : isDraftAndPublish ? "draft" : void 0
|
|
6076
|
+
statusOverride: shouldPublish ? "published" : isDraftAndPublish ? existing?.publishedAt ? "modified" : "draft" : void 0
|
|
5867
6077
|
});
|
|
5868
6078
|
} catch {
|
|
5869
6079
|
}
|
|
@@ -5886,14 +6096,14 @@ async function processCsvRows(strapi, ct, uid, rows, startRowNumber, options) {
|
|
|
5886
6096
|
continue;
|
|
5887
6097
|
}
|
|
5888
6098
|
const createArgs = { data: payload };
|
|
5889
|
-
if (
|
|
6099
|
+
if (effectiveLocale) createArgs.locale = effectiveLocale;
|
|
5890
6100
|
const created = await strapi.documents(uid).create(createArgs);
|
|
5891
6101
|
const newDocId = created?.documentId || docId;
|
|
5892
|
-
const shouldPublishNew = isDraftAndPublish && Boolean(publish) && (publishStrategy === "all" || options.unreviewedConsent ? true : false);
|
|
6102
|
+
const shouldPublishNew = !isEditing && isDraftAndPublish && Boolean(publish) && (publishStrategy === "all" || options.unreviewedConsent ? true : false);
|
|
5893
6103
|
if (shouldPublishNew && newDocId) {
|
|
5894
6104
|
try {
|
|
5895
6105
|
const pubArgs = { documentId: newDocId };
|
|
5896
|
-
if (
|
|
6106
|
+
if (effectiveLocale) pubArgs.locale = effectiveLocale;
|
|
5897
6107
|
await strapi.documents(uid).publish(pubArgs);
|
|
5898
6108
|
} catch (pubErr) {
|
|
5899
6109
|
strapi.log.warn(`[bulk-updater] Auto-publish failed for ${newDocId}:`, pubErr);
|
|
@@ -6488,17 +6698,19 @@ const csvService = ({ strapi }) => ({
|
|
|
6488
6698
|
const row = rows[i];
|
|
6489
6699
|
const docId = extractDocId(row);
|
|
6490
6700
|
const rowLocale = extractLocale(row);
|
|
6701
|
+
const effectiveLocale = getEffectiveLocale(ct, rowLocale);
|
|
6702
|
+
const isEditing = isRowInEditingStage(row);
|
|
6491
6703
|
let rowHasError = false;
|
|
6492
6704
|
let existing = null;
|
|
6493
6705
|
if (docId) {
|
|
6494
|
-
existing = await findExistingDocument(strapi, uid, docId,
|
|
6706
|
+
existing = await findExistingDocument(strapi, uid, docId, effectiveLocale);
|
|
6495
6707
|
}
|
|
6496
6708
|
if (existing && isDraftAndPublish) {
|
|
6497
6709
|
lifecycleStats.totalChecked++;
|
|
6498
|
-
const isApproved = Boolean(existing.publishedAt) && existing.status !== "modified";
|
|
6710
|
+
const isApproved = !isEditing && Boolean(existing.publishedAt) && existing.status !== "modified";
|
|
6499
6711
|
if (isApproved) {
|
|
6500
6712
|
lifecycleStats.published++;
|
|
6501
|
-
} else if (existing.status === "modified") {
|
|
6713
|
+
} else if (existing.status === "modified" || existing.publishedAt && isEditing) {
|
|
6502
6714
|
lifecycleStats.modified++;
|
|
6503
6715
|
lifecycleStats.unreviewedCount++;
|
|
6504
6716
|
} else {
|
|
@@ -6654,10 +6866,11 @@ const csvService = ({ strapi }) => ({
|
|
|
6654
6866
|
const row = rows[i];
|
|
6655
6867
|
let docId = extractDocId(row);
|
|
6656
6868
|
const rowLocale = extractLocale(row);
|
|
6869
|
+
const effectiveLocale = getEffectiveLocale(ct, rowLocale);
|
|
6657
6870
|
if (ct.kind === "singleType" && !docId) {
|
|
6658
6871
|
try {
|
|
6659
6872
|
const findSingleArgs = {};
|
|
6660
|
-
if (
|
|
6873
|
+
if (effectiveLocale) findSingleArgs.locale = effectiveLocale;
|
|
6661
6874
|
const singleDoc = await strapi.documents(uid).findFirst(findSingleArgs);
|
|
6662
6875
|
if (singleDoc?.documentId) {
|
|
6663
6876
|
docId = singleDoc.documentId;
|
|
@@ -6667,7 +6880,7 @@ const csvService = ({ strapi }) => ({
|
|
|
6667
6880
|
}
|
|
6668
6881
|
let existing = null;
|
|
6669
6882
|
if (docId) {
|
|
6670
|
-
existing = await findExistingDocument(strapi, uid, docId,
|
|
6883
|
+
existing = await findExistingDocument(strapi, uid, docId, effectiveLocale);
|
|
6671
6884
|
}
|
|
6672
6885
|
if (mode === "update" && (!docId || !existing)) {
|
|
6673
6886
|
skippedCount++;
|