@localazy/strapi-plugin 1.7.0 → 1.7.1

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.
@@ -20534,7 +20534,7 @@ var distExports = dist$1.exports;
20534
20534
  const io = /* @__PURE__ */ getDefaultExportFromCjs(distExports);
20535
20535
  const { Server: Server2, Namespace, Socket: Socket3 } = io;
20536
20536
  const name = "@localazy/strapi-plugin";
20537
- const version = "1.7.0";
20537
+ const version = "1.7.1";
20538
20538
  const description = "The official Strapi Plugin by Localazy.";
20539
20539
  const keywords = [
20540
20540
  "strapi",
@@ -22052,7 +22052,7 @@ const findSetupModelByCollectionUid = (contentTransferSetup, strapiContentTypesM
22052
22052
  const modelContentTransferSetup = contentTransferSetup.setup.find(
22053
22053
  (model) => Object.keys(model)[0] === currentModel.collectionName
22054
22054
  );
22055
- return modelContentTransferSetup[currentModel.collectionName];
22055
+ return modelContentTransferSetup?.[currentModel.collectionName];
22056
22056
  };
22057
22057
  const getCollectionsNames = (setup2) => {
22058
22058
  return getMainKeysOfNestedArrayObjects(setup2);
@@ -26199,9 +26199,6 @@ const LocalazyTransferUploadService = ({ strapi: strapi2 }) => ({
26199
26199
  const hasDynamicZoneKeySegment = (parsedKey) => {
26200
26200
  return parsedKey.some((segment) => segment.includes(";"));
26201
26201
  };
26202
- const getDynamicZoneKeySegment = (parsedKey) => {
26203
- return parsedKey.find((segment) => segment.includes(";"));
26204
- };
26205
26202
  const getComponentNameFromDynamicZoneKeySegment = (dynamicZoneKeySegment) => {
26206
26203
  return dynamicZoneKeySegment.split(";")[1];
26207
26204
  };
@@ -26221,52 +26218,116 @@ var ShouldSetDownloadedPropertyReturnType = /* @__PURE__ */ ((ShouldSetDownloade
26221
26218
  ShouldSetDownloadedPropertyReturnType2["JSON"] = "json";
26222
26219
  return ShouldSetDownloadedPropertyReturnType2;
26223
26220
  })(ShouldSetDownloadedPropertyReturnType || {});
26224
- const shouldSetDownloadedProperty = (modelContentTransferSetup, parsedKeyRest) => {
26221
+ const locateDownloadedField = (modelContentTransferSetup, parsedKeyRest) => {
26222
+ const notFound = { type: "no", fieldSegmentIndex: -1 };
26225
26223
  if (!modelContentTransferSetup.__model__) {
26226
- return "no";
26224
+ return notFound;
26227
26225
  }
26226
+ let setupModel = modelContentTransferSetup;
26227
+ let startIndex2 = 0;
26228
26228
  if (hasDynamicZoneKeySegment(parsedKeyRest)) {
26229
- const dynamicZonePropertyName = getDynamicZonePropertyName(parsedKeyRest);
26230
- const componentName = getComponentNameFromDynamicZoneKeySegment(getDynamicZoneKeySegment(parsedKeyRest));
26229
+ const dynamicZoneKeySegmentIndex = getDynamicZoneKeySegmentIndex(parsedKeyRest);
26230
+ const componentName = getComponentNameFromDynamicZoneKeySegment(parsedKeyRest[dynamicZoneKeySegmentIndex]);
26231
26231
  const dzContentTransferSetupModel = get(
26232
26232
  modelContentTransferSetup,
26233
- dynamicZonePropertyName
26233
+ getDynamicZonePropertyName(parsedKeyRest)
26234
26234
  );
26235
26235
  if (!Array.isArray(dzContentTransferSetupModel)) {
26236
- return "no";
26236
+ return notFound;
26237
26237
  }
26238
- const dzContentTransferSetupComponentModel = dzContentTransferSetupModel.find(
26239
- (c2) => c2.__component__ === componentName
26240
- );
26241
- if (!dzContentTransferSetupComponentModel) {
26242
- return "no";
26238
+ setupModel = dzContentTransferSetupModel.find((c2) => c2.__component__ === componentName);
26239
+ if (!setupModel) {
26240
+ return notFound;
26243
26241
  }
26244
- const dynamicZoneKeySegmentIndex = getDynamicZoneKeySegmentIndex(parsedKeyRest);
26245
- const slicedParsedKeyRest = parsedKeyRest.slice(dynamicZoneKeySegmentIndex + 1);
26246
- const filteredSlicedParsedKeyRest = slicedParsedKeyRest.filter((segment) => isNaN(parseInt(segment)));
26247
- if (get(dzContentTransferSetupComponentModel, filteredSlicedParsedKeyRest) === true) {
26248
- return "yes";
26249
- }
26250
- while (filteredSlicedParsedKeyRest.length > 0) {
26251
- filteredSlicedParsedKeyRest.pop();
26252
- if (get(dzContentTransferSetupComponentModel, filteredSlicedParsedKeyRest) === true) {
26253
- return "json";
26242
+ startIndex2 = dynamicZoneKeySegmentIndex + 1;
26243
+ }
26244
+ const namedSegmentIndexes = [];
26245
+ for (let index2 = startIndex2; index2 < parsedKeyRest.length; index2++) {
26246
+ if (isNaN(parseInt(parsedKeyRest[index2]))) {
26247
+ namedSegmentIndexes.push(index2);
26248
+ }
26249
+ }
26250
+ for (let length2 = namedSegmentIndexes.length; length2 > 0; length2--) {
26251
+ const fieldPath = namedSegmentIndexes.slice(0, length2).map((index2) => parsedKeyRest[index2]);
26252
+ if (get(setupModel, fieldPath) === true) {
26253
+ const fieldSegmentIndex = namedSegmentIndexes[length2 - 1];
26254
+ const type2 = fieldSegmentIndex === parsedKeyRest.length - 1 ? "yes" : "json";
26255
+ return { type: type2, fieldSegmentIndex };
26256
+ }
26257
+ }
26258
+ return notFound;
26259
+ };
26260
+ const createJsonFieldsDownloadAccumulator = () => {
26261
+ const fields = /* @__PURE__ */ new Map();
26262
+ return {
26263
+ /**
26264
+ * @param fieldKey path to the field in the parsed content: `[iso, uid, documentId, ...ownerPath, fieldName]`
26265
+ * @param valuePath path of this leaf inside the field's value
26266
+ */
26267
+ add(fieldKey, valuePath, value) {
26268
+ const id = JSON.stringify(fieldKey);
26269
+ let field = fields.get(id);
26270
+ if (!field) {
26271
+ field = { fieldKey, value: {} };
26272
+ fields.set(id, field);
26273
+ }
26274
+ set(field.value, valuePath, value);
26275
+ },
26276
+ /** Write every collected field value into `parsedContent` at its own path. */
26277
+ applyTo(parsedContent) {
26278
+ for (const { fieldKey, value } of fields.values()) {
26279
+ set(parsedContent, fieldKey, value);
26254
26280
  }
26255
26281
  }
26256
- return "no";
26257
- } else {
26258
- const filteredParsedKeyRest = parsedKeyRest.filter((partialKey) => isNaN(parseInt(partialKey)));
26259
- if (get(modelContentTransferSetup, filteredParsedKeyRest) === true) {
26260
- return "yes";
26261
- }
26262
- while (filteredParsedKeyRest.length > 0) {
26263
- filteredParsedKeyRest.pop();
26264
- if (get(modelContentTransferSetup, filteredParsedKeyRest) === true) {
26265
- return "json";
26282
+ };
26283
+ };
26284
+ const collectDownloadedContent = ({
26285
+ languages: languages2,
26286
+ processedKeys,
26287
+ contentTransferSetup,
26288
+ models,
26289
+ parseLocalazyKey: parseLocalazyKey2
26290
+ }) => {
26291
+ const parsedLocalazyContent = {};
26292
+ const entryKeySourceMap = {};
26293
+ const jsonFieldsAccumulator = createJsonFieldsDownloadAccumulator();
26294
+ for (const { isoStrapi, keys: keys2 } of languages2) {
26295
+ const parsedKeys = keys2.map((localazyEntry) => {
26296
+ const storedEvent = processedKeys[isoStrapi]?.[localazyEntry.id];
26297
+ const isChanged = !(storedEvent !== void 0 && localazyEntry.event !== void 0 && localazyEntry.event <= storedEvent);
26298
+ const parsedKey = parseLocalazyKey2(localazyEntry.key[0]);
26299
+ return { localazyEntry, parsedKey, isChanged, entryKey: `${isoStrapi}:${parsedKey.uid}:${parsedKey.id}` };
26300
+ });
26301
+ for (const { localazyEntry, entryKey, isChanged } of parsedKeys) {
26302
+ if (isChanged) {
26303
+ if (!entryKeySourceMap[entryKey]) {
26304
+ entryKeySourceMap[entryKey] = [];
26305
+ }
26306
+ entryKeySourceMap[entryKey].push({ lang: isoStrapi, id: localazyEntry.id, event: localazyEntry.event });
26307
+ }
26308
+ }
26309
+ for (const { localazyEntry, parsedKey, entryKey } of parsedKeys) {
26310
+ if (!entryKeySourceMap[entryKey]) {
26311
+ continue;
26312
+ }
26313
+ const modelContentTransferSetup = findSetupModelByCollectionUid(contentTransferSetup, models, parsedKey.uid);
26314
+ if (typeof modelContentTransferSetup === "undefined") {
26315
+ continue;
26316
+ }
26317
+ const { type: type2, fieldSegmentIndex } = locateDownloadedField(modelContentTransferSetup, parsedKey.rest);
26318
+ if (type2 === ShouldSetDownloadedPropertyReturnType.JSON) {
26319
+ jsonFieldsAccumulator.add(
26320
+ [isoStrapi, parsedKey.uid, parsedKey.id, ...parsedKey.rest.slice(0, fieldSegmentIndex + 1)],
26321
+ parsedKey.rest.slice(fieldSegmentIndex + 1),
26322
+ localazyEntry.value
26323
+ );
26324
+ } else if (type2 === ShouldSetDownloadedPropertyReturnType.YES) {
26325
+ set(parsedLocalazyContent, [isoStrapi, parsedKey.uid, parsedKey.id, ...parsedKey.rest], localazyEntry.value);
26266
26326
  }
26267
26327
  }
26268
- return "no";
26269
26328
  }
26329
+ jsonFieldsAccumulator.applyTo(parsedLocalazyContent);
26330
+ return { parsedLocalazyContent, entryKeySourceMap };
26270
26331
  };
26271
26332
  const getFilteredLanguagesCodesForDownload = async (languagesCodes, requestedUiLanguages) => {
26272
26333
  const pluginSettingsServiceHelper = new PluginSettingsServiceHelper();
@@ -26453,10 +26514,8 @@ const LocalazyTransferDownloadService = ({ strapi: strapi2 }) => ({
26453
26514
  }
26454
26515
  await persistCursor();
26455
26516
  };
26456
- const parsedLocalazyContent = {};
26457
26517
  const strapiContentTypesModels = await StrapiService2.getModels();
26458
- const jsonFields = [];
26459
- const entryKeySourceMap = {};
26518
+ const languagesToParse = [];
26460
26519
  for (const [isoLocalazy, keys2] of Object.entries(localazyContent)) {
26461
26520
  const isoStrapi = isoLocalazyToStrapi(isoLocalazy);
26462
26521
  if (!isoStrapi) {
@@ -26465,78 +26524,15 @@ const LocalazyTransferDownloadService = ({ strapi: strapi2 }) => ({
26465
26524
  });
26466
26525
  continue;
26467
26526
  }
26468
- for (const localazyEntry of keys2) {
26469
- const key = localazyEntry.key[0];
26470
- const value = localazyEntry.value;
26471
- const localazyKeyId = localazyEntry.id;
26472
- const localazyKeyEvent = localazyEntry.event;
26473
- const storedEvent = processedKeys[isoStrapi]?.[localazyKeyId];
26474
- if (storedEvent !== void 0 && localazyKeyEvent !== void 0 && localazyKeyEvent <= storedEvent) {
26475
- continue;
26476
- }
26477
- const parsedKey = StrapiI18nService2.parseLocalazyKey(key);
26478
- const entryKey = `${isoStrapi}:${parsedKey.uid}:${parsedKey.id}`;
26479
- if (!entryKeySourceMap[entryKey]) {
26480
- entryKeySourceMap[entryKey] = [];
26481
- }
26482
- entryKeySourceMap[entryKey].push({ lang: isoStrapi, id: localazyKeyId, event: localazyKeyEvent });
26483
- const modelContentTransferSetup = findSetupModelByCollectionUid(
26484
- contentTransferSetup,
26485
- strapiContentTypesModels,
26486
- parsedKey.uid
26487
- );
26488
- if (typeof modelContentTransferSetup !== "undefined") {
26489
- const shouldSetDownloadedPropertyResult = shouldSetDownloadedProperty(
26490
- modelContentTransferSetup,
26491
- parsedKey.rest
26492
- );
26493
- if (shouldSetDownloadedPropertyResult === ShouldSetDownloadedPropertyReturnType.NO) {
26494
- continue;
26495
- }
26496
- let parsedKeyRestWithoutComponents = parsedKey.rest;
26497
- if (shouldSetDownloadedPropertyResult === ShouldSetDownloadedPropertyReturnType.JSON) {
26498
- const setKey = [isoStrapi, parsedKey.uid, parsedKey.id];
26499
- let updatedParsedKeyRestWithoutComponents = parsedKeyRestWithoutComponents;
26500
- let segmentsToAdd = [];
26501
- for (const segment of parsedKeyRestWithoutComponents) {
26502
- const hasEntry = get(modelContentTransferSetup, [...segmentsToAdd, segment]);
26503
- const hasEntryNotFinal = hasEntry && typeof hasEntry !== "boolean";
26504
- const isComponent2 = parseInt(segment) > 0;
26505
- if (hasEntryNotFinal || !hasEntry && isComponent2) {
26506
- segmentsToAdd.push(segment);
26507
- setKey.push(segment);
26508
- updatedParsedKeyRestWithoutComponents = updatedParsedKeyRestWithoutComponents.slice(1);
26509
- } else {
26510
- break;
26511
- }
26512
- }
26513
- parsedKeyRestWithoutComponents = updatedParsedKeyRestWithoutComponents;
26514
- let foundJsonFieldIndex = jsonFields.findIndex((jsonField) => {
26515
- return jsonField.setKey.join() === setKey.join();
26516
- });
26517
- if (foundJsonFieldIndex === -1) {
26518
- jsonFields.push({
26519
- setKey,
26520
- jsonKey: parsedKeyRestWithoutComponents[0],
26521
- jsonValue: {}
26522
- });
26523
- }
26524
- foundJsonFieldIndex = foundJsonFieldIndex === -1 ? jsonFields.length - 1 : foundJsonFieldIndex;
26525
- const foundJsonField = jsonFields[foundJsonFieldIndex];
26526
- const restSliced = parsedKeyRestWithoutComponents.slice(1);
26527
- set(foundJsonField, ["jsonValue", ...restSliced], value);
26528
- jsonFields[foundJsonFieldIndex] = foundJsonField;
26529
- }
26530
- if (shouldSetDownloadedPropertyResult === ShouldSetDownloadedPropertyReturnType.YES) {
26531
- const setKey = [isoStrapi, parsedKey.uid, parsedKey.id, ...parsedKeyRestWithoutComponents];
26532
- set(parsedLocalazyContent, setKey, value);
26533
- }
26534
- }
26535
- }
26536
- }
26537
- for (const jsonField of jsonFields) {
26538
- set(parsedLocalazyContent, [...jsonField.setKey, jsonField.jsonKey], jsonField.jsonValue);
26539
- }
26527
+ languagesToParse.push({ isoStrapi, keys: keys2 });
26528
+ }
26529
+ const { parsedLocalazyContent, entryKeySourceMap } = collectDownloadedContent({
26530
+ languages: languagesToParse,
26531
+ processedKeys,
26532
+ contentTransferSetup,
26533
+ models: strapiContentTypesModels,
26534
+ parseLocalazyKey: (key) => StrapiI18nService2.parseLocalazyKey(key)
26535
+ });
26540
26536
  for (const [isoStrapi, contentTypes2] of Object.entries(parsedLocalazyContent)) {
26541
26537
  for (const [uid, models] of Object.entries(contentTypes2)) {
26542
26538
  const strapiContentTypeModel = strapiContentTypesModels.find((model) => model.uid === uid);
@@ -26720,6 +26716,15 @@ const intlDisplayName = (isoStrapi) => {
26720
26716
  }
26721
26717
  return languageNames.of(isoStrapi.toLowerCase());
26722
26718
  };
26719
+ const parseLocalazyKey = (key) => {
26720
+ const split = key.split(/\.(?![^[]*])|\[|\]/);
26721
+ const filteredSplit = split.filter((item) => item !== "");
26722
+ return {
26723
+ uid: `${filteredSplit[0]}.${filteredSplit[1]}`,
26724
+ id: filteredSplit[2],
26725
+ rest: filteredSplit.slice(3)
26726
+ };
26727
+ };
26723
26728
  const StrapiI18nService = ({ strapi: strapi2 }) => ({
26724
26729
  async getLocales() {
26725
26730
  return strapi2.plugin("i18n").service("locales").find();
@@ -26747,13 +26752,7 @@ const StrapiI18nService = ({ strapi: strapi2 }) => ({
26747
26752
  }
26748
26753
  },
26749
26754
  parseLocalazyKey(key) {
26750
- const split = key.split(/\.(?![^[]*])|\[|\]/);
26751
- const filteredSplit = split.filter((item) => item !== "");
26752
- return {
26753
- uid: `${filteredSplit[0]}.${filteredSplit[1]}`,
26754
- id: filteredSplit[2],
26755
- rest: filteredSplit.slice(3)
26756
- };
26755
+ return parseLocalazyKey(key);
26757
26756
  },
26758
26757
  async getEntryInLocale(modelUid, documentId, isoStrapi) {
26759
26758
  const entry = await strapi2.documents(modelUid).findOne({
@@ -26852,18 +26851,6 @@ const LocalazyUploadService = ({ strapi: strapi2 }) => ({
26852
26851
  return file;
26853
26852
  }
26854
26853
  });
26855
- const resetArrayKeysDeep = (object, keysToFilter) => {
26856
- const sortedKeysToFilter = keysToFilter.sort((a2, b2) => {
26857
- const aLvl = a2.match(/\./g)?.length || 0;
26858
- const bLvl = b2.match(/\./g)?.length || 0;
26859
- return bLvl - aLvl;
26860
- });
26861
- for (const key of sortedKeysToFilter) {
26862
- const part = get(object, key);
26863
- const filteredPart = part.filter((item) => item !== void 0);
26864
- set(object, key, filteredPart);
26865
- }
26866
- };
26867
26854
  const getAttribute = (model, attribute) => {
26868
26855
  if (isEmpty(model)) {
26869
26856
  return void 0;
@@ -26886,22 +26873,63 @@ const isRelation = (attributeObj) => {
26886
26873
  const isBlocks = (attributeObj) => {
26887
26874
  return attributeObj.type === BLOCKS_ATTRIBUTE_TYPE;
26888
26875
  };
26876
+ const isJson = (attributeObj) => {
26877
+ return attributeObj.type === "json";
26878
+ };
26889
26879
  const findModel = (models, uid) => {
26890
26880
  const model = models.find((model2) => model2.uid === uid);
26891
26881
  return model;
26892
26882
  };
26883
+ const arrayItemSegment = (item, index2) => {
26884
+ if (isPlainObject(item) && item.id && item.__component) {
26885
+ return `${item.id};${item.__component}`;
26886
+ }
26887
+ return String(item?.documentId || item?.id || index2);
26888
+ };
26889
+ const objectIdSegment = (value) => {
26890
+ if (isPlainObject(value) && (value.documentId || value.id)) {
26891
+ return String(value.documentId || value.id);
26892
+ }
26893
+ return void 0;
26894
+ };
26895
+ const overlayValue = (source, translated) => {
26896
+ if (typeof source === "string") {
26897
+ return typeof translated === "string" ? translated : source;
26898
+ }
26899
+ if (Array.isArray(source)) {
26900
+ return source.map((item, index2) => overlayValue(item, get(translated, [arrayItemSegment(item, index2)])));
26901
+ }
26902
+ if (isPlainObject(source)) {
26903
+ const result = {};
26904
+ for (const [key, value] of Object.entries(source)) {
26905
+ result[key] = key === "id" || key === "documentId" ? value : overlayChild(value, get(translated, [key]));
26906
+ }
26907
+ return result;
26908
+ }
26909
+ return source;
26910
+ };
26911
+ const overlayChild = (source, translated) => {
26912
+ const idSegment = Array.isArray(source) ? void 0 : objectIdSegment(source);
26913
+ return overlayValue(source, idSegment ? get(translated, [idSegment]) : translated);
26914
+ };
26915
+ const overlayJsonTranslation = (sourceValue, translated) => {
26916
+ if (sourceValue === void 0 || sourceValue === null) {
26917
+ return void 0;
26918
+ }
26919
+ if (typeof sourceValue !== "object") {
26920
+ return typeof sourceValue === "string" && typeof translated === "string" ? translated : sourceValue;
26921
+ }
26922
+ return overlayChild(cloneDeep(sourceValue), translated);
26923
+ };
26893
26924
  const parsedLocalazyEntryToCreateEntry = (models, parsedLocalazyEntry, baseEntry, uid, locale = "") => {
26894
26925
  const createEntry = {};
26895
- const repeatableComponentsKeystoFilter = [];
26896
26926
  const dynamicZoneComponentKeys = [];
26927
+ const rebuiltFieldPaths = [];
26897
26928
  const toCreateEntry = (entry, model2, key = "", prefix = "", component = "", isRepeatableComponent = false, isDZ = false, isInsideDZ = false) => {
26898
26929
  if (Array.isArray(entry)) {
26899
26930
  Object.entries(entry).forEach(([baseEntryItemId, value]) => {
26900
26931
  if (value !== null) {
26901
26932
  if (component && isRepeatableComponent) {
26902
- if (!repeatableComponentsKeystoFilter.includes(prefix)) {
26903
- repeatableComponentsKeystoFilter.push(prefix);
26904
- }
26905
26933
  const baseEntryRepeatableItemId = parseInt(baseEntryItemId);
26906
26934
  const baseEntryRepeateableGroup = get(baseEntry, prefix);
26907
26935
  if (baseEntryRepeateableGroup !== void 0) {
@@ -26923,9 +26951,6 @@ const parsedLocalazyEntryToCreateEntry = (models, parsedLocalazyEntry, baseEntry
26923
26951
  toCreateEntry(value, model2, `${prefix}`, `${prefix}`);
26924
26952
  }
26925
26953
  if (!component && isRepeatableComponent) {
26926
- if (!repeatableComponentsKeystoFilter.includes(prefix)) {
26927
- repeatableComponentsKeystoFilter.push(prefix);
26928
- }
26929
26954
  const baseEntryRepeatableItemId = parseInt(baseEntryItemId);
26930
26955
  const baseEntryRepeateableGroup = get(baseEntry, prefix);
26931
26956
  if (baseEntryRepeateableGroup !== void 0) {
@@ -27029,11 +27054,20 @@ const parsedLocalazyEntryToCreateEntry = (models, parsedLocalazyEntry, baseEntry
27029
27054
  newPrefixBase = `${dzParamKey}.${baseEntryDZIndex}`;
27030
27055
  newPrefix = `${newPrefixBase}.${objectKey}`;
27031
27056
  }
27032
- const valueToSet = isBlocks(attribute) ? overlayBlocksTranslation(get(baseEntry, newPrefix), value) : value;
27057
+ const isRebuiltField = isBlocks(attribute) || isJson(attribute);
27058
+ let valueToSet = value;
27059
+ if (isBlocks(attribute)) {
27060
+ valueToSet = overlayBlocksTranslation(get(baseEntry, newPrefix), value);
27061
+ } else if (isJson(attribute)) {
27062
+ valueToSet = overlayJsonTranslation(get(baseEntry, newPrefix), value);
27063
+ }
27033
27064
  if (valueToSet === void 0) {
27034
27065
  return;
27035
27066
  }
27036
27067
  set(createEntry, newPrefix, valueToSet);
27068
+ if (isRebuiltField) {
27069
+ rebuiltFieldPaths.push(newPrefix);
27070
+ }
27037
27071
  if (component) {
27038
27072
  const componentKeyToSet = `${newPrefixBase}.__component`;
27039
27073
  set(createEntry, componentKeyToSet, component);
@@ -27055,8 +27089,59 @@ const parsedLocalazyEntryToCreateEntry = (models, parsedLocalazyEntry, baseEntry
27055
27089
  if (locale) {
27056
27090
  createEntry.locale = locale;
27057
27091
  }
27058
- resetArrayKeysDeep(createEntry, repeatableComponentsKeystoFilter);
27059
- return { createEntry, dynamicZoneComponentKeys };
27092
+ return { createEntry, dynamicZoneComponentKeys, rebuiltFieldPaths };
27093
+ };
27094
+ const isMediaObject = (obj) => {
27095
+ if (typeof obj !== "object" || obj === null) return false;
27096
+ return "url" in obj && "name" in obj && "ext" in obj && ("mime" in obj || "mimeType" in obj) && typeof obj.url === "string" && typeof obj.name === "string" && typeof obj.ext === "string";
27097
+ };
27098
+ const dropPropertyDeepWithSkip = (obj, propertyName, isRoot = true, skipPredicates = []) => {
27099
+ if (Array.isArray(obj)) {
27100
+ return obj.filter((item) => {
27101
+ if (skipPredicates.length > 0) {
27102
+ return true;
27103
+ }
27104
+ return isRoot || !(typeof item === "object" && item !== null && propertyName in item);
27105
+ }).map(
27106
+ (item) => typeof item === "object" && item !== null ? dropPropertyDeepWithSkip(item, propertyName, false, skipPredicates) : item
27107
+ );
27108
+ }
27109
+ if (typeof obj === "object" && obj !== null) {
27110
+ const shouldSkip = skipPredicates.some((predicate) => predicate(obj));
27111
+ if (shouldSkip) {
27112
+ const result2 = {};
27113
+ for (const key in obj) {
27114
+ if (key === propertyName) {
27115
+ result2[key] = obj[key];
27116
+ } else {
27117
+ result2[key] = typeof obj[key] === "object" && obj[key] !== null ? dropPropertyDeepWithSkip(obj[key], propertyName, false, skipPredicates) : obj[key];
27118
+ }
27119
+ }
27120
+ return result2;
27121
+ }
27122
+ const result = {};
27123
+ for (const key in obj) {
27124
+ if (key === propertyName && !isRoot) {
27125
+ continue;
27126
+ }
27127
+ result[key] = typeof obj[key] === "object" && obj[key] !== null ? dropPropertyDeepWithSkip(obj[key], propertyName, false, skipPredicates) : obj[key];
27128
+ }
27129
+ return result;
27130
+ }
27131
+ return obj;
27132
+ };
27133
+ const dropDocumentIdExceptMedia = (obj) => {
27134
+ return dropPropertyDeepWithSkip(obj, "documentId", true, [isMediaObject]);
27135
+ };
27136
+ const OMIT_KEYS = ["locale", "localizations", "createdAt", "createdBy", "updatedAt", "updatedBy", "publishedAt"];
27137
+ const buildLocalizedCreateEntry = (models, translatedModel, baseEntry, uid, isoStrapi) => {
27138
+ const { createEntry } = parsedLocalazyEntryToCreateEntry(models, translatedModel, baseEntry, uid, isoStrapi);
27139
+ const filteredBaseEntry = dropDocumentIdExceptMedia(omitDeep(baseEntry, OMIT_KEYS));
27140
+ let mergedCreateEntry = {};
27141
+ merge(mergedCreateEntry, filteredBaseEntry, createEntry);
27142
+ mergedCreateEntry = omitDeep(mergedCreateEntry, OMIT_KEYS);
27143
+ mergedCreateEntry.locale = isoStrapi;
27144
+ return mergedCreateEntry;
27060
27145
  };
27061
27146
  const doesExistInPopulatedLocalizedEntry = (val) => {
27062
27147
  if (Array.isArray(val)) {
@@ -27095,17 +27180,17 @@ const populateCreateUpdateEntryWithBaseEntry = async (models, createUpdateEntry,
27095
27180
  }
27096
27181
  }
27097
27182
  } else if (!component && isRepeatableComponent && isDZ) {
27098
- Object.entries(partialBaseEntry).forEach(async ([partialBaseEntryItemIndex, partialBaseEntryItem]) => {
27183
+ for (const [partialBaseEntryItemIndex, partialBaseEntryItem] of Object.entries(partialBaseEntry)) {
27099
27184
  const component2 = partialBaseEntryItem.__component;
27100
27185
  const model3 = findModel(models, component2);
27101
27186
  const newPrefix = `${prefix}.${partialBaseEntryItemIndex}`;
27102
27187
  await populateEntry(partialBaseEntryItem, model3, partialBaseEntryItemIndex, newPrefix);
27103
- });
27188
+ }
27104
27189
  } else if (component && isRepeatableComponent) {
27105
- Object.entries(partialBaseEntry).forEach(async ([partialBaseEntryItemIndex, partialBaseEntryItem]) => {
27190
+ for (const [partialBaseEntryItemIndex, partialBaseEntryItem] of Object.entries(partialBaseEntry)) {
27106
27191
  const newPrefix = `${prefix}.${partialBaseEntryItemIndex}`;
27107
27192
  await populateEntry(partialBaseEntryItem, model2, partialBaseEntryItemIndex, newPrefix);
27108
- });
27193
+ }
27109
27194
  }
27110
27195
  } else if (typeof partialBaseEntry === "object") {
27111
27196
  if (partialBaseEntry === null) {
@@ -27218,7 +27303,7 @@ const populateCreateUpdateEntryWithBaseEntry = async (models, createUpdateEntry,
27218
27303
  } else {
27219
27304
  set(populatedEntry, newPrefix, value);
27220
27305
  }
27221
- } else {
27306
+ } else if (!isBlocks(attribute) && !isJson(attribute)) {
27222
27307
  await populateEntry(value, model2, objectKey2, newPrefix);
27223
27308
  }
27224
27309
  }
@@ -27240,15 +27325,80 @@ const populateCreateUpdateEntryWithBaseEntry = async (models, createUpdateEntry,
27240
27325
  await populateEntry(baseEntry, model);
27241
27326
  return populatedEntry;
27242
27327
  };
27328
+ const dropComponentIds = (models, item, model) => {
27329
+ if (!isPlainObject(item)) {
27330
+ return;
27331
+ }
27332
+ delete item.id;
27333
+ for (const [name2, attribute] of Object.entries(model?.attributes || {})) {
27334
+ const value = item[name2];
27335
+ if (attribute.type === "component") {
27336
+ const componentModel = findModel(models, attribute.component);
27337
+ (Array.isArray(value) ? value : [value]).forEach((child) => dropComponentIds(models, child, componentModel));
27338
+ } else if (attribute.type === "dynamiczone" && Array.isArray(value)) {
27339
+ value.forEach((child) => dropComponentIds(models, child, findModel(models, child?.__component)));
27340
+ }
27341
+ }
27342
+ };
27343
+ const asNewComponent = (models, sourceItem, model) => {
27344
+ const copy = cloneDeep(sourceItem);
27345
+ dropComponentIds(models, copy, model);
27346
+ return copy;
27347
+ };
27348
+ const alignLocalizedEntryToSource = (models, localizedEntry, sourceEntry, model, downloadedEntry) => {
27349
+ if (!isPlainObject(localizedEntry) || !isPlainObject(sourceEntry) || !isPlainObject(downloadedEntry)) {
27350
+ return localizedEntry;
27351
+ }
27352
+ const aligned = { ...localizedEntry };
27353
+ for (const [name2, attribute] of Object.entries(model?.attributes || {})) {
27354
+ const source = sourceEntry[name2];
27355
+ const current = localizedEntry[name2];
27356
+ const downloaded = downloadedEntry[name2];
27357
+ if (downloaded === void 0 || downloaded === null || current === void 0) {
27358
+ continue;
27359
+ }
27360
+ if (attribute.type === "component") {
27361
+ const componentModel = findModel(models, attribute.component);
27362
+ if (attribute.repeatable) {
27363
+ if (!Array.isArray(source)) continue;
27364
+ const currentItems = Array.isArray(current) ? current : [];
27365
+ aligned[name2] = currentItems.length === source.length ? currentItems.map(
27366
+ (item, index2) => alignLocalizedEntryToSource(models, item, source[index2], componentModel, downloaded[index2])
27367
+ ) : source.map((item) => asNewComponent(models, item, componentModel));
27368
+ } else if (isPlainObject(source) && isPlainObject(current)) {
27369
+ aligned[name2] = alignLocalizedEntryToSource(models, current, source, componentModel, downloaded);
27370
+ }
27371
+ } else if (attribute.type === "dynamiczone") {
27372
+ if (!Array.isArray(source)) continue;
27373
+ const currentItems = Array.isArray(current) ? current : [];
27374
+ const sameLayout = currentItems.length === source.length && currentItems.every((item, index2) => item?.__component === source[index2]?.__component);
27375
+ aligned[name2] = sameLayout ? currentItems.map(
27376
+ (item, index2) => alignLocalizedEntryToSource(
27377
+ models,
27378
+ item,
27379
+ source[index2],
27380
+ findModel(models, item.__component),
27381
+ downloaded[index2]
27382
+ )
27383
+ ) : source.map((item) => asNewComponent(models, item, findModel(models, item.__component)));
27384
+ }
27385
+ }
27386
+ return aligned;
27387
+ };
27243
27388
  const parsedLocalazyEntryToUpdateEntry = async (allModels, localazyEntry, fullyPopulatedLocalizedEntry, currentEntry, baseEntry, uid, locale) => {
27244
- const { createEntry, dynamicZoneComponentKeys } = parsedLocalazyEntryToCreateEntry(
27389
+ const { createEntry, dynamicZoneComponentKeys, rebuiltFieldPaths } = parsedLocalazyEntryToCreateEntry(
27245
27390
  allModels,
27246
27391
  localazyEntry,
27247
27392
  baseEntry,
27248
27393
  uid
27249
27394
  );
27395
+ const model = findModel(allModels, uid);
27396
+ const alignedCurrentEntry = alignLocalizedEntryToSource(allModels, currentEntry, baseEntry, model, createEntry);
27250
27397
  let updateEntry = {};
27251
- merge(updateEntry, currentEntry, createEntry);
27398
+ merge(updateEntry, alignedCurrentEntry, createEntry);
27399
+ for (const rebuiltFieldPath of rebuiltFieldPaths) {
27400
+ set(updateEntry, rebuiltFieldPath, cloneDeep(get(createEntry, rebuiltFieldPath)));
27401
+ }
27252
27402
  updateEntry = omitDeep(updateEntry, [
27253
27403
  // '__component', // do not omit the __component
27254
27404
  "locale",
@@ -27272,16 +27422,19 @@ const parsedLocalazyEntryToUpdateEntry = async (allModels, localazyEntry, fullyP
27272
27422
  "updatedBy",
27273
27423
  "publishedAt"
27274
27424
  ]);
27275
- const filteredFullyPopulatedLocalizedEntry = omitDeep(fullyPopulatedLocalizedEntry, [
27276
- // "__component", // do not omit the __component
27277
- "locale",
27278
- "localizations",
27279
- "createdAt",
27280
- "createdBy",
27281
- "updatedAt",
27282
- "updatedBy",
27283
- "publishedAt"
27284
- ]);
27425
+ const filteredFullyPopulatedLocalizedEntry = omitDeep(
27426
+ alignLocalizedEntryToSource(allModels, fullyPopulatedLocalizedEntry, baseEntry, model, createEntry),
27427
+ [
27428
+ // "__component", // do not omit the __component
27429
+ "locale",
27430
+ "localizations",
27431
+ "createdAt",
27432
+ "createdBy",
27433
+ "updatedAt",
27434
+ "updatedBy",
27435
+ "publishedAt"
27436
+ ]
27437
+ );
27285
27438
  const populatedEntry = await populateCreateUpdateEntryWithBaseEntry(
27286
27439
  allModels,
27287
27440
  updateEntry,
@@ -27292,65 +27445,16 @@ const parsedLocalazyEntryToUpdateEntry = async (allModels, localazyEntry, fullyP
27292
27445
  );
27293
27446
  return populatedEntry;
27294
27447
  };
27295
- const isMediaObject = (obj) => {
27296
- if (typeof obj !== "object" || obj === null) return false;
27297
- return "url" in obj && "name" in obj && "ext" in obj && ("mime" in obj || "mimeType" in obj) && typeof obj.url === "string" && typeof obj.name === "string" && typeof obj.ext === "string";
27298
- };
27299
- const dropPropertyDeepWithSkip = (obj, propertyName, isRoot = true, skipPredicates = []) => {
27300
- if (Array.isArray(obj)) {
27301
- return obj.filter((item) => {
27302
- if (skipPredicates.length > 0) {
27303
- return true;
27304
- }
27305
- return isRoot || !(typeof item === "object" && item !== null && propertyName in item);
27306
- }).map(
27307
- (item) => typeof item === "object" && item !== null ? dropPropertyDeepWithSkip(item, propertyName, false, skipPredicates) : item
27308
- );
27309
- }
27310
- if (typeof obj === "object" && obj !== null) {
27311
- const shouldSkip = skipPredicates.some((predicate) => predicate(obj));
27312
- if (shouldSkip) {
27313
- const result2 = {};
27314
- for (const key in obj) {
27315
- if (key === propertyName) {
27316
- result2[key] = obj[key];
27317
- } else {
27318
- result2[key] = typeof obj[key] === "object" && obj[key] !== null ? dropPropertyDeepWithSkip(obj[key], propertyName, false, skipPredicates) : obj[key];
27319
- }
27320
- }
27321
- return result2;
27322
- }
27323
- const result = {};
27324
- for (const key in obj) {
27325
- if (key === propertyName && !isRoot) {
27326
- continue;
27327
- }
27328
- result[key] = typeof obj[key] === "object" && obj[key] !== null ? dropPropertyDeepWithSkip(obj[key], propertyName, false, skipPredicates) : obj[key];
27329
- }
27330
- return result;
27331
- }
27332
- return obj;
27333
- };
27334
- const dropDocumentIdExceptMedia = (obj) => {
27335
- return dropPropertyDeepWithSkip(obj, "documentId", true, [isMediaObject]);
27336
- };
27337
27448
  const StrapiLocalazyI18nService = ({ strapi: strapi2 }) => ({
27338
27449
  async createEntry(uid, strapiContentTypesModels, translatedModel, baseEntry, isoStrapi) {
27339
27450
  const StrapiI18nService2 = getStrapiI18nService();
27340
- const { createEntry } = parsedLocalazyEntryToCreateEntry(
27451
+ const mergedCreateEntry = buildLocalizedCreateEntry(
27341
27452
  strapiContentTypesModels,
27342
27453
  translatedModel,
27343
27454
  baseEntry,
27344
27455
  uid,
27345
27456
  isoStrapi
27346
27457
  );
27347
- const omitKeys = ["locale", "localizations", "createdAt", "createdBy", "updatedAt", "updatedBy", "publishedAt"];
27348
- let filteredBaseEntry = omitDeep(baseEntry, omitKeys);
27349
- filteredBaseEntry = dropDocumentIdExceptMedia(filteredBaseEntry);
27350
- let mergedCreateEntry = {};
27351
- merge(mergedCreateEntry, filteredBaseEntry, createEntry);
27352
- mergedCreateEntry = omitDeep(mergedCreateEntry, omitKeys);
27353
- mergedCreateEntry.locale = isoStrapi;
27354
27458
  const createdEntry = await StrapiI18nService2.createLocalizationForAnExistingEntry(
27355
27459
  uid,
27356
27460
  baseEntry,