@localazy/strapi-plugin 1.6.0 → 1.7.0
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/_chunks/{FetchIdentity-CcEjakiz.js → FetchIdentity-D89DgpbN.js} +1 -1
- package/dist/_chunks/{FetchIdentity-Bm7bc5bS.mjs → FetchIdentity-DkHj24S5.mjs} +1 -1
- package/dist/_chunks/{LanguagesSelector-DejYCwBl.js → LanguagesSelector-638KGQYw.js} +2 -2
- package/dist/_chunks/{LanguagesSelector-B1rwN7-Y.mjs → LanguagesSelector-CR_7I2R1.mjs} +2 -2
- package/dist/_chunks/{LocalazyApp-jPO7Yr1S.js → LocalazyApp-Benn8pkA.js} +5 -5
- package/dist/_chunks/{LocalazyApp-C4kbsnQh.mjs → LocalazyApp-DM3zg5E4.mjs} +5 -5
- package/dist/_chunks/{LocalazyContentTransferSetup-C1wDD9hA.mjs → LocalazyContentTransferSetup-BA_rtSBM.mjs} +4 -4
- package/dist/_chunks/{LocalazyContentTransferSetup-DZh4ZdSi.js → LocalazyContentTransferSetup-CWchyGdD.js} +4 -4
- package/dist/_chunks/{LocalazyGlobalSettings-D76it6rn.js → LocalazyGlobalSettings-88jqQbD4.js} +5 -5
- package/dist/_chunks/{LocalazyGlobalSettings-DOW5rjLn.mjs → LocalazyGlobalSettings-BWF0s9tM.mjs} +5 -5
- package/dist/_chunks/{LocalazyPanel-C_Z4W49T.mjs → LocalazyPanel-4HRa1jNl.mjs} +2 -2
- package/dist/_chunks/{LocalazyPanel-D2LQpqii.js → LocalazyPanel-D0w9JSIS.js} +2 -2
- package/dist/_chunks/{LocalazyStatusColumn-Dy6N4_X6.js → LocalazyStatusColumn-BR3f8rKp.js} +2 -2
- package/dist/_chunks/{LocalazyStatusColumn-C_ZCd_s7.mjs → LocalazyStatusColumn-D4-rZZUK.mjs} +2 -2
- package/dist/_chunks/{RequireLocalazyAuth-BVwF0bRC.js → RequireLocalazyAuth-C442750b.js} +2 -2
- package/dist/_chunks/{RequireLocalazyAuth-DNhTZZ_6.mjs → RequireLocalazyAuth-DbNjEOq-.mjs} +2 -2
- package/dist/_chunks/{entry-exclusion-service-CF_yNCly.mjs → entry-exclusion-service-Bd3mUDde.mjs} +1 -1
- package/dist/_chunks/{entry-exclusion-service-CH3ZoJQN.js → entry-exclusion-service-CAIcybXX.js} +1 -1
- package/dist/_chunks/{has-model-changed-CVJEuGxM.mjs → has-model-changed-BNs3d9q5.mjs} +4 -3
- package/dist/_chunks/{has-model-changed-DdYbyv0v.js → has-model-changed-BrDeyHFt.js} +4 -3
- package/dist/_chunks/{index-DP2ugzc_.mjs → index-C9Px4v-A.mjs} +7 -7
- package/dist/_chunks/{index-CEGaWWh3.js → index-DwFm1TyM.js} +7 -7
- package/dist/_chunks/{strapi-api-base-CCUuu7EY.js → strapi-api-base-BWZYbxxj.js} +1 -1
- package/dist/_chunks/{strapi-api-base-IiMEtDoH.mjs → strapi-api-base-lPo7wq6I.mjs} +1 -1
- package/dist/admin/index.js +1 -1
- package/dist/admin/index.mjs +1 -1
- package/dist/admin/src/modules/@common/models/supported-content-type-fields.d.ts +1 -1
- package/dist/server/index.js +266 -178
- package/dist/server/index.mjs +266 -178
- package/dist/server/src/utils/blocks-to-translatable.d.ts +34 -0
- package/dist/server/src/utils/model-utils.d.ts +2 -1
- package/package.json +1 -1
package/dist/server/index.mjs
CHANGED
|
@@ -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.
|
|
20523
|
+
const version = "1.7.0";
|
|
20524
20524
|
const description = "The official Strapi Plugin by Localazy.";
|
|
20525
20525
|
const keywords = [
|
|
20526
20526
|
"strapi",
|
|
@@ -25611,182 +25611,6 @@ const PluginSettingsService = ({ strapi: strapi2 }) => ({
|
|
|
25611
25611
|
return cursor;
|
|
25612
25612
|
}
|
|
25613
25613
|
});
|
|
25614
|
-
const LocalazyTransferUploadService = ({ strapi: strapi2 }) => ({
|
|
25615
|
-
async upload({ notificationService }) {
|
|
25616
|
-
console.time("upload");
|
|
25617
|
-
await notificationService.emit(EventType.UPLOAD, {
|
|
25618
|
-
message: "Upload started"
|
|
25619
|
-
});
|
|
25620
|
-
const activityLogsService = getActivityLogsService();
|
|
25621
|
-
const sessionId = await activityLogsService.startSession("upload", "Strapi User");
|
|
25622
|
-
await activityLogsService.addEntry(sessionId, "Upload started");
|
|
25623
|
-
let success = true;
|
|
25624
|
-
const StrapiService2 = getStrapiService();
|
|
25625
|
-
const StrapiI18nService2 = getStrapiI18nService();
|
|
25626
|
-
const LocalazyUploadService2 = getLocalazyUploadService();
|
|
25627
|
-
const EntryExclusionService2 = getEntryExclusionService();
|
|
25628
|
-
const contentTransferSetup = await getPluginSettingsService().getContentTransferSetup();
|
|
25629
|
-
if (!contentTransferSetup.has_setup) {
|
|
25630
|
-
const message = "Content transfer setup is not set up.";
|
|
25631
|
-
success = false;
|
|
25632
|
-
await notificationService.emit(EventType.UPLOAD_FINISHED, {
|
|
25633
|
-
success,
|
|
25634
|
-
message
|
|
25635
|
-
});
|
|
25636
|
-
await activityLogsService.addEntry(sessionId, message);
|
|
25637
|
-
await activityLogsService.finishSession(sessionId, "failed", message);
|
|
25638
|
-
strapi2.log.info(message);
|
|
25639
|
-
return;
|
|
25640
|
-
}
|
|
25641
|
-
const { setup: setup2 } = contentTransferSetup;
|
|
25642
|
-
const collectionsNames = getCollectionsNames(setup2);
|
|
25643
|
-
const models = await StrapiService2.getModels();
|
|
25644
|
-
const strapiDefaultLocaleCode = await StrapiI18nService2.getDefaultLocaleCode();
|
|
25645
|
-
const attemptedTuples = [];
|
|
25646
|
-
let pickedFlattenStrapiContent = {};
|
|
25647
|
-
for (const collectionName of collectionsNames) {
|
|
25648
|
-
const currentModel = models.find((model) => model.collectionName === collectionName);
|
|
25649
|
-
const modelUid = currentModel.uid;
|
|
25650
|
-
if (!currentModel) {
|
|
25651
|
-
strapi2.log.warn(`Model with uid ${modelUid} is not found.`);
|
|
25652
|
-
continue;
|
|
25653
|
-
}
|
|
25654
|
-
const transferSetupModel = findSetupModelByCollectionName(setup2, collectionName);
|
|
25655
|
-
if (!isCollectionTransferEnabled(setup2, collectionName)) {
|
|
25656
|
-
const message2 = `Collection ${collectionName} transfer is disabled.`;
|
|
25657
|
-
await notificationService.emit(EventType.UPLOAD, {
|
|
25658
|
-
message: message2
|
|
25659
|
-
});
|
|
25660
|
-
await activityLogsService.addEntry(sessionId, message2);
|
|
25661
|
-
strapi2.log.info(message2);
|
|
25662
|
-
continue;
|
|
25663
|
-
}
|
|
25664
|
-
const currentTransferSetupModel = transferSetupModel[collectionName];
|
|
25665
|
-
const pickPaths = getPickPathsWithComponents(currentTransferSetupModel);
|
|
25666
|
-
if (!pickPaths.length) {
|
|
25667
|
-
const message2 = `No fields for collection ${collectionName} transfer are enabled.`;
|
|
25668
|
-
await notificationService.emit(EventType.UPLOAD, {
|
|
25669
|
-
message: message2
|
|
25670
|
-
});
|
|
25671
|
-
await activityLogsService.addEntry(sessionId, message2);
|
|
25672
|
-
strapi2.log.warn(message2);
|
|
25673
|
-
continue;
|
|
25674
|
-
}
|
|
25675
|
-
const pickPathsWithUid = pickPaths.map((pickPath) => `${modelUid}.${pickPath}`);
|
|
25676
|
-
let entries = await strapi2.documents(modelUid).findMany({
|
|
25677
|
-
locUploadPLevel: 6,
|
|
25678
|
-
status: "draft"
|
|
25679
|
-
});
|
|
25680
|
-
if (!entries.length) {
|
|
25681
|
-
strapi2.log.info(`No entries found for model ${modelUid}`);
|
|
25682
|
-
continue;
|
|
25683
|
-
}
|
|
25684
|
-
const excludedEntries = await EntryExclusionService2.getContentTypeExclusions(modelUid);
|
|
25685
|
-
const filteredEntries = [];
|
|
25686
|
-
for (const entry of entries) {
|
|
25687
|
-
const isExcluded = excludedEntries.includes(entry.documentId);
|
|
25688
|
-
if (!isExcluded) {
|
|
25689
|
-
filteredEntries.push(entry);
|
|
25690
|
-
}
|
|
25691
|
-
}
|
|
25692
|
-
entries = filteredEntries;
|
|
25693
|
-
if (!entries.length) {
|
|
25694
|
-
const message2 = `All entries for model ${collectionName} are excluded from translation`;
|
|
25695
|
-
await notificationService.emit(EventType.UPLOAD, {
|
|
25696
|
-
message: message2
|
|
25697
|
-
});
|
|
25698
|
-
await activityLogsService.addEntry(sessionId, message2);
|
|
25699
|
-
strapi2.log.info(message2);
|
|
25700
|
-
continue;
|
|
25701
|
-
}
|
|
25702
|
-
const message = `Excluding ${excludedEntries.length} entries for model ${collectionName} from upload. Entries to translate: ${entries.length}.`;
|
|
25703
|
-
await notificationService.emit(EventType.UPLOAD, {
|
|
25704
|
-
message
|
|
25705
|
-
});
|
|
25706
|
-
await activityLogsService.addEntry(sessionId, message);
|
|
25707
|
-
strapi2.log.info(message);
|
|
25708
|
-
if (strapiDefaultLocaleCode) {
|
|
25709
|
-
for (const entry of entries) {
|
|
25710
|
-
attemptedTuples.push({
|
|
25711
|
-
uid: modelUid,
|
|
25712
|
-
documentId: entry.documentId,
|
|
25713
|
-
locale: strapiDefaultLocaleCode
|
|
25714
|
-
});
|
|
25715
|
-
}
|
|
25716
|
-
}
|
|
25717
|
-
entries = omitDeep(entries, ["locale", "createdAt", "updatedAt", "publishedAt"]);
|
|
25718
|
-
entries.forEach((entry) => {
|
|
25719
|
-
const flatten = flattenObject({
|
|
25720
|
-
[modelUid]: entry
|
|
25721
|
-
});
|
|
25722
|
-
const pickedFlatten = pickEntries(flatten, pickPathsWithUid);
|
|
25723
|
-
pickedFlattenStrapiContent = {
|
|
25724
|
-
...pickedFlattenStrapiContent,
|
|
25725
|
-
...pickedFlatten
|
|
25726
|
-
};
|
|
25727
|
-
});
|
|
25728
|
-
const characterLimitsMetadata = getCharacterLimitsMetadata(pickedFlattenStrapiContent, modelUid);
|
|
25729
|
-
pickedFlattenStrapiContent = {
|
|
25730
|
-
...pickedFlattenStrapiContent,
|
|
25731
|
-
...characterLimitsMetadata
|
|
25732
|
-
};
|
|
25733
|
-
}
|
|
25734
|
-
const localazyLocaleCode = strapiDefaultLocaleCode ? isoStrapiToLocalazy(strapiDefaultLocaleCode) : config.default.LOCALAZY_DEFAULT_LOCALE;
|
|
25735
|
-
const importFile = LocalazyUploadService2.createImportFileRepresentation(
|
|
25736
|
-
localazyLocaleCode,
|
|
25737
|
-
pickedFlattenStrapiContent
|
|
25738
|
-
);
|
|
25739
|
-
const uploadConfig = {
|
|
25740
|
-
contentOptions: {
|
|
25741
|
-
type: config.default.LOCALAZY_DEFAULT_FILE_EXTENSION
|
|
25742
|
-
},
|
|
25743
|
-
i18nOptions: { deprecate: "file" },
|
|
25744
|
-
fileOptions: {
|
|
25745
|
-
name: config.default.LOCALAZY_DEFAULT_FILE_NAME,
|
|
25746
|
-
path: config.default.LOCALAZY_DEFAULT_FILE_PATH
|
|
25747
|
-
}
|
|
25748
|
-
};
|
|
25749
|
-
await notificationService.emit(EventType.UPLOAD, {
|
|
25750
|
-
message: "Uploading collections to Localazy..."
|
|
25751
|
-
});
|
|
25752
|
-
await activityLogsService.addEntry(sessionId, "Uploading collections to Localazy...");
|
|
25753
|
-
try {
|
|
25754
|
-
await LocalazyUploadService2.upload(importFile, uploadConfig);
|
|
25755
|
-
await activityLogsService.recordAttemptedEntries(
|
|
25756
|
-
sessionId,
|
|
25757
|
-
attemptedTuples.map((t3) => ({ ...t3, status: "success" }))
|
|
25758
|
-
);
|
|
25759
|
-
} catch (error) {
|
|
25760
|
-
success = false;
|
|
25761
|
-
const errorMessage = `Upload to Localazy failed: ${error instanceof Error ? error.message : String(error)}`;
|
|
25762
|
-
strapi2.log.error(errorMessage);
|
|
25763
|
-
await notificationService.emit(EventType.UPLOAD_FINISHED, {
|
|
25764
|
-
success,
|
|
25765
|
-
message: errorMessage
|
|
25766
|
-
});
|
|
25767
|
-
await activityLogsService.addEntry(sessionId, errorMessage);
|
|
25768
|
-
await activityLogsService.recordAttemptedEntries(
|
|
25769
|
-
sessionId,
|
|
25770
|
-
attemptedTuples.map((t3) => ({ ...t3, status: "failed", errorMessage }))
|
|
25771
|
-
);
|
|
25772
|
-
await activityLogsService.finishSession(sessionId, "failed", errorMessage);
|
|
25773
|
-
console.timeEnd("upload");
|
|
25774
|
-
return;
|
|
25775
|
-
}
|
|
25776
|
-
strapi2.log.info("Upload finished in");
|
|
25777
|
-
await notificationService.emit(EventType.UPLOAD_FINISHED, {
|
|
25778
|
-
success,
|
|
25779
|
-
message: "Upload finished"
|
|
25780
|
-
});
|
|
25781
|
-
await activityLogsService.addEntry(sessionId, "Upload finished");
|
|
25782
|
-
await activityLogsService.finishSession(
|
|
25783
|
-
sessionId,
|
|
25784
|
-
success ? "completed" : "failed",
|
|
25785
|
-
success ? "Upload completed successfully" : "Upload finished with errors"
|
|
25786
|
-
);
|
|
25787
|
-
console.timeEnd("upload");
|
|
25788
|
-
}
|
|
25789
|
-
});
|
|
25790
25614
|
var symbolTag$2 = "[object Symbol]";
|
|
25791
25615
|
function isSymbol(value) {
|
|
25792
25616
|
return typeof value == "symbol" || isObjectLike(value) && baseGetTag(value) == symbolTag$2;
|
|
@@ -26101,6 +25925,263 @@ function baseSet(object, path, value, customizer) {
|
|
|
26101
25925
|
function set(object, path, value) {
|
|
26102
25926
|
return object == null ? object : baseSet(object, path, value);
|
|
26103
25927
|
}
|
|
25928
|
+
const BLOCKS_ATTRIBUTE_TYPE = "blocks";
|
|
25929
|
+
const projectBlocksFields = (entry, model, getModel) => {
|
|
25930
|
+
const cloned = cloneDeep(entry);
|
|
25931
|
+
walkAndProject(cloned, model, getModel);
|
|
25932
|
+
return cloned;
|
|
25933
|
+
};
|
|
25934
|
+
const walkAndProject = (value, model, getModel) => {
|
|
25935
|
+
if (!value || !model?.attributes) {
|
|
25936
|
+
return;
|
|
25937
|
+
}
|
|
25938
|
+
for (const [attributeName, attribute] of Object.entries(model.attributes)) {
|
|
25939
|
+
const fieldValue = value[attributeName];
|
|
25940
|
+
if (fieldValue === void 0 || fieldValue === null) {
|
|
25941
|
+
continue;
|
|
25942
|
+
}
|
|
25943
|
+
if (attribute.type === BLOCKS_ATTRIBUTE_TYPE) {
|
|
25944
|
+
value[attributeName] = projectBlocksValue(fieldValue);
|
|
25945
|
+
} else if (attribute.type === "component") {
|
|
25946
|
+
const componentModel = getModel(attribute.component);
|
|
25947
|
+
if (attribute.repeatable && Array.isArray(fieldValue)) {
|
|
25948
|
+
fieldValue.forEach((item) => walkAndProject(item, componentModel, getModel));
|
|
25949
|
+
} else if (isPlainObject(fieldValue)) {
|
|
25950
|
+
walkAndProject(fieldValue, componentModel, getModel);
|
|
25951
|
+
}
|
|
25952
|
+
} else if (attribute.type === "dynamiczone" && Array.isArray(fieldValue)) {
|
|
25953
|
+
fieldValue.forEach((item) => {
|
|
25954
|
+
if (item?.__component) {
|
|
25955
|
+
walkAndProject(item, getModel(item.__component), getModel);
|
|
25956
|
+
}
|
|
25957
|
+
});
|
|
25958
|
+
}
|
|
25959
|
+
}
|
|
25960
|
+
};
|
|
25961
|
+
const projectBlocksValue = (nodes) => {
|
|
25962
|
+
if (!Array.isArray(nodes)) {
|
|
25963
|
+
return nodes;
|
|
25964
|
+
}
|
|
25965
|
+
return nodes.map(projectNode);
|
|
25966
|
+
};
|
|
25967
|
+
const projectNode = (node) => {
|
|
25968
|
+
if (!isPlainObject(node)) {
|
|
25969
|
+
return {};
|
|
25970
|
+
}
|
|
25971
|
+
const projected = {};
|
|
25972
|
+
if (typeof node.text === "string") {
|
|
25973
|
+
projected.text = node.text;
|
|
25974
|
+
}
|
|
25975
|
+
if (Array.isArray(node.children)) {
|
|
25976
|
+
projected.children = node.children.map(projectNode);
|
|
25977
|
+
}
|
|
25978
|
+
return projected;
|
|
25979
|
+
};
|
|
25980
|
+
const overlayBlocksTranslation = (sourceAst, translated) => {
|
|
25981
|
+
if (!Array.isArray(sourceAst)) {
|
|
25982
|
+
return void 0;
|
|
25983
|
+
}
|
|
25984
|
+
return sourceAst.map((node, index2) => overlayNode(node, get(translated, [String(index2)])));
|
|
25985
|
+
};
|
|
25986
|
+
const overlayNode = (node, translatedNode) => {
|
|
25987
|
+
if (!isPlainObject(node)) {
|
|
25988
|
+
return cloneDeep(node);
|
|
25989
|
+
}
|
|
25990
|
+
if (typeof node.text === "string") {
|
|
25991
|
+
const translatedText = isPlainObject(translatedNode) ? translatedNode.text : void 0;
|
|
25992
|
+
return typeof translatedText === "string" ? { ...node, text: translatedText } : cloneDeep(node);
|
|
25993
|
+
}
|
|
25994
|
+
if (Array.isArray(node.children)) {
|
|
25995
|
+
return {
|
|
25996
|
+
...node,
|
|
25997
|
+
children: node.children.map(
|
|
25998
|
+
(child, index2) => overlayNode(child, translatedNode ? get(translatedNode, ["children", String(index2)]) : void 0)
|
|
25999
|
+
)
|
|
26000
|
+
};
|
|
26001
|
+
}
|
|
26002
|
+
return cloneDeep(node);
|
|
26003
|
+
};
|
|
26004
|
+
const LocalazyTransferUploadService = ({ strapi: strapi2 }) => ({
|
|
26005
|
+
async upload({ notificationService }) {
|
|
26006
|
+
console.time("upload");
|
|
26007
|
+
await notificationService.emit(EventType.UPLOAD, {
|
|
26008
|
+
message: "Upload started"
|
|
26009
|
+
});
|
|
26010
|
+
const activityLogsService = getActivityLogsService();
|
|
26011
|
+
const sessionId = await activityLogsService.startSession("upload", "Strapi User");
|
|
26012
|
+
await activityLogsService.addEntry(sessionId, "Upload started");
|
|
26013
|
+
let success = true;
|
|
26014
|
+
const StrapiService2 = getStrapiService();
|
|
26015
|
+
const StrapiI18nService2 = getStrapiI18nService();
|
|
26016
|
+
const LocalazyUploadService2 = getLocalazyUploadService();
|
|
26017
|
+
const EntryExclusionService2 = getEntryExclusionService();
|
|
26018
|
+
const contentTransferSetup = await getPluginSettingsService().getContentTransferSetup();
|
|
26019
|
+
if (!contentTransferSetup.has_setup) {
|
|
26020
|
+
const message = "Content transfer setup is not set up.";
|
|
26021
|
+
success = false;
|
|
26022
|
+
await notificationService.emit(EventType.UPLOAD_FINISHED, {
|
|
26023
|
+
success,
|
|
26024
|
+
message
|
|
26025
|
+
});
|
|
26026
|
+
await activityLogsService.addEntry(sessionId, message);
|
|
26027
|
+
await activityLogsService.finishSession(sessionId, "failed", message);
|
|
26028
|
+
strapi2.log.info(message);
|
|
26029
|
+
return;
|
|
26030
|
+
}
|
|
26031
|
+
const { setup: setup2 } = contentTransferSetup;
|
|
26032
|
+
const collectionsNames = getCollectionsNames(setup2);
|
|
26033
|
+
const models = await StrapiService2.getModels();
|
|
26034
|
+
const strapiDefaultLocaleCode = await StrapiI18nService2.getDefaultLocaleCode();
|
|
26035
|
+
const attemptedTuples = [];
|
|
26036
|
+
let pickedFlattenStrapiContent = {};
|
|
26037
|
+
for (const collectionName of collectionsNames) {
|
|
26038
|
+
const currentModel = models.find((model) => model.collectionName === collectionName);
|
|
26039
|
+
const modelUid = currentModel.uid;
|
|
26040
|
+
if (!currentModel) {
|
|
26041
|
+
strapi2.log.warn(`Model with uid ${modelUid} is not found.`);
|
|
26042
|
+
continue;
|
|
26043
|
+
}
|
|
26044
|
+
const transferSetupModel = findSetupModelByCollectionName(setup2, collectionName);
|
|
26045
|
+
if (!isCollectionTransferEnabled(setup2, collectionName)) {
|
|
26046
|
+
const message2 = `Collection ${collectionName} transfer is disabled.`;
|
|
26047
|
+
await notificationService.emit(EventType.UPLOAD, {
|
|
26048
|
+
message: message2
|
|
26049
|
+
});
|
|
26050
|
+
await activityLogsService.addEntry(sessionId, message2);
|
|
26051
|
+
strapi2.log.info(message2);
|
|
26052
|
+
continue;
|
|
26053
|
+
}
|
|
26054
|
+
const currentTransferSetupModel = transferSetupModel[collectionName];
|
|
26055
|
+
const pickPaths = getPickPathsWithComponents(currentTransferSetupModel);
|
|
26056
|
+
if (!pickPaths.length) {
|
|
26057
|
+
const message2 = `No fields for collection ${collectionName} transfer are enabled.`;
|
|
26058
|
+
await notificationService.emit(EventType.UPLOAD, {
|
|
26059
|
+
message: message2
|
|
26060
|
+
});
|
|
26061
|
+
await activityLogsService.addEntry(sessionId, message2);
|
|
26062
|
+
strapi2.log.warn(message2);
|
|
26063
|
+
continue;
|
|
26064
|
+
}
|
|
26065
|
+
const pickPathsWithUid = pickPaths.map((pickPath) => `${modelUid}.${pickPath}`);
|
|
26066
|
+
let entries = await strapi2.documents(modelUid).findMany({
|
|
26067
|
+
locUploadPLevel: 6,
|
|
26068
|
+
status: "draft"
|
|
26069
|
+
});
|
|
26070
|
+
if (!entries.length) {
|
|
26071
|
+
strapi2.log.info(`No entries found for model ${modelUid}`);
|
|
26072
|
+
continue;
|
|
26073
|
+
}
|
|
26074
|
+
const excludedEntries = await EntryExclusionService2.getContentTypeExclusions(modelUid);
|
|
26075
|
+
const filteredEntries = [];
|
|
26076
|
+
for (const entry of entries) {
|
|
26077
|
+
const isExcluded = excludedEntries.includes(entry.documentId);
|
|
26078
|
+
if (!isExcluded) {
|
|
26079
|
+
filteredEntries.push(entry);
|
|
26080
|
+
}
|
|
26081
|
+
}
|
|
26082
|
+
entries = filteredEntries;
|
|
26083
|
+
if (!entries.length) {
|
|
26084
|
+
const message2 = `All entries for model ${collectionName} are excluded from translation`;
|
|
26085
|
+
await notificationService.emit(EventType.UPLOAD, {
|
|
26086
|
+
message: message2
|
|
26087
|
+
});
|
|
26088
|
+
await activityLogsService.addEntry(sessionId, message2);
|
|
26089
|
+
strapi2.log.info(message2);
|
|
26090
|
+
continue;
|
|
26091
|
+
}
|
|
26092
|
+
const message = `Excluding ${excludedEntries.length} entries for model ${collectionName} from upload. Entries to translate: ${entries.length}.`;
|
|
26093
|
+
await notificationService.emit(EventType.UPLOAD, {
|
|
26094
|
+
message
|
|
26095
|
+
});
|
|
26096
|
+
await activityLogsService.addEntry(sessionId, message);
|
|
26097
|
+
strapi2.log.info(message);
|
|
26098
|
+
if (strapiDefaultLocaleCode) {
|
|
26099
|
+
for (const entry of entries) {
|
|
26100
|
+
attemptedTuples.push({
|
|
26101
|
+
uid: modelUid,
|
|
26102
|
+
documentId: entry.documentId,
|
|
26103
|
+
locale: strapiDefaultLocaleCode
|
|
26104
|
+
});
|
|
26105
|
+
}
|
|
26106
|
+
}
|
|
26107
|
+
entries = omitDeep(entries, ["locale", "createdAt", "updatedAt", "publishedAt"]);
|
|
26108
|
+
entries.forEach((entry) => {
|
|
26109
|
+
const projectedEntry = projectBlocksFields(
|
|
26110
|
+
entry,
|
|
26111
|
+
strapi2.getModel(modelUid),
|
|
26112
|
+
(uid) => strapi2.getModel(uid)
|
|
26113
|
+
);
|
|
26114
|
+
const flatten = flattenObject({
|
|
26115
|
+
[modelUid]: projectedEntry
|
|
26116
|
+
});
|
|
26117
|
+
const pickedFlatten = pickEntries(flatten, pickPathsWithUid);
|
|
26118
|
+
pickedFlattenStrapiContent = {
|
|
26119
|
+
...pickedFlattenStrapiContent,
|
|
26120
|
+
...pickedFlatten
|
|
26121
|
+
};
|
|
26122
|
+
});
|
|
26123
|
+
const characterLimitsMetadata = getCharacterLimitsMetadata(pickedFlattenStrapiContent, modelUid);
|
|
26124
|
+
pickedFlattenStrapiContent = {
|
|
26125
|
+
...pickedFlattenStrapiContent,
|
|
26126
|
+
...characterLimitsMetadata
|
|
26127
|
+
};
|
|
26128
|
+
}
|
|
26129
|
+
const localazyLocaleCode = strapiDefaultLocaleCode ? isoStrapiToLocalazy(strapiDefaultLocaleCode) : config.default.LOCALAZY_DEFAULT_LOCALE;
|
|
26130
|
+
const importFile = LocalazyUploadService2.createImportFileRepresentation(
|
|
26131
|
+
localazyLocaleCode,
|
|
26132
|
+
pickedFlattenStrapiContent
|
|
26133
|
+
);
|
|
26134
|
+
const uploadConfig = {
|
|
26135
|
+
contentOptions: {
|
|
26136
|
+
type: config.default.LOCALAZY_DEFAULT_FILE_EXTENSION
|
|
26137
|
+
},
|
|
26138
|
+
i18nOptions: { deprecate: "file" },
|
|
26139
|
+
fileOptions: {
|
|
26140
|
+
name: config.default.LOCALAZY_DEFAULT_FILE_NAME,
|
|
26141
|
+
path: config.default.LOCALAZY_DEFAULT_FILE_PATH
|
|
26142
|
+
}
|
|
26143
|
+
};
|
|
26144
|
+
await notificationService.emit(EventType.UPLOAD, {
|
|
26145
|
+
message: "Uploading collections to Localazy..."
|
|
26146
|
+
});
|
|
26147
|
+
await activityLogsService.addEntry(sessionId, "Uploading collections to Localazy...");
|
|
26148
|
+
try {
|
|
26149
|
+
await LocalazyUploadService2.upload(importFile, uploadConfig);
|
|
26150
|
+
await activityLogsService.recordAttemptedEntries(
|
|
26151
|
+
sessionId,
|
|
26152
|
+
attemptedTuples.map((t3) => ({ ...t3, status: "success" }))
|
|
26153
|
+
);
|
|
26154
|
+
} catch (error) {
|
|
26155
|
+
success = false;
|
|
26156
|
+
const errorMessage = `Upload to Localazy failed: ${error instanceof Error ? error.message : String(error)}`;
|
|
26157
|
+
strapi2.log.error(errorMessage);
|
|
26158
|
+
await notificationService.emit(EventType.UPLOAD_FINISHED, {
|
|
26159
|
+
success,
|
|
26160
|
+
message: errorMessage
|
|
26161
|
+
});
|
|
26162
|
+
await activityLogsService.addEntry(sessionId, errorMessage);
|
|
26163
|
+
await activityLogsService.recordAttemptedEntries(
|
|
26164
|
+
sessionId,
|
|
26165
|
+
attemptedTuples.map((t3) => ({ ...t3, status: "failed", errorMessage }))
|
|
26166
|
+
);
|
|
26167
|
+
await activityLogsService.finishSession(sessionId, "failed", errorMessage);
|
|
26168
|
+
console.timeEnd("upload");
|
|
26169
|
+
return;
|
|
26170
|
+
}
|
|
26171
|
+
strapi2.log.info("Upload finished in");
|
|
26172
|
+
await notificationService.emit(EventType.UPLOAD_FINISHED, {
|
|
26173
|
+
success,
|
|
26174
|
+
message: "Upload finished"
|
|
26175
|
+
});
|
|
26176
|
+
await activityLogsService.addEntry(sessionId, "Upload finished");
|
|
26177
|
+
await activityLogsService.finishSession(
|
|
26178
|
+
sessionId,
|
|
26179
|
+
success ? "completed" : "failed",
|
|
26180
|
+
success ? "Upload completed successfully" : "Upload finished with errors"
|
|
26181
|
+
);
|
|
26182
|
+
console.timeEnd("upload");
|
|
26183
|
+
}
|
|
26184
|
+
});
|
|
26104
26185
|
const hasDynamicZoneKeySegment = (parsedKey) => {
|
|
26105
26186
|
return parsedKey.some((segment) => segment.includes(";"));
|
|
26106
26187
|
};
|
|
@@ -26788,6 +26869,9 @@ const isRepeatable = (attributeObj) => {
|
|
|
26788
26869
|
const isRelation = (attributeObj) => {
|
|
26789
26870
|
return attributeObj.type === "relation" && attributeObj.target !== "plugin::upload.file";
|
|
26790
26871
|
};
|
|
26872
|
+
const isBlocks = (attributeObj) => {
|
|
26873
|
+
return attributeObj.type === BLOCKS_ATTRIBUTE_TYPE;
|
|
26874
|
+
};
|
|
26791
26875
|
const findModel = (models, uid) => {
|
|
26792
26876
|
const model = models.find((model2) => model2.uid === uid);
|
|
26793
26877
|
return model;
|
|
@@ -26931,7 +27015,11 @@ const parsedLocalazyEntryToCreateEntry = (models, parsedLocalazyEntry, baseEntry
|
|
|
26931
27015
|
newPrefixBase = `${dzParamKey}.${baseEntryDZIndex}`;
|
|
26932
27016
|
newPrefix = `${newPrefixBase}.${objectKey}`;
|
|
26933
27017
|
}
|
|
26934
|
-
|
|
27018
|
+
const valueToSet = isBlocks(attribute) ? overlayBlocksTranslation(get(baseEntry, newPrefix), value) : value;
|
|
27019
|
+
if (valueToSet === void 0) {
|
|
27020
|
+
return;
|
|
27021
|
+
}
|
|
27022
|
+
set(createEntry, newPrefix, valueToSet);
|
|
26935
27023
|
if (component) {
|
|
26936
27024
|
const componentKeyToSet = `${newPrefixBase}.__component`;
|
|
26937
27025
|
set(createEntry, componentKeyToSet, component);
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
export declare const BLOCKS_ATTRIBUTE_TYPE = "blocks";
|
|
2
|
+
type GetModel = (uid: string) => {
|
|
3
|
+
attributes?: Record<string, any>;
|
|
4
|
+
} | undefined;
|
|
5
|
+
/**
|
|
6
|
+
* Upload side. A Blocks value is a rich-text AST: text lives in `text` leaves, everything else
|
|
7
|
+
* (block types, headings, lists, links, marks, images, quotes, code blocks) is structure. We
|
|
8
|
+
* project each blocks field down to a skeleton that keeps only the translatable text leaves in
|
|
9
|
+
* their original positions, so the transfer pipeline emits ONE segment per text node with the
|
|
10
|
+
* formatting carried as structure — never as literal markup inside the string. The dropped
|
|
11
|
+
* structure is restored from the source AST on download (see `overlayBlocksTranslation`). Blocks
|
|
12
|
+
* nested inside components / dynamic zones are reached by walking the schema. The source entry is
|
|
13
|
+
* not mutated.
|
|
14
|
+
*/
|
|
15
|
+
export declare const projectBlocksFields: (entry: any, model: any, getModel: GetModel) => any;
|
|
16
|
+
/**
|
|
17
|
+
* Reduce a blocks AST to a text-only skeleton: every node keeps only its `text` leaf and/or its
|
|
18
|
+
* (recursively projected) `children`. Structural nodes without text (e.g. images, dividers) become
|
|
19
|
+
* empty and contribute no segment. Positions are preserved so download can overlay by path.
|
|
20
|
+
*/
|
|
21
|
+
export declare const projectBlocksValue: (nodes: any) => any;
|
|
22
|
+
/**
|
|
23
|
+
* Download side. Rebuild a full blocks AST for the target locale by cloning the source-locale AST
|
|
24
|
+
* and overlaying the translated text onto each text leaf at the matching position. All structure
|
|
25
|
+
* and formatting come from the source, so the result is always a document Strapi accepts, a
|
|
26
|
+
* translation identical to the source round-trips byte-identically, and text nodes left
|
|
27
|
+
* untranslated fall back to the source text. `translated` is the per-node text skeleton
|
|
28
|
+
* reconstructed from the downloaded keys (an array, or an object keyed by numeric position).
|
|
29
|
+
*
|
|
30
|
+
* Returns `undefined` when there is no source AST to overlay onto (nothing safe to write), so the
|
|
31
|
+
* caller can skip the field instead of corrupting it.
|
|
32
|
+
*/
|
|
33
|
+
export declare const overlayBlocksTranslation: (sourceAst: any, translated: any) => any[] | undefined;
|
|
34
|
+
export {};
|
|
@@ -3,5 +3,6 @@ declare const isComponent: (attributeObj: any) => boolean;
|
|
|
3
3
|
declare const isDynamicZone: (attributeObj: any) => boolean;
|
|
4
4
|
declare const isRepeatable: (attributeObj: any) => boolean;
|
|
5
5
|
declare const isRelation: (attributeObj: any) => boolean;
|
|
6
|
+
declare const isBlocks: (attributeObj: any) => boolean;
|
|
6
7
|
declare const findModel: (models: any, uid: any) => any;
|
|
7
|
-
export { getAttribute, isComponent, isDynamicZone, isRepeatable, isRelation, findModel };
|
|
8
|
+
export { getAttribute, isComponent, isDynamicZone, isRepeatable, isRelation, isBlocks, findModel };
|