@translationstudio/translationstudio-strapi-extension 1.1.0 → 1.1.3

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.
@@ -81,6 +81,27 @@ const controller = ({ strapi: strapi2 }) => ({
81
81
  ctx.status = 200;
82
82
  ctx.body = [{ fields: result }];
83
83
  },
84
+ async setDevelopmentUrl(ctx) {
85
+ const url = ctx.request.body.url;
86
+ const result = await strapi2.plugin(APP_NAME$1).service("service").setDevelopmentUrl(url);
87
+ if (result) {
88
+ ctx.status = 200;
89
+ ctx.body = { success: true };
90
+ } else {
91
+ ctx.status = 500;
92
+ ctx.body = { success: false };
93
+ }
94
+ },
95
+ async getDevelopmentUrl(ctx) {
96
+ const url = await strapi2.plugin(APP_NAME$1).service("service").getDevelopmentUrl();
97
+ if (url) {
98
+ ctx.status = 200;
99
+ ctx.body = { url };
100
+ } else {
101
+ ctx.status = 404;
102
+ ctx.body = { url: "" };
103
+ }
104
+ },
84
105
  async importData(ctx) {
85
106
  if (!await this.validateToken(ctx)) {
86
107
  ctx.status = 400;
@@ -144,6 +165,22 @@ const routes = [
144
165
  policies: []
145
166
  }
146
167
  },
168
+ {
169
+ method: "GET",
170
+ path: "/devurl",
171
+ handler: "controller.getDevelopmentUrl",
172
+ config: {
173
+ policies: []
174
+ }
175
+ },
176
+ {
177
+ method: "POST",
178
+ path: "/devurl",
179
+ handler: "controller.setDevelopmentUrl",
180
+ config: {
181
+ policies: []
182
+ }
183
+ },
147
184
  {
148
185
  method: "GET",
149
186
  path: "/getToken",
@@ -289,49 +326,54 @@ const getEntry = async (contentTypeID, entryID, locale) => {
289
326
  const transformResponse = (data) => data.map(
290
327
  (item) => item.realType === "blocks" && Array.isArray(item.translatableValue[0]) ? { ...item, translatableValue: item.translatableValue[0] } : item
291
328
  );
329
+ function jsonToHtml(json) {
330
+ if (!json || !Array.isArray(json)) {
331
+ return "";
332
+ }
333
+ return json.map((node) => processNode(node)).join("");
334
+ }
335
+ function processNode(node) {
336
+ if (!node) return "";
337
+ switch (node.type) {
338
+ case "paragraph":
339
+ return `<p>${node.children.map(processNode).join("")}</p>`;
340
+ case "heading":
341
+ const level = node.level || 1;
342
+ return `<h${level}>${node.children.map(processNode).join("")}</h${level}>`;
343
+ case "link":
344
+ const url = node.url || "#";
345
+ return `<a href="${url}">${node.children.map(processNode).join("")}</a>`;
346
+ case "list":
347
+ const listType = node.format === "ordered" ? "ol" : "ul";
348
+ return `<${listType}>${node.children.map(processNode).join("")}</${listType}>`;
349
+ case "list-item":
350
+ return `<li>${node.children.map(processNode).join("")}</li>`;
351
+ case "quote":
352
+ return `<blockquote>${node.children.map(processNode).join("")}</blockquote>`;
353
+ case "code":
354
+ return `<pre><code>${node.children.map((child) => child.text).join("")}</code></pre>`;
355
+ case "image":
356
+ return `<img src="${node.url}" alt="${node.alt || ""}" />`;
357
+ case "text":
358
+ return formatText(node);
359
+ default:
360
+ return node.children && Array.isArray(node.children) ? node.children.map(processNode).join("") : node.text || "";
361
+ }
362
+ }
292
363
  function formatText(child) {
293
364
  if (child.type === "link") {
294
- return `<a href="${child.url}">${child.children.map((sub) => sub.text).join("")}</a>`;
365
+ return `<a href="${child.url}">${child.children.map((sub) => formatText(sub)).join("")}</a>`;
295
366
  }
296
367
  let text = child.text || "";
368
+ if (child.code) text = `<code>${text}</code>`;
297
369
  if (child.bold) text = `<strong>${text}</strong>`;
298
370
  if (child.italic) text = `<em>${text}</em>`;
299
371
  if (child.underline) text = `<u>${text}</u>`;
300
- if (child.strikethrough) text = `<del>${text}</del>`;
372
+ if (child.strikethrough) {
373
+ text = `~~${text}~~`;
374
+ }
301
375
  return text;
302
376
  }
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
377
  const processComponent = async (fieldName, componentName, value, schemaName, componentId) => {
336
378
  const contentFields = [];
337
379
  const componentSchema = await strapi.components[componentName];
@@ -529,149 +571,197 @@ const isDynamicZone = (fieldSchema, value, schema) => {
529
571
  const isComponent = (fieldSchema, value, schema) => {
530
572
  return fieldSchema.type === "component" && isFieldLocalizable(fieldSchema, schema);
531
573
  };
532
- function parseInlineElements(text) {
533
- if (!text.includes("<")) {
534
- return [{ type: "text", text }];
574
+ function htmlToJson(html) {
575
+ function parseHTML(html2) {
576
+ const elements2 = [];
577
+ const tagRegex = /<([a-z0-9]+)((?:\s+[a-z-]+="[^"]*")*)\s*>([\s\S]*?)<\/\1>/gi;
578
+ let match;
579
+ while ((match = tagRegex.exec(html2)) !== null) {
580
+ const [, tag, attributes, content] = match;
581
+ const attrs = {};
582
+ const attrRegex = /([a-z-]+)="([^"]*)"/gi;
583
+ let attrMatch;
584
+ while ((attrMatch = attrRegex.exec(attributes)) !== null) {
585
+ attrs[attrMatch[1]] = attrMatch[2];
586
+ }
587
+ elements2.push({ tag, attrs, content });
588
+ }
589
+ return elements2;
535
590
  }
536
- const linkRegex = /<a\s+href="([^"]+)"[^>]*>([\s\S]*?)<\/a>/g;
537
- if (text.includes("<a ")) {
538
- let linkMatch;
591
+ function parseInlineContent(content) {
592
+ const segments = [];
593
+ let currentText = "";
594
+ let formatStack = [];
595
+ let currentFormat = {
596
+ bold: false,
597
+ italic: false,
598
+ underline: false,
599
+ code: false,
600
+ strikethrough: false
601
+ };
602
+ const pushSegment = () => {
603
+ if (currentText) {
604
+ segments.push({
605
+ type: "text",
606
+ text: currentText,
607
+ ...Object.fromEntries(Object.entries(currentFormat).filter(([_, value]) => value))
608
+ });
609
+ currentText = "";
610
+ }
611
+ };
612
+ const tags = content.split(/(<[^>]+>|~~)/);
613
+ for (const tag of tags) {
614
+ if (!tag) continue;
615
+ if (tag === "~~") {
616
+ pushSegment();
617
+ currentFormat.strikethrough = !currentFormat.strikethrough;
618
+ continue;
619
+ }
620
+ if (tag.startsWith("<")) {
621
+ pushSegment();
622
+ if (tag.startsWith("</")) {
623
+ const tagName = tag.slice(2, -1).toLowerCase();
624
+ const lastTag = formatStack.pop();
625
+ if (lastTag && lastTag.type === tagName) {
626
+ switch (tagName) {
627
+ case "strong":
628
+ currentFormat.bold = false;
629
+ break;
630
+ case "em":
631
+ currentFormat.italic = false;
632
+ break;
633
+ case "u":
634
+ currentFormat.underline = false;
635
+ break;
636
+ case "code":
637
+ currentFormat.code = false;
638
+ break;
639
+ case "del":
640
+ currentFormat.strikethrough = false;
641
+ break;
642
+ }
643
+ }
644
+ } else {
645
+ const tagName = tag.slice(1, -1).toLowerCase();
646
+ formatStack.push({ type: tagName, index: segments.length });
647
+ switch (tagName) {
648
+ case "strong":
649
+ currentFormat.bold = true;
650
+ break;
651
+ case "em":
652
+ currentFormat.italic = true;
653
+ break;
654
+ case "u":
655
+ currentFormat.underline = true;
656
+ break;
657
+ case "code":
658
+ currentFormat.code = true;
659
+ break;
660
+ case "del":
661
+ currentFormat.strikethrough = true;
662
+ break;
663
+ }
664
+ }
665
+ } else {
666
+ currentText += tag;
667
+ }
668
+ }
669
+ pushSegment();
670
+ return segments.filter((segment) => segment.text.length > 0);
671
+ }
672
+ function parseList(html2, format) {
673
+ const listItems = html2.match(/<li>([\s\S]*?)<\/li>/g) || [];
674
+ return {
675
+ type: "list",
676
+ format,
677
+ children: listItems.map((item) => ({
678
+ type: "list-item",
679
+ children: parseListContent(item.replace(/<li>|<\/li>/g, ""))
680
+ }))
681
+ };
682
+ }
683
+ function parseListContent(content) {
684
+ const children = [];
685
+ const linkRegex = /<a\s+href="([^"]+)">([\s\S]*?)<\/a>/g;
539
686
  let lastIndex = 0;
540
- const elements = [];
541
- while ((linkMatch = linkRegex.exec(text)) !== null) {
542
- const [fullMatch, url, linkContent] = linkMatch;
543
- if (linkMatch.index > lastIndex) {
544
- const beforeText = text.substring(lastIndex, linkMatch.index);
545
- if (beforeText) {
546
- elements.push(...parseInlineElements(beforeText));
687
+ let match;
688
+ while ((match = linkRegex.exec(content)) !== null) {
689
+ const [fullMatch, href, linkText] = match;
690
+ if (match.index > lastIndex) {
691
+ const textBefore = content.slice(lastIndex, match.index);
692
+ if (textBefore.trim()) {
693
+ children.push(...parseInlineContent(textBefore));
547
694
  }
548
695
  }
549
- elements.push({
696
+ children.push({
550
697
  type: "link",
551
- url,
552
- children: parseInlineElements(linkContent)
698
+ url: href,
699
+ children: parseInlineContent(linkText)
553
700
  });
554
- lastIndex = linkMatch.index + fullMatch.length;
701
+ lastIndex = match.index + fullMatch.length;
555
702
  }
556
- if (lastIndex < text.length) {
557
- const afterText = text.substring(lastIndex);
558
- if (afterText) {
559
- elements.push(...parseInlineElements(afterText));
703
+ if (lastIndex < content.length) {
704
+ const remainingText = content.slice(lastIndex);
705
+ if (remainingText.trim()) {
706
+ children.push(...parseInlineContent(remainingText));
560
707
  }
561
708
  }
562
- return elements;
709
+ return children;
563
710
  }
564
- const formatRegex = /<(strong|em|u|del)>([\s\S]*?)<\/\1>/;
565
- const match = formatRegex.exec(text);
566
- if (match) {
567
- const [fullMatch, tag, content] = match;
568
- const beforeText = text.substring(0, match.index);
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;
711
+ function parseParagraph(content) {
712
+ return {
713
+ type: "paragraph",
714
+ children: parseListContent(content)
715
+ };
586
716
  }
587
- return [{ type: "text", text }];
588
- }
589
- function parseHeading(tag, innerText) {
590
- const level = parseInt(tag[1]);
591
- return {
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
- });
717
+ const blocks = [];
718
+ const elements = parseHTML(html);
719
+ if (elements.length === 0 && html.trim()) {
720
+ blocks.push(parseParagraph(html));
721
+ return blocks;
613
722
  }
614
- return {
615
- type: "list",
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) {
723
+ for (const element of elements) {
724
+ switch (element.tag.toLowerCase()) {
627
725
  case "h1":
628
726
  case "h2":
629
727
  case "h3":
630
- jsonData.push(parseHeading(tag, content));
728
+ case "h4":
729
+ case "h5":
730
+ case "h6":
731
+ blocks.push({
732
+ type: "heading",
733
+ level: parseInt(element.tag.slice(1)),
734
+ children: parseListContent(element.content)
735
+ });
631
736
  break;
632
737
  case "p":
633
- if (content.includes("<a ")) {
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
- }
738
+ blocks.push(parseParagraph(element.content));
667
739
  break;
668
740
  case "ul":
741
+ blocks.push(parseList(element.content, "unordered"));
742
+ break;
669
743
  case "ol":
670
- jsonData.push(parseList(tag, content));
744
+ blocks.push(parseList(element.content, "ordered"));
745
+ break;
746
+ case "blockquote":
747
+ blocks.push({
748
+ type: "quote",
749
+ children: [parseParagraph(element.content)]
750
+ });
671
751
  break;
752
+ case "pre":
753
+ if (element.content.includes("<code>")) {
754
+ blocks.push({
755
+ type: "code",
756
+ children: parseInlineContent(element.content)
757
+ });
758
+ }
759
+ break;
760
+ default:
761
+ blocks.push(parseParagraph(element.content));
672
762
  }
673
763
  }
674
- return jsonData;
764
+ return blocks;
675
765
  }
676
766
  async function updateEntry(contentTypeID, entryID, sourceLocale, targetLocale, data, attributes) {
677
767
  if (!entryID) {
@@ -683,6 +773,14 @@ async function updateEntry(contentTypeID, entryID, sourceLocale, targetLocale, d
683
773
  locale: sourceLocale
684
774
  });
685
775
  const processedData = processDataRecursively(data);
776
+ for (const [key, value] of Object.entries(processedData)) {
777
+ if (attributes[key]?.type === "blocks" && typeof value === "string") {
778
+ console.warn(
779
+ `Field ${key} is a blocks field but received string value. Converting to blocks format.`
780
+ );
781
+ processedData[key] = htmlToJson(value);
782
+ }
783
+ }
686
784
  const localizedData = {};
687
785
  for (const field in processedData) {
688
786
  if (attributes[field] && (!attributes[field].pluginOptions?.i18n || attributes[field].pluginOptions?.i18n?.localized !== false)) {
@@ -701,23 +799,29 @@ async function updateEntry(contentTypeID, entryID, sourceLocale, targetLocale, d
701
799
  });
702
800
  }
703
801
  }
704
- function processDataRecursively(data) {
802
+ function processDataRecursively(data, schema) {
705
803
  if (!data || typeof data !== "object") {
706
804
  return data;
707
805
  }
708
806
  if (Array.isArray(data)) {
807
+ if (data[0]?.fields) {
808
+ const processedFields = {};
809
+ for (const fieldData of data[0].fields) {
810
+ if (fieldData.realType === "blocks") {
811
+ if (fieldData.translatableValue?.[0]) {
812
+ processedFields[fieldData.field] = htmlToJson(fieldData.translatableValue[0]);
813
+ }
814
+ } else {
815
+ processedFields[fieldData.field] = fieldData.translatableValue?.[0] || null;
816
+ }
817
+ }
818
+ return processedFields;
819
+ }
709
820
  return data.map((item) => processDataRecursively(item));
710
821
  }
711
822
  const result = {};
712
823
  for (const key in data) {
713
- const value = data[key];
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
- }
824
+ result[key] = processDataRecursively(data[key]);
721
825
  }
722
826
  return result;
723
827
  }
@@ -762,16 +866,15 @@ function processRepeatableComponents(fields, existingEntry, rootPath) {
762
866
  }
763
867
  const componentId = field.componentInfo.id;
764
868
  if (!componentsById.has(componentId)) {
765
- const existingComponent = existingComponents.find(
766
- (c) => c.id === componentId
767
- );
768
- componentsById.set(
769
- componentId,
770
- existingComponent ? { ...existingComponent } : {}
771
- );
869
+ const existingComponent = existingComponents.find((c) => c.id === componentId);
870
+ componentsById.set(componentId, existingComponent ? { ...existingComponent } : {});
772
871
  }
773
872
  const component = componentsById.get(componentId);
774
- component[field.field] = field.translatableValue[0];
873
+ if (field.realType === "blocks") {
874
+ component[field.field] = htmlToJson(field.translatableValue[0] || "");
875
+ } else {
876
+ component[field.field] = field.translatableValue[0];
877
+ }
775
878
  });
776
879
  return Array.from(componentsById.values()).map((comp) => {
777
880
  if (!existingComponents.find((ec) => ec.id === comp.id)) {
@@ -793,7 +896,11 @@ function processNestedComponents(fields, pathParts, existingEntry, acc) {
793
896
  }
794
897
  if (index2 === pathParts.length - 1) {
795
898
  fields.forEach((field) => {
796
- current[part][field.field] = field.translatableValue[0];
899
+ if (field.realType === "blocks") {
900
+ current[part][field.field] = htmlToJson(field.translatableValue[0] || "");
901
+ } else {
902
+ current[part][field.field] = field.translatableValue[0];
903
+ }
797
904
  });
798
905
  } else {
799
906
  current = current[part];
@@ -808,11 +915,7 @@ function processComponentFields(componentFieldsMap, acc, existingEntry, targetSc
808
915
  const rootPath = pathParts[0];
809
916
  const schema = targetSchema.attributes?.[rootPath];
810
917
  if (schema?.repeatable) {
811
- acc[rootPath] = processRepeatableComponents(
812
- fields,
813
- existingEntry,
814
- rootPath
815
- );
918
+ acc[rootPath] = processRepeatableComponents(fields, existingEntry, rootPath);
816
919
  } else {
817
920
  processNestedComponents(fields, pathParts, existingEntry, acc);
818
921
  }
@@ -877,9 +980,9 @@ function prepareImportData(translatables, existingEntry, targetSchema) {
877
980
  return withDynamicZones;
878
981
  }, {});
879
982
  }
880
- const jwt = require("jsonwebtoken");
983
+ require("jsonwebtoken");
881
984
  const crypto = require("crypto");
882
- const TRANSLATIONTUDIO_URL = "https://cms-strapi-service-7866fdd79eab.herokuapp.com";
985
+ const TRANSLATIONTUDIO_URL = "https://strapi.translationstudio.tech";
883
986
  const APP_NAME = "translationstudio";
884
987
  const service = ({ strapi: strapi2 }) => {
885
988
  const pluginStore = strapi2.store({
@@ -892,6 +995,16 @@ const service = ({ strapi: strapi2 }) => {
892
995
  const result = await pluginStore.get({ key: "license" });
893
996
  return { license: result };
894
997
  },
998
+ async getTranslationstudioUrl() {
999
+ try {
1000
+ const result = await pluginStore.get({ key: "developurl" });
1001
+ if (typeof result === "string" && result !== "")
1002
+ return result;
1003
+ } catch (err) {
1004
+ console.warn(err);
1005
+ }
1006
+ return TRANSLATIONTUDIO_URL;
1007
+ },
895
1008
  async setLicense(license) {
896
1009
  try {
897
1010
  await pluginStore.set({
@@ -903,6 +1016,26 @@ const service = ({ strapi: strapi2 }) => {
903
1016
  return { success: false };
904
1017
  }
905
1018
  },
1019
+ async setDevelopmentUrl(url) {
1020
+ try {
1021
+ await pluginStore.set({
1022
+ key: "developurl",
1023
+ value: url
1024
+ });
1025
+ return true;
1026
+ } catch (error) {
1027
+ return false;
1028
+ }
1029
+ },
1030
+ async getDevelopmentUrl() {
1031
+ try {
1032
+ const result = await pluginStore.get({ key: "developurl" });
1033
+ if (typeof result === "string")
1034
+ return result;
1035
+ } catch (error) {
1036
+ }
1037
+ return "";
1038
+ },
906
1039
  // Access Token
907
1040
  async getToken() {
908
1041
  try {
@@ -914,28 +1047,18 @@ const service = ({ strapi: strapi2 }) => {
914
1047
  },
915
1048
  async generateToken() {
916
1049
  const secretKey = crypto.randomBytes(64).toString("hex");
917
- const token = jwt.sign(
918
- {
919
- app: APP_NAME,
920
- iat: Math.floor(Date.now() / 1e3)
921
- },
922
- secretKey,
923
- { expiresIn: "10y" }
924
- );
925
1050
  await pluginStore.set({
926
1051
  key: "token",
927
- value: token
1052
+ value: secretKey
928
1053
  });
929
- return { token };
1054
+ return { token: secretKey };
930
1055
  },
931
1056
  async getLanguageOptions() {
932
1057
  const { license } = await this.getLicense();
933
- const response = await fetch(
934
- TRANSLATIONTUDIO_URL + "/mappings",
935
- {
936
- headers: { Authorization: `${license}` }
937
- }
938
- );
1058
+ const url = await this.getTranslationstudioUrl();
1059
+ const response = await fetch(url + "/mappings", {
1060
+ headers: { Authorization: `${license}` }
1061
+ });
939
1062
  const responseData = await response.json();
940
1063
  return responseData;
941
1064
  },
@@ -943,10 +1066,7 @@ const service = ({ strapi: strapi2 }) => {
943
1066
  const { contentTypeID, entryID, locale } = parsePayload(payload);
944
1067
  const contentType = await getContentType(contentTypeID);
945
1068
  const entry = await getEntry(contentTypeID, entryID, locale);
946
- const contentFields = await processEntryFields(
947
- entry,
948
- contentType.attributes
949
- );
1069
+ const contentFields = await processEntryFields(entry, contentType.attributes);
950
1070
  return transformResponse(contentFields);
951
1071
  },
952
1072
  async importData(payload) {
@@ -954,17 +1074,9 @@ const service = ({ strapi: strapi2 }) => {
954
1074
  const sourceLocale = payload.source;
955
1075
  const targetLocale = payload.target;
956
1076
  try {
957
- const existingEntry = await getEntry(
958
- contentTypeID,
959
- entryID,
960
- targetLocale
961
- );
1077
+ const existingEntry = await getEntry(contentTypeID, entryID, targetLocale);
962
1078
  const targetSchema = await getContentType(contentTypeID);
963
- const data = prepareImportData(
964
- payload.document[0].fields,
965
- existingEntry,
966
- targetSchema
967
- );
1079
+ const data = prepareImportData(payload.document[0].fields, existingEntry, targetSchema);
968
1080
  if (targetSchema.pluginOptions.i18n.localized === true) {
969
1081
  await updateEntry(
970
1082
  contentTypeID,
@@ -982,17 +1094,15 @@ const service = ({ strapi: strapi2 }) => {
982
1094
  },
983
1095
  async requestTranslation(payload) {
984
1096
  const { license } = await this.getLicense();
985
- const response = await fetch(
986
- TRANSLATIONTUDIO_URL + "/translate",
987
- {
988
- method: "POST",
989
- headers: {
990
- Authorization: `${license}`,
991
- "Content-Type": "application/json"
992
- },
993
- body: JSON.stringify(payload)
994
- }
995
- );
1097
+ const url = await this.getTranslationstudioUrl();
1098
+ const response = await fetch(url + "/translate", {
1099
+ method: "POST",
1100
+ headers: {
1101
+ Authorization: `${license}`,
1102
+ "Content-Type": "application/json"
1103
+ },
1104
+ body: JSON.stringify(payload)
1105
+ });
996
1106
  if (response.status === 204) return true;
997
1107
  },
998
1108
  async getEmail(ctx) {