strapi-plugin-bulk-updater 1.5.0 → 1.5.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -68,7 +68,7 @@ const index = {
68
68
  id: `${PLUGIN_ID}.plugin.name`,
69
69
  defaultMessage: "Bulk Attribute Updater"
70
70
  },
71
- Component: () => Promise.resolve().then(() => require("../_chunks/BulkUpdater-CSmtXjbM.js")),
71
+ Component: () => Promise.resolve().then(() => require("../_chunks/BulkUpdater-JZW74XM4.js")),
72
72
  permissions: [],
73
73
  position: 3
74
74
  });
@@ -65,7 +65,7 @@ const index = {
65
65
  id: `${PLUGIN_ID}.plugin.name`,
66
66
  defaultMessage: "Bulk Attribute Updater"
67
67
  },
68
- Component: () => import("../_chunks/BulkUpdater-By9Dd_YF.mjs"),
68
+ Component: () => import("../_chunks/BulkUpdater-BiSkkAHF.mjs"),
69
69
  permissions: [],
70
70
  position: 3
71
71
  });
@@ -1116,14 +1116,15 @@ function discoverComponentAttributes(strapi, compUid, prefix, currentDepth, maxD
1116
1116
  }
1117
1117
  function parseDynamicZonePath(path) {
1118
1118
  if (!path) return { cleanPath: "", rootKey: "", subPath: "" };
1119
- const bracketMatch = path.match(/^([^.[]+)\[([^\]]+)\]\.(.+)$/);
1119
+ const bracketMatch = path.match(/^([^.[]+)\[([^\]]+)\](?:\.(.+))?$/);
1120
1120
  if (bracketMatch) {
1121
1121
  const rootKey = bracketMatch[1];
1122
- const selector = bracketMatch[2];
1123
- const subPath = bracketMatch[3];
1124
- const cleanPath = `${rootKey}.${subPath}`;
1125
- if (/^\d+$/.test(selector)) {
1126
- return { cleanPath, rootKey, subPath, targetIndex: parseInt(selector, 10) };
1122
+ const selector = bracketMatch[2].trim();
1123
+ const subPath = bracketMatch[3] || "";
1124
+ const cleanPath = subPath ? `${rootKey}.${subPath}` : rootKey;
1125
+ const numMatch = selector.match(/^#?(\d+)/);
1126
+ if (numMatch) {
1127
+ return { cleanPath, rootKey, subPath, targetIndex: parseInt(numMatch[1], 10) };
1127
1128
  }
1128
1129
  return { cleanPath, rootKey, subPath, targetComponentUid: selector };
1129
1130
  }
@@ -4276,42 +4277,74 @@ const auditService = ({ strapi }) => ({
4276
4277
  for (const item of diffs) {
4277
4278
  if (item.status === "updated" && item.uid && item.documentId && item.attribute) {
4278
4279
  try {
4280
+ const ct = strapi.contentTypes[item.uid];
4281
+ if (!ct) {
4282
+ throw new Error(`Content type "${item.uid}" does not exist in schema.`);
4283
+ }
4279
4284
  const isRel = item.oldValue && typeof item.oldValue === "object" && item.oldValue.isRelation;
4280
4285
  let rollbackPayload;
4281
4286
  if (isRel) {
4282
4287
  const oldDocIds = Array.isArray(item.oldValue.documentIds) ? item.oldValue.documentIds : [];
4283
4288
  rollbackPayload = { set: oldDocIds };
4284
4289
  } else {
4285
- rollbackPayload = item.oldValue;
4290
+ rollbackPayload = item.oldValue ?? null;
4286
4291
  }
4287
- if (item.attribute.includes(".")) {
4288
- const [parentKey, childKey] = item.attribute.split(".");
4289
- const ct2 = strapi.contentTypes[item.uid];
4290
- if (ct2?.attributes?.[parentKey]?.type === "component") {
4291
- const currentDoc = await strapi.documents(item.uid).findOne({
4292
- documentId: item.documentId,
4293
- populate: [parentKey]
4294
- });
4295
- const currentParent = currentDoc?.[parentKey] || {};
4296
- const restoredParent = {
4297
- ...currentParent,
4298
- [childKey]: rollbackPayload
4299
- };
4300
- await strapi.documents(item.uid).update({
4301
- documentId: item.documentId,
4302
- data: {
4303
- [parentKey]: restoredParent
4304
- }
4305
- });
4292
+ const parsed = parseDynamicZonePath(item.attribute);
4293
+ const rootKey = parsed.rootKey;
4294
+ const rootAttrDef = ct.attributes?.[rootKey];
4295
+ const isComponent = rootAttrDef?.type === "component";
4296
+ const isDynamicZone = rootAttrDef?.type === "dynamiczone";
4297
+ const isNested = item.attribute.includes(".") || item.attribute.includes("[") || isComponent || isDynamicZone || isDeepComponentField(ct, strapi.components, item.attribute);
4298
+ let wasPublished = false;
4299
+ if (isNested && (isComponent || isDynamicZone || rootAttrDef)) {
4300
+ const populateOption = buildDeepPopulate$1(ct.attributes, strapi.components);
4301
+ const findOneArgs = { documentId: item.documentId };
4302
+ if (populateOption) {
4303
+ findOneArgs.populate = populateOption;
4304
+ }
4305
+ const currentDoc = await strapi.documents(item.uid).findOne(findOneArgs);
4306
+ if (!currentDoc) {
4307
+ throw new Error(`Document "${item.documentId}" not found in collection "${item.uid}".`);
4308
+ }
4309
+ wasPublished = Boolean(currentDoc?.publishedAt);
4310
+ const isRootDz = isDynamicZone;
4311
+ const existingRoot = currentDoc?.[rootKey] || (isRootDz ? [] : {});
4312
+ let restoredRoot;
4313
+ if (Array.isArray(item.dynamicZoneDiffs) && item.dynamicZoneDiffs.length > 0) {
4314
+ let workingRoot = existingRoot;
4315
+ for (const dzDiff of item.dynamicZoneDiffs) {
4316
+ const parsedDz = parseDynamicZonePath(dzDiff.attribute || item.attribute);
4317
+ const dzParts = parsedDz.cleanPath.split(".").slice(1);
4318
+ const targetIndexes = dzDiff.index !== void 0 ? [dzDiff.index] : parsedDz.targetIndex !== void 0 ? [parsedDz.targetIndex] : void 0;
4319
+ workingRoot = setDeepProperty(workingRoot, dzParts, dzDiff.oldValue ?? null, {
4320
+ targetIndexes,
4321
+ targetComponentUid: dzDiff.componentUid || parsedDz.targetComponentUid,
4322
+ strapi
4323
+ });
4324
+ }
4325
+ restoredRoot = workingRoot;
4306
4326
  } else {
4307
- await strapi.documents(item.uid).update({
4308
- documentId: item.documentId,
4309
- data: {
4310
- [item.attribute]: rollbackPayload
4311
- }
4327
+ const parts = parsed.cleanPath.split(".");
4328
+ const pathParts = parts.slice(1);
4329
+ const targetIndexes = parsed.targetIndex !== void 0 ? [parsed.targetIndex] : void 0;
4330
+ const targetComponentUid = parsed.targetComponentUid;
4331
+ restoredRoot = setDeepProperty(existingRoot, pathParts, rollbackPayload, {
4332
+ targetIndexes,
4333
+ targetComponentUid,
4334
+ strapi
4312
4335
  });
4313
4336
  }
4337
+ await strapi.documents(item.uid).update({
4338
+ documentId: item.documentId,
4339
+ data: {
4340
+ [rootKey]: restoredRoot
4341
+ }
4342
+ });
4314
4343
  } else {
4344
+ const currentDoc = await strapi.documents(item.uid).findOne({
4345
+ documentId: item.documentId
4346
+ });
4347
+ wasPublished = Boolean(currentDoc?.publishedAt);
4315
4348
  await strapi.documents(item.uid).update({
4316
4349
  documentId: item.documentId,
4317
4350
  data: {
@@ -4319,13 +4352,13 @@ const auditService = ({ strapi }) => ({
4319
4352
  }
4320
4353
  });
4321
4354
  }
4322
- const ct = strapi.contentTypes[item.uid];
4323
- if (ct?.options?.draftAndPublish) {
4355
+ if (ct?.options?.draftAndPublish && wasPublished) {
4324
4356
  try {
4325
4357
  await strapi.documents(item.uid).publish({
4326
4358
  documentId: item.documentId
4327
4359
  });
4328
- } catch {
4360
+ } catch (publishErr) {
4361
+ strapi.log.warn(`[bulk-updater] Failed to auto-publish rollback for ${item.uid}/${item.documentId}:`, publishErr?.message);
4329
4362
  }
4330
4363
  }
4331
4364
  try {
@@ -4333,7 +4366,7 @@ const auditService = ({ strapi }) => ({
4333
4366
  uid: item.uid,
4334
4367
  documentId: item.documentId,
4335
4368
  userId,
4336
- statusOverride: ct?.options?.draftAndPublish ? "published" : void 0
4369
+ statusOverride: ct?.options?.draftAndPublish ? wasPublished ? "published" : "draft" : void 0
4337
4370
  });
4338
4371
  } catch {
4339
4372
  }