@translationstudio/translationstudio-strapi-extension 1.1.0 → 1.1.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.
- package/dist/admin/index.js +6 -12
- package/dist/admin/index.mjs +6 -12
- package/dist/server/index.js +257 -208
- package/dist/server/index.mjs +257 -208
- package/dist/server/src/services/functions/exportData/jsonToHtml.d.ts +6 -2
- package/dist/server/src/services/functions/importData/htmlToJson.d.ts +1 -2
- package/dist/server/src/services/functions/importData/parseInlineElements.d.ts +21 -1
- package/dist/server/src/services/functions/importData/processComponentFields.d.ts +1 -1
- package/dist/server/src/services/functions/importData/updateEntry.d.ts +1 -1
- package/dist/server/src/services/service.d.ts +2 -2
- package/package.json +1 -1
package/dist/server/index.js
CHANGED
|
@@ -289,49 +289,54 @@ const getEntry = async (contentTypeID, entryID, locale) => {
|
|
|
289
289
|
const transformResponse = (data) => data.map(
|
|
290
290
|
(item) => item.realType === "blocks" && Array.isArray(item.translatableValue[0]) ? { ...item, translatableValue: item.translatableValue[0] } : item
|
|
291
291
|
);
|
|
292
|
+
function jsonToHtml(json) {
|
|
293
|
+
if (!json || !Array.isArray(json)) {
|
|
294
|
+
return "";
|
|
295
|
+
}
|
|
296
|
+
return json.map((node) => processNode(node)).join("");
|
|
297
|
+
}
|
|
298
|
+
function processNode(node) {
|
|
299
|
+
if (!node) return "";
|
|
300
|
+
switch (node.type) {
|
|
301
|
+
case "paragraph":
|
|
302
|
+
return `<p>${node.children.map(processNode).join("")}</p>`;
|
|
303
|
+
case "heading":
|
|
304
|
+
const level = node.level || 1;
|
|
305
|
+
return `<h${level}>${node.children.map(processNode).join("")}</h${level}>`;
|
|
306
|
+
case "link":
|
|
307
|
+
const url = node.url || "#";
|
|
308
|
+
return `<a href="${url}">${node.children.map(processNode).join("")}</a>`;
|
|
309
|
+
case "list":
|
|
310
|
+
const listType = node.format === "ordered" ? "ol" : "ul";
|
|
311
|
+
return `<${listType}>${node.children.map(processNode).join("")}</${listType}>`;
|
|
312
|
+
case "list-item":
|
|
313
|
+
return `<li>${node.children.map(processNode).join("")}</li>`;
|
|
314
|
+
case "quote":
|
|
315
|
+
return `<blockquote>${node.children.map(processNode).join("")}</blockquote>`;
|
|
316
|
+
case "code":
|
|
317
|
+
return `<pre><code>${node.children.map((child) => child.text).join("")}</code></pre>`;
|
|
318
|
+
case "image":
|
|
319
|
+
return `<img src="${node.url}" alt="${node.alt || ""}" />`;
|
|
320
|
+
case "text":
|
|
321
|
+
return formatText(node);
|
|
322
|
+
default:
|
|
323
|
+
return node.children && Array.isArray(node.children) ? node.children.map(processNode).join("") : node.text || "";
|
|
324
|
+
}
|
|
325
|
+
}
|
|
292
326
|
function formatText(child) {
|
|
293
327
|
if (child.type === "link") {
|
|
294
|
-
return `<a href="${child.url}">${child.children.map((sub) => sub
|
|
328
|
+
return `<a href="${child.url}">${child.children.map((sub) => formatText(sub)).join("")}</a>`;
|
|
295
329
|
}
|
|
296
330
|
let text = child.text || "";
|
|
331
|
+
if (child.code) text = `<code>${text}</code>`;
|
|
297
332
|
if (child.bold) text = `<strong>${text}</strong>`;
|
|
298
333
|
if (child.italic) text = `<em>${text}</em>`;
|
|
299
334
|
if (child.underline) text = `<u>${text}</u>`;
|
|
300
|
-
if (child.strikethrough)
|
|
335
|
+
if (child.strikethrough) {
|
|
336
|
+
text = `~~${text}~~`;
|
|
337
|
+
}
|
|
301
338
|
return text;
|
|
302
339
|
}
|
|
303
|
-
function renderChildren(children) {
|
|
304
|
-
return children.map(formatText).join("");
|
|
305
|
-
}
|
|
306
|
-
function renderHeading(element) {
|
|
307
|
-
return `<h${element.level}>${renderChildren(element.children)}</h${element.level}>`;
|
|
308
|
-
}
|
|
309
|
-
function renderParagraph(element) {
|
|
310
|
-
return `<p>${renderChildren(element.children)}</p>`;
|
|
311
|
-
}
|
|
312
|
-
function renderList(element) {
|
|
313
|
-
const tag = element.format === "unordered" ? "ul" : "ol";
|
|
314
|
-
const items = element.children.map(renderListItem).join("");
|
|
315
|
-
return `<${tag}>${items}</${tag}>`;
|
|
316
|
-
}
|
|
317
|
-
function renderListItem(item) {
|
|
318
|
-
const content = item.children.map(formatText).join("");
|
|
319
|
-
return `<li>${content}</li>`;
|
|
320
|
-
}
|
|
321
|
-
function jsonToHtml(jsonData) {
|
|
322
|
-
return jsonData.map((element) => {
|
|
323
|
-
switch (element.type) {
|
|
324
|
-
case "heading":
|
|
325
|
-
return renderHeading(element);
|
|
326
|
-
case "paragraph":
|
|
327
|
-
return renderParagraph(element);
|
|
328
|
-
case "list":
|
|
329
|
-
return renderList(element);
|
|
330
|
-
default:
|
|
331
|
-
return "";
|
|
332
|
-
}
|
|
333
|
-
}).join("");
|
|
334
|
-
}
|
|
335
340
|
const processComponent = async (fieldName, componentName, value, schemaName, componentId) => {
|
|
336
341
|
const contentFields = [];
|
|
337
342
|
const componentSchema = await strapi.components[componentName];
|
|
@@ -529,149 +534,197 @@ const isDynamicZone = (fieldSchema, value, schema) => {
|
|
|
529
534
|
const isComponent = (fieldSchema, value, schema) => {
|
|
530
535
|
return fieldSchema.type === "component" && isFieldLocalizable(fieldSchema, schema);
|
|
531
536
|
};
|
|
532
|
-
function
|
|
533
|
-
|
|
534
|
-
|
|
537
|
+
function htmlToJson(html) {
|
|
538
|
+
function parseHTML(html2) {
|
|
539
|
+
const elements2 = [];
|
|
540
|
+
const tagRegex = /<([a-z0-9]+)((?:\s+[a-z-]+="[^"]*")*)\s*>([\s\S]*?)<\/\1>/gi;
|
|
541
|
+
let match;
|
|
542
|
+
while ((match = tagRegex.exec(html2)) !== null) {
|
|
543
|
+
const [, tag, attributes, content] = match;
|
|
544
|
+
const attrs = {};
|
|
545
|
+
const attrRegex = /([a-z-]+)="([^"]*)"/gi;
|
|
546
|
+
let attrMatch;
|
|
547
|
+
while ((attrMatch = attrRegex.exec(attributes)) !== null) {
|
|
548
|
+
attrs[attrMatch[1]] = attrMatch[2];
|
|
549
|
+
}
|
|
550
|
+
elements2.push({ tag, attrs, content });
|
|
551
|
+
}
|
|
552
|
+
return elements2;
|
|
535
553
|
}
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
let
|
|
554
|
+
function parseInlineContent(content) {
|
|
555
|
+
const segments = [];
|
|
556
|
+
let currentText = "";
|
|
557
|
+
let formatStack = [];
|
|
558
|
+
let currentFormat = {
|
|
559
|
+
bold: false,
|
|
560
|
+
italic: false,
|
|
561
|
+
underline: false,
|
|
562
|
+
code: false,
|
|
563
|
+
strikethrough: false
|
|
564
|
+
};
|
|
565
|
+
const pushSegment = () => {
|
|
566
|
+
if (currentText) {
|
|
567
|
+
segments.push({
|
|
568
|
+
type: "text",
|
|
569
|
+
text: currentText,
|
|
570
|
+
...Object.fromEntries(Object.entries(currentFormat).filter(([_, value]) => value))
|
|
571
|
+
});
|
|
572
|
+
currentText = "";
|
|
573
|
+
}
|
|
574
|
+
};
|
|
575
|
+
const tags = content.split(/(<[^>]+>|~~)/);
|
|
576
|
+
for (const tag of tags) {
|
|
577
|
+
if (!tag) continue;
|
|
578
|
+
if (tag === "~~") {
|
|
579
|
+
pushSegment();
|
|
580
|
+
currentFormat.strikethrough = !currentFormat.strikethrough;
|
|
581
|
+
continue;
|
|
582
|
+
}
|
|
583
|
+
if (tag.startsWith("<")) {
|
|
584
|
+
pushSegment();
|
|
585
|
+
if (tag.startsWith("</")) {
|
|
586
|
+
const tagName = tag.slice(2, -1).toLowerCase();
|
|
587
|
+
const lastTag = formatStack.pop();
|
|
588
|
+
if (lastTag && lastTag.type === tagName) {
|
|
589
|
+
switch (tagName) {
|
|
590
|
+
case "strong":
|
|
591
|
+
currentFormat.bold = false;
|
|
592
|
+
break;
|
|
593
|
+
case "em":
|
|
594
|
+
currentFormat.italic = false;
|
|
595
|
+
break;
|
|
596
|
+
case "u":
|
|
597
|
+
currentFormat.underline = false;
|
|
598
|
+
break;
|
|
599
|
+
case "code":
|
|
600
|
+
currentFormat.code = false;
|
|
601
|
+
break;
|
|
602
|
+
case "del":
|
|
603
|
+
currentFormat.strikethrough = false;
|
|
604
|
+
break;
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
} else {
|
|
608
|
+
const tagName = tag.slice(1, -1).toLowerCase();
|
|
609
|
+
formatStack.push({ type: tagName, index: segments.length });
|
|
610
|
+
switch (tagName) {
|
|
611
|
+
case "strong":
|
|
612
|
+
currentFormat.bold = true;
|
|
613
|
+
break;
|
|
614
|
+
case "em":
|
|
615
|
+
currentFormat.italic = true;
|
|
616
|
+
break;
|
|
617
|
+
case "u":
|
|
618
|
+
currentFormat.underline = true;
|
|
619
|
+
break;
|
|
620
|
+
case "code":
|
|
621
|
+
currentFormat.code = true;
|
|
622
|
+
break;
|
|
623
|
+
case "del":
|
|
624
|
+
currentFormat.strikethrough = true;
|
|
625
|
+
break;
|
|
626
|
+
}
|
|
627
|
+
}
|
|
628
|
+
} else {
|
|
629
|
+
currentText += tag;
|
|
630
|
+
}
|
|
631
|
+
}
|
|
632
|
+
pushSegment();
|
|
633
|
+
return segments.filter((segment) => segment.text.length > 0);
|
|
634
|
+
}
|
|
635
|
+
function parseList(html2, format) {
|
|
636
|
+
const listItems = html2.match(/<li>([\s\S]*?)<\/li>/g) || [];
|
|
637
|
+
return {
|
|
638
|
+
type: "list",
|
|
639
|
+
format,
|
|
640
|
+
children: listItems.map((item) => ({
|
|
641
|
+
type: "list-item",
|
|
642
|
+
children: parseListContent(item.replace(/<li>|<\/li>/g, ""))
|
|
643
|
+
}))
|
|
644
|
+
};
|
|
645
|
+
}
|
|
646
|
+
function parseListContent(content) {
|
|
647
|
+
const children = [];
|
|
648
|
+
const linkRegex = /<a\s+href="([^"]+)">([\s\S]*?)<\/a>/g;
|
|
539
649
|
let lastIndex = 0;
|
|
540
|
-
|
|
541
|
-
while ((
|
|
542
|
-
const [fullMatch,
|
|
543
|
-
if (
|
|
544
|
-
const
|
|
545
|
-
if (
|
|
546
|
-
|
|
650
|
+
let match;
|
|
651
|
+
while ((match = linkRegex.exec(content)) !== null) {
|
|
652
|
+
const [fullMatch, href, linkText] = match;
|
|
653
|
+
if (match.index > lastIndex) {
|
|
654
|
+
const textBefore = content.slice(lastIndex, match.index);
|
|
655
|
+
if (textBefore.trim()) {
|
|
656
|
+
children.push(...parseInlineContent(textBefore));
|
|
547
657
|
}
|
|
548
658
|
}
|
|
549
|
-
|
|
659
|
+
children.push({
|
|
550
660
|
type: "link",
|
|
551
|
-
url,
|
|
552
|
-
children:
|
|
661
|
+
url: href,
|
|
662
|
+
children: parseInlineContent(linkText)
|
|
553
663
|
});
|
|
554
|
-
lastIndex =
|
|
664
|
+
lastIndex = match.index + fullMatch.length;
|
|
555
665
|
}
|
|
556
|
-
if (lastIndex <
|
|
557
|
-
const
|
|
558
|
-
if (
|
|
559
|
-
|
|
666
|
+
if (lastIndex < content.length) {
|
|
667
|
+
const remainingText = content.slice(lastIndex);
|
|
668
|
+
if (remainingText.trim()) {
|
|
669
|
+
children.push(...parseInlineContent(remainingText));
|
|
560
670
|
}
|
|
561
671
|
}
|
|
562
|
-
return
|
|
672
|
+
return children;
|
|
563
673
|
}
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
const afterText = text.substring(match.index + fullMatch.length);
|
|
570
|
-
const elements = [];
|
|
571
|
-
if (beforeText) {
|
|
572
|
-
elements.push(...parseInlineElements(beforeText));
|
|
573
|
-
}
|
|
574
|
-
const nestedElements = parseInlineElements(content);
|
|
575
|
-
nestedElements.forEach((element) => {
|
|
576
|
-
if (tag === "strong") element.bold = true;
|
|
577
|
-
else if (tag === "em") element.italic = true;
|
|
578
|
-
else if (tag === "u") element.underline = true;
|
|
579
|
-
else if (tag === "del") element.strikethrough = true;
|
|
580
|
-
});
|
|
581
|
-
elements.push(...nestedElements);
|
|
582
|
-
if (afterText) {
|
|
583
|
-
elements.push(...parseInlineElements(afterText));
|
|
584
|
-
}
|
|
585
|
-
return elements;
|
|
674
|
+
function parseParagraph(content) {
|
|
675
|
+
return {
|
|
676
|
+
type: "paragraph",
|
|
677
|
+
children: parseListContent(content)
|
|
678
|
+
};
|
|
586
679
|
}
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
type: "heading",
|
|
593
|
-
level,
|
|
594
|
-
children: [{ type: "text", text: innerText.trim() }]
|
|
595
|
-
};
|
|
596
|
-
}
|
|
597
|
-
function parseParagraph(innerText) {
|
|
598
|
-
return {
|
|
599
|
-
type: "paragraph",
|
|
600
|
-
children: parseInlineElements(innerText)
|
|
601
|
-
};
|
|
602
|
-
}
|
|
603
|
-
function parseList(tag, innerText) {
|
|
604
|
-
const listType = tag === "ul" ? "unordered" : "ordered";
|
|
605
|
-
const listItems = [];
|
|
606
|
-
const listItemRegex = /<li>(.*?)<\/li>/g;
|
|
607
|
-
let itemMatch;
|
|
608
|
-
while ((itemMatch = listItemRegex.exec(innerText)) !== null) {
|
|
609
|
-
listItems.push({
|
|
610
|
-
type: "list-item",
|
|
611
|
-
children: parseInlineElements(itemMatch[1])
|
|
612
|
-
});
|
|
680
|
+
const blocks = [];
|
|
681
|
+
const elements = parseHTML(html);
|
|
682
|
+
if (elements.length === 0 && html.trim()) {
|
|
683
|
+
blocks.push(parseParagraph(html));
|
|
684
|
+
return blocks;
|
|
613
685
|
}
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
format: listType,
|
|
617
|
-
children: listItems
|
|
618
|
-
};
|
|
619
|
-
}
|
|
620
|
-
function htmlToJson(htmlData) {
|
|
621
|
-
const jsonData = [];
|
|
622
|
-
const blockRegex = /<(h[1-3]|p|ul|ol)(?:[^>]*?)>([\s\S]*?)<\/\1>/g;
|
|
623
|
-
let match;
|
|
624
|
-
while ((match = blockRegex.exec(htmlData)) !== null) {
|
|
625
|
-
const [, tag, content] = match;
|
|
626
|
-
switch (tag) {
|
|
686
|
+
for (const element of elements) {
|
|
687
|
+
switch (element.tag.toLowerCase()) {
|
|
627
688
|
case "h1":
|
|
628
689
|
case "h2":
|
|
629
690
|
case "h3":
|
|
630
|
-
|
|
691
|
+
case "h4":
|
|
692
|
+
case "h5":
|
|
693
|
+
case "h6":
|
|
694
|
+
blocks.push({
|
|
695
|
+
type: "heading",
|
|
696
|
+
level: parseInt(element.tag.slice(1)),
|
|
697
|
+
children: parseListContent(element.content)
|
|
698
|
+
});
|
|
631
699
|
break;
|
|
632
700
|
case "p":
|
|
633
|
-
|
|
634
|
-
const linkRegex = /<a\s+href="([^"]+)"[^>]*>([\s\S]*?)<\/a>/g;
|
|
635
|
-
let linkMatch;
|
|
636
|
-
let lastIndex = 0;
|
|
637
|
-
const children = [];
|
|
638
|
-
children.push({ type: "text", text: "" });
|
|
639
|
-
while ((linkMatch = linkRegex.exec(content)) !== null) {
|
|
640
|
-
const [fullMatch, url, linkText] = linkMatch;
|
|
641
|
-
if (linkMatch.index > lastIndex) {
|
|
642
|
-
const beforeLinkText = content.substring(lastIndex, linkMatch.index);
|
|
643
|
-
if (beforeLinkText) {
|
|
644
|
-
children.push({ type: "text", text: beforeLinkText });
|
|
645
|
-
}
|
|
646
|
-
}
|
|
647
|
-
children.push({
|
|
648
|
-
type: "link",
|
|
649
|
-
url,
|
|
650
|
-
children: [{ type: "text", text: linkText }]
|
|
651
|
-
});
|
|
652
|
-
lastIndex = linkMatch.index + fullMatch.length;
|
|
653
|
-
}
|
|
654
|
-
const afterLastLink = content.substring(lastIndex);
|
|
655
|
-
if (afterLastLink) {
|
|
656
|
-
children.push({ type: "text", text: afterLastLink });
|
|
657
|
-
} else {
|
|
658
|
-
children.push({ type: "text", text: "" });
|
|
659
|
-
}
|
|
660
|
-
jsonData.push({
|
|
661
|
-
type: "paragraph",
|
|
662
|
-
children
|
|
663
|
-
});
|
|
664
|
-
} else {
|
|
665
|
-
jsonData.push(parseParagraph(content));
|
|
666
|
-
}
|
|
701
|
+
blocks.push(parseParagraph(element.content));
|
|
667
702
|
break;
|
|
668
703
|
case "ul":
|
|
704
|
+
blocks.push(parseList(element.content, "unordered"));
|
|
705
|
+
break;
|
|
669
706
|
case "ol":
|
|
670
|
-
|
|
707
|
+
blocks.push(parseList(element.content, "ordered"));
|
|
671
708
|
break;
|
|
709
|
+
case "blockquote":
|
|
710
|
+
blocks.push({
|
|
711
|
+
type: "quote",
|
|
712
|
+
children: [parseParagraph(element.content)]
|
|
713
|
+
});
|
|
714
|
+
break;
|
|
715
|
+
case "pre":
|
|
716
|
+
if (element.content.includes("<code>")) {
|
|
717
|
+
blocks.push({
|
|
718
|
+
type: "code",
|
|
719
|
+
children: parseInlineContent(element.content)
|
|
720
|
+
});
|
|
721
|
+
}
|
|
722
|
+
break;
|
|
723
|
+
default:
|
|
724
|
+
blocks.push(parseParagraph(element.content));
|
|
672
725
|
}
|
|
673
726
|
}
|
|
674
|
-
return
|
|
727
|
+
return blocks;
|
|
675
728
|
}
|
|
676
729
|
async function updateEntry(contentTypeID, entryID, sourceLocale, targetLocale, data, attributes) {
|
|
677
730
|
if (!entryID) {
|
|
@@ -683,6 +736,14 @@ async function updateEntry(contentTypeID, entryID, sourceLocale, targetLocale, d
|
|
|
683
736
|
locale: sourceLocale
|
|
684
737
|
});
|
|
685
738
|
const processedData = processDataRecursively(data);
|
|
739
|
+
for (const [key, value] of Object.entries(processedData)) {
|
|
740
|
+
if (attributes[key]?.type === "blocks" && typeof value === "string") {
|
|
741
|
+
console.warn(
|
|
742
|
+
`Field ${key} is a blocks field but received string value. Converting to blocks format.`
|
|
743
|
+
);
|
|
744
|
+
processedData[key] = htmlToJson(value);
|
|
745
|
+
}
|
|
746
|
+
}
|
|
686
747
|
const localizedData = {};
|
|
687
748
|
for (const field in processedData) {
|
|
688
749
|
if (attributes[field] && (!attributes[field].pluginOptions?.i18n || attributes[field].pluginOptions?.i18n?.localized !== false)) {
|
|
@@ -701,23 +762,29 @@ async function updateEntry(contentTypeID, entryID, sourceLocale, targetLocale, d
|
|
|
701
762
|
});
|
|
702
763
|
}
|
|
703
764
|
}
|
|
704
|
-
function processDataRecursively(data) {
|
|
765
|
+
function processDataRecursively(data, schema) {
|
|
705
766
|
if (!data || typeof data !== "object") {
|
|
706
767
|
return data;
|
|
707
768
|
}
|
|
708
769
|
if (Array.isArray(data)) {
|
|
770
|
+
if (data[0]?.fields) {
|
|
771
|
+
const processedFields = {};
|
|
772
|
+
for (const fieldData of data[0].fields) {
|
|
773
|
+
if (fieldData.realType === "blocks") {
|
|
774
|
+
if (fieldData.translatableValue?.[0]) {
|
|
775
|
+
processedFields[fieldData.field] = htmlToJson(fieldData.translatableValue[0]);
|
|
776
|
+
}
|
|
777
|
+
} else {
|
|
778
|
+
processedFields[fieldData.field] = fieldData.translatableValue?.[0] || null;
|
|
779
|
+
}
|
|
780
|
+
}
|
|
781
|
+
return processedFields;
|
|
782
|
+
}
|
|
709
783
|
return data.map((item) => processDataRecursively(item));
|
|
710
784
|
}
|
|
711
785
|
const result = {};
|
|
712
786
|
for (const key in data) {
|
|
713
|
-
|
|
714
|
-
if (typeof value === "string" && (key.includes("Blocks") || key.includes("RTBlocks") || key === "blocks")) {
|
|
715
|
-
result[key] = htmlToJson(value);
|
|
716
|
-
} else if (value && typeof value === "object") {
|
|
717
|
-
result[key] = processDataRecursively(value);
|
|
718
|
-
} else {
|
|
719
|
-
result[key] = value;
|
|
720
|
-
}
|
|
787
|
+
result[key] = processDataRecursively(data[key]);
|
|
721
788
|
}
|
|
722
789
|
return result;
|
|
723
790
|
}
|
|
@@ -762,16 +829,15 @@ function processRepeatableComponents(fields, existingEntry, rootPath) {
|
|
|
762
829
|
}
|
|
763
830
|
const componentId = field.componentInfo.id;
|
|
764
831
|
if (!componentsById.has(componentId)) {
|
|
765
|
-
const existingComponent = existingComponents.find(
|
|
766
|
-
|
|
767
|
-
);
|
|
768
|
-
componentsById.set(
|
|
769
|
-
componentId,
|
|
770
|
-
existingComponent ? { ...existingComponent } : {}
|
|
771
|
-
);
|
|
832
|
+
const existingComponent = existingComponents.find((c) => c.id === componentId);
|
|
833
|
+
componentsById.set(componentId, existingComponent ? { ...existingComponent } : {});
|
|
772
834
|
}
|
|
773
835
|
const component = componentsById.get(componentId);
|
|
774
|
-
|
|
836
|
+
if (field.realType === "blocks") {
|
|
837
|
+
component[field.field] = htmlToJson(field.translatableValue[0] || "");
|
|
838
|
+
} else {
|
|
839
|
+
component[field.field] = field.translatableValue[0];
|
|
840
|
+
}
|
|
775
841
|
});
|
|
776
842
|
return Array.from(componentsById.values()).map((comp) => {
|
|
777
843
|
if (!existingComponents.find((ec) => ec.id === comp.id)) {
|
|
@@ -793,7 +859,11 @@ function processNestedComponents(fields, pathParts, existingEntry, acc) {
|
|
|
793
859
|
}
|
|
794
860
|
if (index2 === pathParts.length - 1) {
|
|
795
861
|
fields.forEach((field) => {
|
|
796
|
-
|
|
862
|
+
if (field.realType === "blocks") {
|
|
863
|
+
current[part][field.field] = htmlToJson(field.translatableValue[0] || "");
|
|
864
|
+
} else {
|
|
865
|
+
current[part][field.field] = field.translatableValue[0];
|
|
866
|
+
}
|
|
797
867
|
});
|
|
798
868
|
} else {
|
|
799
869
|
current = current[part];
|
|
@@ -808,11 +878,7 @@ function processComponentFields(componentFieldsMap, acc, existingEntry, targetSc
|
|
|
808
878
|
const rootPath = pathParts[0];
|
|
809
879
|
const schema = targetSchema.attributes?.[rootPath];
|
|
810
880
|
if (schema?.repeatable) {
|
|
811
|
-
acc[rootPath] = processRepeatableComponents(
|
|
812
|
-
fields,
|
|
813
|
-
existingEntry,
|
|
814
|
-
rootPath
|
|
815
|
-
);
|
|
881
|
+
acc[rootPath] = processRepeatableComponents(fields, existingEntry, rootPath);
|
|
816
882
|
} else {
|
|
817
883
|
processNestedComponents(fields, pathParts, existingEntry, acc);
|
|
818
884
|
}
|
|
@@ -930,12 +996,9 @@ const service = ({ strapi: strapi2 }) => {
|
|
|
930
996
|
},
|
|
931
997
|
async getLanguageOptions() {
|
|
932
998
|
const { license } = await this.getLicense();
|
|
933
|
-
const response = await fetch(
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
headers: { Authorization: `${license}` }
|
|
937
|
-
}
|
|
938
|
-
);
|
|
999
|
+
const response = await fetch(TRANSLATIONTUDIO_URL + "/mappings", {
|
|
1000
|
+
headers: { Authorization: `${license}` }
|
|
1001
|
+
});
|
|
939
1002
|
const responseData = await response.json();
|
|
940
1003
|
return responseData;
|
|
941
1004
|
},
|
|
@@ -943,10 +1006,7 @@ const service = ({ strapi: strapi2 }) => {
|
|
|
943
1006
|
const { contentTypeID, entryID, locale } = parsePayload(payload);
|
|
944
1007
|
const contentType = await getContentType(contentTypeID);
|
|
945
1008
|
const entry = await getEntry(contentTypeID, entryID, locale);
|
|
946
|
-
const contentFields = await processEntryFields(
|
|
947
|
-
entry,
|
|
948
|
-
contentType.attributes
|
|
949
|
-
);
|
|
1009
|
+
const contentFields = await processEntryFields(entry, contentType.attributes);
|
|
950
1010
|
return transformResponse(contentFields);
|
|
951
1011
|
},
|
|
952
1012
|
async importData(payload) {
|
|
@@ -954,17 +1014,9 @@ const service = ({ strapi: strapi2 }) => {
|
|
|
954
1014
|
const sourceLocale = payload.source;
|
|
955
1015
|
const targetLocale = payload.target;
|
|
956
1016
|
try {
|
|
957
|
-
const existingEntry = await getEntry(
|
|
958
|
-
contentTypeID,
|
|
959
|
-
entryID,
|
|
960
|
-
targetLocale
|
|
961
|
-
);
|
|
1017
|
+
const existingEntry = await getEntry(contentTypeID, entryID, targetLocale);
|
|
962
1018
|
const targetSchema = await getContentType(contentTypeID);
|
|
963
|
-
const data = prepareImportData(
|
|
964
|
-
payload.document[0].fields,
|
|
965
|
-
existingEntry,
|
|
966
|
-
targetSchema
|
|
967
|
-
);
|
|
1019
|
+
const data = prepareImportData(payload.document[0].fields, existingEntry, targetSchema);
|
|
968
1020
|
if (targetSchema.pluginOptions.i18n.localized === true) {
|
|
969
1021
|
await updateEntry(
|
|
970
1022
|
contentTypeID,
|
|
@@ -982,17 +1034,14 @@ const service = ({ strapi: strapi2 }) => {
|
|
|
982
1034
|
},
|
|
983
1035
|
async requestTranslation(payload) {
|
|
984
1036
|
const { license } = await this.getLicense();
|
|
985
|
-
const response = await fetch(
|
|
986
|
-
|
|
987
|
-
{
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
body: JSON.stringify(payload)
|
|
994
|
-
}
|
|
995
|
-
);
|
|
1037
|
+
const response = await fetch(TRANSLATIONTUDIO_URL + "/translate", {
|
|
1038
|
+
method: "POST",
|
|
1039
|
+
headers: {
|
|
1040
|
+
Authorization: `${license}`,
|
|
1041
|
+
"Content-Type": "application/json"
|
|
1042
|
+
},
|
|
1043
|
+
body: JSON.stringify(payload)
|
|
1044
|
+
});
|
|
996
1045
|
if (response.status === 204) return true;
|
|
997
1046
|
},
|
|
998
1047
|
async getEmail(ctx) {
|