@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.
@@ -20520,7 +20520,7 @@ var distExports = dist$1.exports;
20520
20520
  const io = /* @__PURE__ */ getDefaultExportFromCjs(distExports);
20521
20521
  const { Server: Server2, Namespace, Socket: Socket3 } = io;
20522
20522
  const name = "@localazy/strapi-plugin";
20523
- const version = "1.7.0";
20523
+ const version = "1.7.1";
20524
20524
  const description = "The official Strapi Plugin by Localazy.";
20525
20525
  const keywords = [
20526
20526
  "strapi",
@@ -22038,7 +22038,7 @@ const findSetupModelByCollectionUid = (contentTransferSetup, strapiContentTypesM
22038
22038
  const modelContentTransferSetup = contentTransferSetup.setup.find(
22039
22039
  (model) => Object.keys(model)[0] === currentModel.collectionName
22040
22040
  );
22041
- return modelContentTransferSetup[currentModel.collectionName];
22041
+ return modelContentTransferSetup?.[currentModel.collectionName];
22042
22042
  };
22043
22043
  const getCollectionsNames = (setup2) => {
22044
22044
  return getMainKeysOfNestedArrayObjects(setup2);
@@ -26185,9 +26185,6 @@ const LocalazyTransferUploadService = ({ strapi: strapi2 }) => ({
26185
26185
  const hasDynamicZoneKeySegment = (parsedKey) => {
26186
26186
  return parsedKey.some((segment) => segment.includes(";"));
26187
26187
  };
26188
- const getDynamicZoneKeySegment = (parsedKey) => {
26189
- return parsedKey.find((segment) => segment.includes(";"));
26190
- };
26191
26188
  const getComponentNameFromDynamicZoneKeySegment = (dynamicZoneKeySegment) => {
26192
26189
  return dynamicZoneKeySegment.split(";")[1];
26193
26190
  };
@@ -26207,52 +26204,116 @@ var ShouldSetDownloadedPropertyReturnType = /* @__PURE__ */ ((ShouldSetDownloade
26207
26204
  ShouldSetDownloadedPropertyReturnType2["JSON"] = "json";
26208
26205
  return ShouldSetDownloadedPropertyReturnType2;
26209
26206
  })(ShouldSetDownloadedPropertyReturnType || {});
26210
- const shouldSetDownloadedProperty = (modelContentTransferSetup, parsedKeyRest) => {
26207
+ const locateDownloadedField = (modelContentTransferSetup, parsedKeyRest) => {
26208
+ const notFound = { type: "no", fieldSegmentIndex: -1 };
26211
26209
  if (!modelContentTransferSetup.__model__) {
26212
- return "no";
26210
+ return notFound;
26213
26211
  }
26212
+ let setupModel = modelContentTransferSetup;
26213
+ let startIndex2 = 0;
26214
26214
  if (hasDynamicZoneKeySegment(parsedKeyRest)) {
26215
- const dynamicZonePropertyName = getDynamicZonePropertyName(parsedKeyRest);
26216
- const componentName = getComponentNameFromDynamicZoneKeySegment(getDynamicZoneKeySegment(parsedKeyRest));
26215
+ const dynamicZoneKeySegmentIndex = getDynamicZoneKeySegmentIndex(parsedKeyRest);
26216
+ const componentName = getComponentNameFromDynamicZoneKeySegment(parsedKeyRest[dynamicZoneKeySegmentIndex]);
26217
26217
  const dzContentTransferSetupModel = get(
26218
26218
  modelContentTransferSetup,
26219
- dynamicZonePropertyName
26219
+ getDynamicZonePropertyName(parsedKeyRest)
26220
26220
  );
26221
26221
  if (!Array.isArray(dzContentTransferSetupModel)) {
26222
- return "no";
26222
+ return notFound;
26223
26223
  }
26224
- const dzContentTransferSetupComponentModel = dzContentTransferSetupModel.find(
26225
- (c2) => c2.__component__ === componentName
26226
- );
26227
- if (!dzContentTransferSetupComponentModel) {
26228
- return "no";
26224
+ setupModel = dzContentTransferSetupModel.find((c2) => c2.__component__ === componentName);
26225
+ if (!setupModel) {
26226
+ return notFound;
26229
26227
  }
26230
- const dynamicZoneKeySegmentIndex = getDynamicZoneKeySegmentIndex(parsedKeyRest);
26231
- const slicedParsedKeyRest = parsedKeyRest.slice(dynamicZoneKeySegmentIndex + 1);
26232
- const filteredSlicedParsedKeyRest = slicedParsedKeyRest.filter((segment) => isNaN(parseInt(segment)));
26233
- if (get(dzContentTransferSetupComponentModel, filteredSlicedParsedKeyRest) === true) {
26234
- return "yes";
26235
- }
26236
- while (filteredSlicedParsedKeyRest.length > 0) {
26237
- filteredSlicedParsedKeyRest.pop();
26238
- if (get(dzContentTransferSetupComponentModel, filteredSlicedParsedKeyRest) === true) {
26239
- return "json";
26228
+ startIndex2 = dynamicZoneKeySegmentIndex + 1;
26229
+ }
26230
+ const namedSegmentIndexes = [];
26231
+ for (let index2 = startIndex2; index2 < parsedKeyRest.length; index2++) {
26232
+ if (isNaN(parseInt(parsedKeyRest[index2]))) {
26233
+ namedSegmentIndexes.push(index2);
26234
+ }
26235
+ }
26236
+ for (let length2 = namedSegmentIndexes.length; length2 > 0; length2--) {
26237
+ const fieldPath = namedSegmentIndexes.slice(0, length2).map((index2) => parsedKeyRest[index2]);
26238
+ if (get(setupModel, fieldPath) === true) {
26239
+ const fieldSegmentIndex = namedSegmentIndexes[length2 - 1];
26240
+ const type2 = fieldSegmentIndex === parsedKeyRest.length - 1 ? "yes" : "json";
26241
+ return { type: type2, fieldSegmentIndex };
26242
+ }
26243
+ }
26244
+ return notFound;
26245
+ };
26246
+ const createJsonFieldsDownloadAccumulator = () => {
26247
+ const fields = /* @__PURE__ */ new Map();
26248
+ return {
26249
+ /**
26250
+ * @param fieldKey path to the field in the parsed content: `[iso, uid, documentId, ...ownerPath, fieldName]`
26251
+ * @param valuePath path of this leaf inside the field's value
26252
+ */
26253
+ add(fieldKey, valuePath, value) {
26254
+ const id = JSON.stringify(fieldKey);
26255
+ let field = fields.get(id);
26256
+ if (!field) {
26257
+ field = { fieldKey, value: {} };
26258
+ fields.set(id, field);
26259
+ }
26260
+ set(field.value, valuePath, value);
26261
+ },
26262
+ /** Write every collected field value into `parsedContent` at its own path. */
26263
+ applyTo(parsedContent) {
26264
+ for (const { fieldKey, value } of fields.values()) {
26265
+ set(parsedContent, fieldKey, value);
26240
26266
  }
26241
26267
  }
26242
- return "no";
26243
- } else {
26244
- const filteredParsedKeyRest = parsedKeyRest.filter((partialKey) => isNaN(parseInt(partialKey)));
26245
- if (get(modelContentTransferSetup, filteredParsedKeyRest) === true) {
26246
- return "yes";
26247
- }
26248
- while (filteredParsedKeyRest.length > 0) {
26249
- filteredParsedKeyRest.pop();
26250
- if (get(modelContentTransferSetup, filteredParsedKeyRest) === true) {
26251
- return "json";
26268
+ };
26269
+ };
26270
+ const collectDownloadedContent = ({
26271
+ languages: languages2,
26272
+ processedKeys,
26273
+ contentTransferSetup,
26274
+ models,
26275
+ parseLocalazyKey: parseLocalazyKey2
26276
+ }) => {
26277
+ const parsedLocalazyContent = {};
26278
+ const entryKeySourceMap = {};
26279
+ const jsonFieldsAccumulator = createJsonFieldsDownloadAccumulator();
26280
+ for (const { isoStrapi, keys: keys2 } of languages2) {
26281
+ const parsedKeys = keys2.map((localazyEntry) => {
26282
+ const storedEvent = processedKeys[isoStrapi]?.[localazyEntry.id];
26283
+ const isChanged = !(storedEvent !== void 0 && localazyEntry.event !== void 0 && localazyEntry.event <= storedEvent);
26284
+ const parsedKey = parseLocalazyKey2(localazyEntry.key[0]);
26285
+ return { localazyEntry, parsedKey, isChanged, entryKey: `${isoStrapi}:${parsedKey.uid}:${parsedKey.id}` };
26286
+ });
26287
+ for (const { localazyEntry, entryKey, isChanged } of parsedKeys) {
26288
+ if (isChanged) {
26289
+ if (!entryKeySourceMap[entryKey]) {
26290
+ entryKeySourceMap[entryKey] = [];
26291
+ }
26292
+ entryKeySourceMap[entryKey].push({ lang: isoStrapi, id: localazyEntry.id, event: localazyEntry.event });
26293
+ }
26294
+ }
26295
+ for (const { localazyEntry, parsedKey, entryKey } of parsedKeys) {
26296
+ if (!entryKeySourceMap[entryKey]) {
26297
+ continue;
26298
+ }
26299
+ const modelContentTransferSetup = findSetupModelByCollectionUid(contentTransferSetup, models, parsedKey.uid);
26300
+ if (typeof modelContentTransferSetup === "undefined") {
26301
+ continue;
26302
+ }
26303
+ const { type: type2, fieldSegmentIndex } = locateDownloadedField(modelContentTransferSetup, parsedKey.rest);
26304
+ if (type2 === ShouldSetDownloadedPropertyReturnType.JSON) {
26305
+ jsonFieldsAccumulator.add(
26306
+ [isoStrapi, parsedKey.uid, parsedKey.id, ...parsedKey.rest.slice(0, fieldSegmentIndex + 1)],
26307
+ parsedKey.rest.slice(fieldSegmentIndex + 1),
26308
+ localazyEntry.value
26309
+ );
26310
+ } else if (type2 === ShouldSetDownloadedPropertyReturnType.YES) {
26311
+ set(parsedLocalazyContent, [isoStrapi, parsedKey.uid, parsedKey.id, ...parsedKey.rest], localazyEntry.value);
26252
26312
  }
26253
26313
  }
26254
- return "no";
26255
26314
  }
26315
+ jsonFieldsAccumulator.applyTo(parsedLocalazyContent);
26316
+ return { parsedLocalazyContent, entryKeySourceMap };
26256
26317
  };
26257
26318
  const getFilteredLanguagesCodesForDownload = async (languagesCodes, requestedUiLanguages) => {
26258
26319
  const pluginSettingsServiceHelper = new PluginSettingsServiceHelper();
@@ -26439,10 +26500,8 @@ const LocalazyTransferDownloadService = ({ strapi: strapi2 }) => ({
26439
26500
  }
26440
26501
  await persistCursor();
26441
26502
  };
26442
- const parsedLocalazyContent = {};
26443
26503
  const strapiContentTypesModels = await StrapiService2.getModels();
26444
- const jsonFields = [];
26445
- const entryKeySourceMap = {};
26504
+ const languagesToParse = [];
26446
26505
  for (const [isoLocalazy, keys2] of Object.entries(localazyContent)) {
26447
26506
  const isoStrapi = isoLocalazyToStrapi(isoLocalazy);
26448
26507
  if (!isoStrapi) {
@@ -26451,78 +26510,15 @@ const LocalazyTransferDownloadService = ({ strapi: strapi2 }) => ({
26451
26510
  });
26452
26511
  continue;
26453
26512
  }
26454
- for (const localazyEntry of keys2) {
26455
- const key = localazyEntry.key[0];
26456
- const value = localazyEntry.value;
26457
- const localazyKeyId = localazyEntry.id;
26458
- const localazyKeyEvent = localazyEntry.event;
26459
- const storedEvent = processedKeys[isoStrapi]?.[localazyKeyId];
26460
- if (storedEvent !== void 0 && localazyKeyEvent !== void 0 && localazyKeyEvent <= storedEvent) {
26461
- continue;
26462
- }
26463
- const parsedKey = StrapiI18nService2.parseLocalazyKey(key);
26464
- const entryKey = `${isoStrapi}:${parsedKey.uid}:${parsedKey.id}`;
26465
- if (!entryKeySourceMap[entryKey]) {
26466
- entryKeySourceMap[entryKey] = [];
26467
- }
26468
- entryKeySourceMap[entryKey].push({ lang: isoStrapi, id: localazyKeyId, event: localazyKeyEvent });
26469
- const modelContentTransferSetup = findSetupModelByCollectionUid(
26470
- contentTransferSetup,
26471
- strapiContentTypesModels,
26472
- parsedKey.uid
26473
- );
26474
- if (typeof modelContentTransferSetup !== "undefined") {
26475
- const shouldSetDownloadedPropertyResult = shouldSetDownloadedProperty(
26476
- modelContentTransferSetup,
26477
- parsedKey.rest
26478
- );
26479
- if (shouldSetDownloadedPropertyResult === ShouldSetDownloadedPropertyReturnType.NO) {
26480
- continue;
26481
- }
26482
- let parsedKeyRestWithoutComponents = parsedKey.rest;
26483
- if (shouldSetDownloadedPropertyResult === ShouldSetDownloadedPropertyReturnType.JSON) {
26484
- const setKey = [isoStrapi, parsedKey.uid, parsedKey.id];
26485
- let updatedParsedKeyRestWithoutComponents = parsedKeyRestWithoutComponents;
26486
- let segmentsToAdd = [];
26487
- for (const segment of parsedKeyRestWithoutComponents) {
26488
- const hasEntry = get(modelContentTransferSetup, [...segmentsToAdd, segment]);
26489
- const hasEntryNotFinal = hasEntry && typeof hasEntry !== "boolean";
26490
- const isComponent2 = parseInt(segment) > 0;
26491
- if (hasEntryNotFinal || !hasEntry && isComponent2) {
26492
- segmentsToAdd.push(segment);
26493
- setKey.push(segment);
26494
- updatedParsedKeyRestWithoutComponents = updatedParsedKeyRestWithoutComponents.slice(1);
26495
- } else {
26496
- break;
26497
- }
26498
- }
26499
- parsedKeyRestWithoutComponents = updatedParsedKeyRestWithoutComponents;
26500
- let foundJsonFieldIndex = jsonFields.findIndex((jsonField) => {
26501
- return jsonField.setKey.join() === setKey.join();
26502
- });
26503
- if (foundJsonFieldIndex === -1) {
26504
- jsonFields.push({
26505
- setKey,
26506
- jsonKey: parsedKeyRestWithoutComponents[0],
26507
- jsonValue: {}
26508
- });
26509
- }
26510
- foundJsonFieldIndex = foundJsonFieldIndex === -1 ? jsonFields.length - 1 : foundJsonFieldIndex;
26511
- const foundJsonField = jsonFields[foundJsonFieldIndex];
26512
- const restSliced = parsedKeyRestWithoutComponents.slice(1);
26513
- set(foundJsonField, ["jsonValue", ...restSliced], value);
26514
- jsonFields[foundJsonFieldIndex] = foundJsonField;
26515
- }
26516
- if (shouldSetDownloadedPropertyResult === ShouldSetDownloadedPropertyReturnType.YES) {
26517
- const setKey = [isoStrapi, parsedKey.uid, parsedKey.id, ...parsedKeyRestWithoutComponents];
26518
- set(parsedLocalazyContent, setKey, value);
26519
- }
26520
- }
26521
- }
26522
- }
26523
- for (const jsonField of jsonFields) {
26524
- set(parsedLocalazyContent, [...jsonField.setKey, jsonField.jsonKey], jsonField.jsonValue);
26525
- }
26513
+ languagesToParse.push({ isoStrapi, keys: keys2 });
26514
+ }
26515
+ const { parsedLocalazyContent, entryKeySourceMap } = collectDownloadedContent({
26516
+ languages: languagesToParse,
26517
+ processedKeys,
26518
+ contentTransferSetup,
26519
+ models: strapiContentTypesModels,
26520
+ parseLocalazyKey: (key) => StrapiI18nService2.parseLocalazyKey(key)
26521
+ });
26526
26522
  for (const [isoStrapi, contentTypes2] of Object.entries(parsedLocalazyContent)) {
26527
26523
  for (const [uid, models] of Object.entries(contentTypes2)) {
26528
26524
  const strapiContentTypeModel = strapiContentTypesModels.find((model) => model.uid === uid);
@@ -26706,6 +26702,15 @@ const intlDisplayName = (isoStrapi) => {
26706
26702
  }
26707
26703
  return languageNames.of(isoStrapi.toLowerCase());
26708
26704
  };
26705
+ const parseLocalazyKey = (key) => {
26706
+ const split = key.split(/\.(?![^[]*])|\[|\]/);
26707
+ const filteredSplit = split.filter((item) => item !== "");
26708
+ return {
26709
+ uid: `${filteredSplit[0]}.${filteredSplit[1]}`,
26710
+ id: filteredSplit[2],
26711
+ rest: filteredSplit.slice(3)
26712
+ };
26713
+ };
26709
26714
  const StrapiI18nService = ({ strapi: strapi2 }) => ({
26710
26715
  async getLocales() {
26711
26716
  return strapi2.plugin("i18n").service("locales").find();
@@ -26733,13 +26738,7 @@ const StrapiI18nService = ({ strapi: strapi2 }) => ({
26733
26738
  }
26734
26739
  },
26735
26740
  parseLocalazyKey(key) {
26736
- const split = key.split(/\.(?![^[]*])|\[|\]/);
26737
- const filteredSplit = split.filter((item) => item !== "");
26738
- return {
26739
- uid: `${filteredSplit[0]}.${filteredSplit[1]}`,
26740
- id: filteredSplit[2],
26741
- rest: filteredSplit.slice(3)
26742
- };
26741
+ return parseLocalazyKey(key);
26743
26742
  },
26744
26743
  async getEntryInLocale(modelUid, documentId, isoStrapi) {
26745
26744
  const entry = await strapi2.documents(modelUid).findOne({
@@ -26838,18 +26837,6 @@ const LocalazyUploadService = ({ strapi: strapi2 }) => ({
26838
26837
  return file;
26839
26838
  }
26840
26839
  });
26841
- const resetArrayKeysDeep = (object, keysToFilter) => {
26842
- const sortedKeysToFilter = keysToFilter.sort((a2, b2) => {
26843
- const aLvl = a2.match(/\./g)?.length || 0;
26844
- const bLvl = b2.match(/\./g)?.length || 0;
26845
- return bLvl - aLvl;
26846
- });
26847
- for (const key of sortedKeysToFilter) {
26848
- const part = get(object, key);
26849
- const filteredPart = part.filter((item) => item !== void 0);
26850
- set(object, key, filteredPart);
26851
- }
26852
- };
26853
26840
  const getAttribute = (model, attribute) => {
26854
26841
  if (isEmpty(model)) {
26855
26842
  return void 0;
@@ -26872,22 +26859,63 @@ const isRelation = (attributeObj) => {
26872
26859
  const isBlocks = (attributeObj) => {
26873
26860
  return attributeObj.type === BLOCKS_ATTRIBUTE_TYPE;
26874
26861
  };
26862
+ const isJson = (attributeObj) => {
26863
+ return attributeObj.type === "json";
26864
+ };
26875
26865
  const findModel = (models, uid) => {
26876
26866
  const model = models.find((model2) => model2.uid === uid);
26877
26867
  return model;
26878
26868
  };
26869
+ const arrayItemSegment = (item, index2) => {
26870
+ if (isPlainObject(item) && item.id && item.__component) {
26871
+ return `${item.id};${item.__component}`;
26872
+ }
26873
+ return String(item?.documentId || item?.id || index2);
26874
+ };
26875
+ const objectIdSegment = (value) => {
26876
+ if (isPlainObject(value) && (value.documentId || value.id)) {
26877
+ return String(value.documentId || value.id);
26878
+ }
26879
+ return void 0;
26880
+ };
26881
+ const overlayValue = (source, translated) => {
26882
+ if (typeof source === "string") {
26883
+ return typeof translated === "string" ? translated : source;
26884
+ }
26885
+ if (Array.isArray(source)) {
26886
+ return source.map((item, index2) => overlayValue(item, get(translated, [arrayItemSegment(item, index2)])));
26887
+ }
26888
+ if (isPlainObject(source)) {
26889
+ const result = {};
26890
+ for (const [key, value] of Object.entries(source)) {
26891
+ result[key] = key === "id" || key === "documentId" ? value : overlayChild(value, get(translated, [key]));
26892
+ }
26893
+ return result;
26894
+ }
26895
+ return source;
26896
+ };
26897
+ const overlayChild = (source, translated) => {
26898
+ const idSegment = Array.isArray(source) ? void 0 : objectIdSegment(source);
26899
+ return overlayValue(source, idSegment ? get(translated, [idSegment]) : translated);
26900
+ };
26901
+ const overlayJsonTranslation = (sourceValue, translated) => {
26902
+ if (sourceValue === void 0 || sourceValue === null) {
26903
+ return void 0;
26904
+ }
26905
+ if (typeof sourceValue !== "object") {
26906
+ return typeof sourceValue === "string" && typeof translated === "string" ? translated : sourceValue;
26907
+ }
26908
+ return overlayChild(cloneDeep(sourceValue), translated);
26909
+ };
26879
26910
  const parsedLocalazyEntryToCreateEntry = (models, parsedLocalazyEntry, baseEntry, uid, locale = "") => {
26880
26911
  const createEntry = {};
26881
- const repeatableComponentsKeystoFilter = [];
26882
26912
  const dynamicZoneComponentKeys = [];
26913
+ const rebuiltFieldPaths = [];
26883
26914
  const toCreateEntry = (entry, model2, key = "", prefix = "", component = "", isRepeatableComponent = false, isDZ = false, isInsideDZ = false) => {
26884
26915
  if (Array.isArray(entry)) {
26885
26916
  Object.entries(entry).forEach(([baseEntryItemId, value]) => {
26886
26917
  if (value !== null) {
26887
26918
  if (component && isRepeatableComponent) {
26888
- if (!repeatableComponentsKeystoFilter.includes(prefix)) {
26889
- repeatableComponentsKeystoFilter.push(prefix);
26890
- }
26891
26919
  const baseEntryRepeatableItemId = parseInt(baseEntryItemId);
26892
26920
  const baseEntryRepeateableGroup = get(baseEntry, prefix);
26893
26921
  if (baseEntryRepeateableGroup !== void 0) {
@@ -26909,9 +26937,6 @@ const parsedLocalazyEntryToCreateEntry = (models, parsedLocalazyEntry, baseEntry
26909
26937
  toCreateEntry(value, model2, `${prefix}`, `${prefix}`);
26910
26938
  }
26911
26939
  if (!component && isRepeatableComponent) {
26912
- if (!repeatableComponentsKeystoFilter.includes(prefix)) {
26913
- repeatableComponentsKeystoFilter.push(prefix);
26914
- }
26915
26940
  const baseEntryRepeatableItemId = parseInt(baseEntryItemId);
26916
26941
  const baseEntryRepeateableGroup = get(baseEntry, prefix);
26917
26942
  if (baseEntryRepeateableGroup !== void 0) {
@@ -27015,11 +27040,20 @@ const parsedLocalazyEntryToCreateEntry = (models, parsedLocalazyEntry, baseEntry
27015
27040
  newPrefixBase = `${dzParamKey}.${baseEntryDZIndex}`;
27016
27041
  newPrefix = `${newPrefixBase}.${objectKey}`;
27017
27042
  }
27018
- const valueToSet = isBlocks(attribute) ? overlayBlocksTranslation(get(baseEntry, newPrefix), value) : value;
27043
+ const isRebuiltField = isBlocks(attribute) || isJson(attribute);
27044
+ let valueToSet = value;
27045
+ if (isBlocks(attribute)) {
27046
+ valueToSet = overlayBlocksTranslation(get(baseEntry, newPrefix), value);
27047
+ } else if (isJson(attribute)) {
27048
+ valueToSet = overlayJsonTranslation(get(baseEntry, newPrefix), value);
27049
+ }
27019
27050
  if (valueToSet === void 0) {
27020
27051
  return;
27021
27052
  }
27022
27053
  set(createEntry, newPrefix, valueToSet);
27054
+ if (isRebuiltField) {
27055
+ rebuiltFieldPaths.push(newPrefix);
27056
+ }
27023
27057
  if (component) {
27024
27058
  const componentKeyToSet = `${newPrefixBase}.__component`;
27025
27059
  set(createEntry, componentKeyToSet, component);
@@ -27041,8 +27075,59 @@ const parsedLocalazyEntryToCreateEntry = (models, parsedLocalazyEntry, baseEntry
27041
27075
  if (locale) {
27042
27076
  createEntry.locale = locale;
27043
27077
  }
27044
- resetArrayKeysDeep(createEntry, repeatableComponentsKeystoFilter);
27045
- return { createEntry, dynamicZoneComponentKeys };
27078
+ return { createEntry, dynamicZoneComponentKeys, rebuiltFieldPaths };
27079
+ };
27080
+ const isMediaObject = (obj) => {
27081
+ if (typeof obj !== "object" || obj === null) return false;
27082
+ 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";
27083
+ };
27084
+ const dropPropertyDeepWithSkip = (obj, propertyName, isRoot = true, skipPredicates = []) => {
27085
+ if (Array.isArray(obj)) {
27086
+ return obj.filter((item) => {
27087
+ if (skipPredicates.length > 0) {
27088
+ return true;
27089
+ }
27090
+ return isRoot || !(typeof item === "object" && item !== null && propertyName in item);
27091
+ }).map(
27092
+ (item) => typeof item === "object" && item !== null ? dropPropertyDeepWithSkip(item, propertyName, false, skipPredicates) : item
27093
+ );
27094
+ }
27095
+ if (typeof obj === "object" && obj !== null) {
27096
+ const shouldSkip = skipPredicates.some((predicate) => predicate(obj));
27097
+ if (shouldSkip) {
27098
+ const result2 = {};
27099
+ for (const key in obj) {
27100
+ if (key === propertyName) {
27101
+ result2[key] = obj[key];
27102
+ } else {
27103
+ result2[key] = typeof obj[key] === "object" && obj[key] !== null ? dropPropertyDeepWithSkip(obj[key], propertyName, false, skipPredicates) : obj[key];
27104
+ }
27105
+ }
27106
+ return result2;
27107
+ }
27108
+ const result = {};
27109
+ for (const key in obj) {
27110
+ if (key === propertyName && !isRoot) {
27111
+ continue;
27112
+ }
27113
+ result[key] = typeof obj[key] === "object" && obj[key] !== null ? dropPropertyDeepWithSkip(obj[key], propertyName, false, skipPredicates) : obj[key];
27114
+ }
27115
+ return result;
27116
+ }
27117
+ return obj;
27118
+ };
27119
+ const dropDocumentIdExceptMedia = (obj) => {
27120
+ return dropPropertyDeepWithSkip(obj, "documentId", true, [isMediaObject]);
27121
+ };
27122
+ const OMIT_KEYS = ["locale", "localizations", "createdAt", "createdBy", "updatedAt", "updatedBy", "publishedAt"];
27123
+ const buildLocalizedCreateEntry = (models, translatedModel, baseEntry, uid, isoStrapi) => {
27124
+ const { createEntry } = parsedLocalazyEntryToCreateEntry(models, translatedModel, baseEntry, uid, isoStrapi);
27125
+ const filteredBaseEntry = dropDocumentIdExceptMedia(omitDeep(baseEntry, OMIT_KEYS));
27126
+ let mergedCreateEntry = {};
27127
+ merge(mergedCreateEntry, filteredBaseEntry, createEntry);
27128
+ mergedCreateEntry = omitDeep(mergedCreateEntry, OMIT_KEYS);
27129
+ mergedCreateEntry.locale = isoStrapi;
27130
+ return mergedCreateEntry;
27046
27131
  };
27047
27132
  const doesExistInPopulatedLocalizedEntry = (val) => {
27048
27133
  if (Array.isArray(val)) {
@@ -27081,17 +27166,17 @@ const populateCreateUpdateEntryWithBaseEntry = async (models, createUpdateEntry,
27081
27166
  }
27082
27167
  }
27083
27168
  } else if (!component && isRepeatableComponent && isDZ) {
27084
- Object.entries(partialBaseEntry).forEach(async ([partialBaseEntryItemIndex, partialBaseEntryItem]) => {
27169
+ for (const [partialBaseEntryItemIndex, partialBaseEntryItem] of Object.entries(partialBaseEntry)) {
27085
27170
  const component2 = partialBaseEntryItem.__component;
27086
27171
  const model3 = findModel(models, component2);
27087
27172
  const newPrefix = `${prefix}.${partialBaseEntryItemIndex}`;
27088
27173
  await populateEntry(partialBaseEntryItem, model3, partialBaseEntryItemIndex, newPrefix);
27089
- });
27174
+ }
27090
27175
  } else if (component && isRepeatableComponent) {
27091
- Object.entries(partialBaseEntry).forEach(async ([partialBaseEntryItemIndex, partialBaseEntryItem]) => {
27176
+ for (const [partialBaseEntryItemIndex, partialBaseEntryItem] of Object.entries(partialBaseEntry)) {
27092
27177
  const newPrefix = `${prefix}.${partialBaseEntryItemIndex}`;
27093
27178
  await populateEntry(partialBaseEntryItem, model2, partialBaseEntryItemIndex, newPrefix);
27094
- });
27179
+ }
27095
27180
  }
27096
27181
  } else if (typeof partialBaseEntry === "object") {
27097
27182
  if (partialBaseEntry === null) {
@@ -27204,7 +27289,7 @@ const populateCreateUpdateEntryWithBaseEntry = async (models, createUpdateEntry,
27204
27289
  } else {
27205
27290
  set(populatedEntry, newPrefix, value);
27206
27291
  }
27207
- } else {
27292
+ } else if (!isBlocks(attribute) && !isJson(attribute)) {
27208
27293
  await populateEntry(value, model2, objectKey2, newPrefix);
27209
27294
  }
27210
27295
  }
@@ -27226,15 +27311,80 @@ const populateCreateUpdateEntryWithBaseEntry = async (models, createUpdateEntry,
27226
27311
  await populateEntry(baseEntry, model);
27227
27312
  return populatedEntry;
27228
27313
  };
27314
+ const dropComponentIds = (models, item, model) => {
27315
+ if (!isPlainObject(item)) {
27316
+ return;
27317
+ }
27318
+ delete item.id;
27319
+ for (const [name2, attribute] of Object.entries(model?.attributes || {})) {
27320
+ const value = item[name2];
27321
+ if (attribute.type === "component") {
27322
+ const componentModel = findModel(models, attribute.component);
27323
+ (Array.isArray(value) ? value : [value]).forEach((child) => dropComponentIds(models, child, componentModel));
27324
+ } else if (attribute.type === "dynamiczone" && Array.isArray(value)) {
27325
+ value.forEach((child) => dropComponentIds(models, child, findModel(models, child?.__component)));
27326
+ }
27327
+ }
27328
+ };
27329
+ const asNewComponent = (models, sourceItem, model) => {
27330
+ const copy = cloneDeep(sourceItem);
27331
+ dropComponentIds(models, copy, model);
27332
+ return copy;
27333
+ };
27334
+ const alignLocalizedEntryToSource = (models, localizedEntry, sourceEntry, model, downloadedEntry) => {
27335
+ if (!isPlainObject(localizedEntry) || !isPlainObject(sourceEntry) || !isPlainObject(downloadedEntry)) {
27336
+ return localizedEntry;
27337
+ }
27338
+ const aligned = { ...localizedEntry };
27339
+ for (const [name2, attribute] of Object.entries(model?.attributes || {})) {
27340
+ const source = sourceEntry[name2];
27341
+ const current = localizedEntry[name2];
27342
+ const downloaded = downloadedEntry[name2];
27343
+ if (downloaded === void 0 || downloaded === null || current === void 0) {
27344
+ continue;
27345
+ }
27346
+ if (attribute.type === "component") {
27347
+ const componentModel = findModel(models, attribute.component);
27348
+ if (attribute.repeatable) {
27349
+ if (!Array.isArray(source)) continue;
27350
+ const currentItems = Array.isArray(current) ? current : [];
27351
+ aligned[name2] = currentItems.length === source.length ? currentItems.map(
27352
+ (item, index2) => alignLocalizedEntryToSource(models, item, source[index2], componentModel, downloaded[index2])
27353
+ ) : source.map((item) => asNewComponent(models, item, componentModel));
27354
+ } else if (isPlainObject(source) && isPlainObject(current)) {
27355
+ aligned[name2] = alignLocalizedEntryToSource(models, current, source, componentModel, downloaded);
27356
+ }
27357
+ } else if (attribute.type === "dynamiczone") {
27358
+ if (!Array.isArray(source)) continue;
27359
+ const currentItems = Array.isArray(current) ? current : [];
27360
+ const sameLayout = currentItems.length === source.length && currentItems.every((item, index2) => item?.__component === source[index2]?.__component);
27361
+ aligned[name2] = sameLayout ? currentItems.map(
27362
+ (item, index2) => alignLocalizedEntryToSource(
27363
+ models,
27364
+ item,
27365
+ source[index2],
27366
+ findModel(models, item.__component),
27367
+ downloaded[index2]
27368
+ )
27369
+ ) : source.map((item) => asNewComponent(models, item, findModel(models, item.__component)));
27370
+ }
27371
+ }
27372
+ return aligned;
27373
+ };
27229
27374
  const parsedLocalazyEntryToUpdateEntry = async (allModels, localazyEntry, fullyPopulatedLocalizedEntry, currentEntry, baseEntry, uid, locale) => {
27230
- const { createEntry, dynamicZoneComponentKeys } = parsedLocalazyEntryToCreateEntry(
27375
+ const { createEntry, dynamicZoneComponentKeys, rebuiltFieldPaths } = parsedLocalazyEntryToCreateEntry(
27231
27376
  allModels,
27232
27377
  localazyEntry,
27233
27378
  baseEntry,
27234
27379
  uid
27235
27380
  );
27381
+ const model = findModel(allModels, uid);
27382
+ const alignedCurrentEntry = alignLocalizedEntryToSource(allModels, currentEntry, baseEntry, model, createEntry);
27236
27383
  let updateEntry = {};
27237
- merge(updateEntry, currentEntry, createEntry);
27384
+ merge(updateEntry, alignedCurrentEntry, createEntry);
27385
+ for (const rebuiltFieldPath of rebuiltFieldPaths) {
27386
+ set(updateEntry, rebuiltFieldPath, cloneDeep(get(createEntry, rebuiltFieldPath)));
27387
+ }
27238
27388
  updateEntry = omitDeep(updateEntry, [
27239
27389
  // '__component', // do not omit the __component
27240
27390
  "locale",
@@ -27258,16 +27408,19 @@ const parsedLocalazyEntryToUpdateEntry = async (allModels, localazyEntry, fullyP
27258
27408
  "updatedBy",
27259
27409
  "publishedAt"
27260
27410
  ]);
27261
- const filteredFullyPopulatedLocalizedEntry = omitDeep(fullyPopulatedLocalizedEntry, [
27262
- // "__component", // do not omit the __component
27263
- "locale",
27264
- "localizations",
27265
- "createdAt",
27266
- "createdBy",
27267
- "updatedAt",
27268
- "updatedBy",
27269
- "publishedAt"
27270
- ]);
27411
+ const filteredFullyPopulatedLocalizedEntry = omitDeep(
27412
+ alignLocalizedEntryToSource(allModels, fullyPopulatedLocalizedEntry, baseEntry, model, createEntry),
27413
+ [
27414
+ // "__component", // do not omit the __component
27415
+ "locale",
27416
+ "localizations",
27417
+ "createdAt",
27418
+ "createdBy",
27419
+ "updatedAt",
27420
+ "updatedBy",
27421
+ "publishedAt"
27422
+ ]
27423
+ );
27271
27424
  const populatedEntry = await populateCreateUpdateEntryWithBaseEntry(
27272
27425
  allModels,
27273
27426
  updateEntry,
@@ -27278,65 +27431,16 @@ const parsedLocalazyEntryToUpdateEntry = async (allModels, localazyEntry, fullyP
27278
27431
  );
27279
27432
  return populatedEntry;
27280
27433
  };
27281
- const isMediaObject = (obj) => {
27282
- if (typeof obj !== "object" || obj === null) return false;
27283
- 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";
27284
- };
27285
- const dropPropertyDeepWithSkip = (obj, propertyName, isRoot = true, skipPredicates = []) => {
27286
- if (Array.isArray(obj)) {
27287
- return obj.filter((item) => {
27288
- if (skipPredicates.length > 0) {
27289
- return true;
27290
- }
27291
- return isRoot || !(typeof item === "object" && item !== null && propertyName in item);
27292
- }).map(
27293
- (item) => typeof item === "object" && item !== null ? dropPropertyDeepWithSkip(item, propertyName, false, skipPredicates) : item
27294
- );
27295
- }
27296
- if (typeof obj === "object" && obj !== null) {
27297
- const shouldSkip = skipPredicates.some((predicate) => predicate(obj));
27298
- if (shouldSkip) {
27299
- const result2 = {};
27300
- for (const key in obj) {
27301
- if (key === propertyName) {
27302
- result2[key] = obj[key];
27303
- } else {
27304
- result2[key] = typeof obj[key] === "object" && obj[key] !== null ? dropPropertyDeepWithSkip(obj[key], propertyName, false, skipPredicates) : obj[key];
27305
- }
27306
- }
27307
- return result2;
27308
- }
27309
- const result = {};
27310
- for (const key in obj) {
27311
- if (key === propertyName && !isRoot) {
27312
- continue;
27313
- }
27314
- result[key] = typeof obj[key] === "object" && obj[key] !== null ? dropPropertyDeepWithSkip(obj[key], propertyName, false, skipPredicates) : obj[key];
27315
- }
27316
- return result;
27317
- }
27318
- return obj;
27319
- };
27320
- const dropDocumentIdExceptMedia = (obj) => {
27321
- return dropPropertyDeepWithSkip(obj, "documentId", true, [isMediaObject]);
27322
- };
27323
27434
  const StrapiLocalazyI18nService = ({ strapi: strapi2 }) => ({
27324
27435
  async createEntry(uid, strapiContentTypesModels, translatedModel, baseEntry, isoStrapi) {
27325
27436
  const StrapiI18nService2 = getStrapiI18nService();
27326
- const { createEntry } = parsedLocalazyEntryToCreateEntry(
27437
+ const mergedCreateEntry = buildLocalizedCreateEntry(
27327
27438
  strapiContentTypesModels,
27328
27439
  translatedModel,
27329
27440
  baseEntry,
27330
27441
  uid,
27331
27442
  isoStrapi
27332
27443
  );
27333
- const omitKeys = ["locale", "localizations", "createdAt", "createdBy", "updatedAt", "updatedBy", "publishedAt"];
27334
- let filteredBaseEntry = omitDeep(baseEntry, omitKeys);
27335
- filteredBaseEntry = dropDocumentIdExceptMedia(filteredBaseEntry);
27336
- let mergedCreateEntry = {};
27337
- merge(mergedCreateEntry, filteredBaseEntry, createEntry);
27338
- mergedCreateEntry = omitDeep(mergedCreateEntry, omitKeys);
27339
- mergedCreateEntry.locale = isoStrapi;
27340
27444
  const createdEntry = await StrapiI18nService2.createLocalizationForAnExistingEntry(
27341
27445
  uid,
27342
27446
  baseEntry,