@localazy/strapi-plugin 0.1.5 → 0.1.8

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/README.md CHANGED
@@ -1,4 +1,4 @@
1
- ### The Official Strapi Localization Plugin by Localazy
1
+ ## The Official Strapi Localization Plugin by Localazy
2
2
 
3
3
  Strapi localization doesn't have to be a headache! Install the Strapi localization plugin and seamlessly translate your content into multiple languages with [Localazy](https://localazy.com).
4
4
 
@@ -9,15 +9,17 @@ Strapi localization doesn't have to be a headache! Install the Strapi localizati
9
9
 
10
10
  Learn more in the [Strapi + Localazy tutorial](https://localazy.com/blog/how-to-strapi-localization-with-localazy#getting-started-with-strapi-localization).
11
11
 
12
- ### General information
13
-
14
- This repository contains all the code needed to run the Strapi Localization Plugin by Localazy.
12
+ ## Setup
15
13
 
16
14
  ### Install plugin via NPM
17
15
 
18
16
  The plugin is available on [NPM](https://www.npmjs.com/package/@localazy/strapi-plugin).
19
17
  You can also follow the installation commands located in your Strapi project Marketplace. This is the recommended approach.
20
18
 
19
+ ```
20
+ npm install @localazy/strapi-plugin
21
+ ```
22
+
21
23
  ### Use plugin in a clean project locally
22
24
 
23
25
  Besides installing the plugin via `npm`, you can also use it in a project locally. Assuming you have a (clean) Strapi project set up, do:
@@ -43,12 +45,10 @@ module.exports = {
43
45
 
44
46
  5. Run the project. The plugin will be available in the admin.
45
47
 
46
- ### Tests
48
+ ## Tests
47
49
 
48
50
  To run tests, run `npm run test` command. To watch tests, run `npm run test:watch` command.
49
51
 
50
- In case you have an access, you might also want to check the README file located in development project root for more information on tests debugging.
51
-
52
- ### Support
52
+ ## Support
53
53
  - If you encounter any issues or have questions, please contact us at [team@localazy.com](mailto:team@localazy.com).
54
54
  - Join the [Localazy Discord](https://discord.gg/CAVhHrh) to discuss all things localization.
@@ -0,0 +1,22 @@
1
+ import React from "react";
2
+ import { Flex } from '@strapi/design-system/Flex';
3
+ import { Loader } from "@strapi/design-system/Loader";
4
+ import { useTranslation } from "react-i18next";
5
+
6
+ import "../../../../i18n";
7
+
8
+ function PluginPageLoader() {
9
+ const { t } = useTranslation();
10
+
11
+ return (
12
+ <Flex
13
+ marginTop={10}
14
+ alignItems="center"
15
+ justifyContent="center"
16
+ >
17
+ <Loader>{t("common.loading_content")}</Loader>
18
+ </Flex>
19
+ )
20
+ }
21
+
22
+ export default PluginPageLoader;
@@ -0,0 +1,67 @@
1
+ import AnalyticsService from "../../../plugins/analytics-service";
2
+
3
+ export default class ProductAnalyticsService {
4
+ static async trackAppConnected(userId, project, params = {}) {
5
+ try {
6
+ const data = this.buildData(userId, "Strapi Connected", project, params);
7
+ await AnalyticsService.trackEvent(data.event, {
8
+ ...data.data,
9
+ userId,
10
+ category: "Project",
11
+ });
12
+ } catch (e) {
13
+ console.warn(e);
14
+ }
15
+ }
16
+
17
+ static async trackAppDisconnected(userId, project, params = {}) {
18
+ try {
19
+ const data = this.buildData(userId, "Strapi Disconnected", project, params);
20
+ await AnalyticsService.trackEvent(data.event, {
21
+ ...data.data,
22
+ userId,
23
+ category: "Project",
24
+ });
25
+ } catch (e) {
26
+ console.warn(e);
27
+ }
28
+ }
29
+
30
+ static async trackUploadToLocalazy(userId, project, params = {}) {
31
+ try {
32
+ const data = this.buildData(userId, "Strapi Upload", project, params);
33
+ await AnalyticsService.trackEvent(data.event, {
34
+ ...data.data,
35
+ userId,
36
+ category: "Project",
37
+ });
38
+ } catch (e) {
39
+ console.warn(e);
40
+ }
41
+ }
42
+
43
+ static async trackDownloadToStrapi(userId, project, params = {}) {
44
+ try {
45
+ const data = this.buildData(userId, "Strapi Download", project, params);
46
+ await AnalyticsService.trackEvent(data.event, {
47
+ ...data.data,
48
+ userId,
49
+ category: "Project",
50
+ });
51
+ } catch (e) {
52
+ console.warn(e);
53
+ }
54
+ }
55
+
56
+ static buildData(userId, event, project, params) {
57
+ return {
58
+ event,
59
+ data: {
60
+ "User Id": userId,
61
+ "Project Id": project.id,
62
+ "Project Name": project.name,
63
+ ...params,
64
+ },
65
+ };
66
+ }
67
+ }
@@ -0,0 +1,102 @@
1
+ const { isoStrapiToLocalazy, isoLocalazyToStrapi } = require("../iso-locales-utils");
2
+
3
+ describe("iso-locales-utils.js", () => {
4
+ describe("transform Strapi ISO to Localazy ISO", () => {
5
+ it("should transform codes containing lang only", () => {
6
+ // setup
7
+ const input = ["en", "fr", "de", "es", "it", "ja", "ko", "pt", "ru", "zh"];
8
+
9
+ // execute
10
+ const output = input.map((item) => isoStrapiToLocalazy(item));
11
+
12
+ // verify
13
+ const expected = input;
14
+ expect(output).toEqual(expected);
15
+ });
16
+
17
+ it("should transform codes containing lang-region", () => {
18
+ // setup
19
+ const input = ["en-US", "fr-CA", "de-DE", "es-ES", "it-IT", "ja-JP", "ko-KR", "pt-BR", "ru-RU", "zh-CN"];
20
+
21
+ // execute
22
+ const output = input.map((item) => isoStrapiToLocalazy(item));
23
+
24
+ // verify
25
+ const expected = ["en_US", "fr_CA", "de_DE", "es_ES", "it_IT", "ja_JP", "ko_KR", "pt_BR", "ru_RU", "zh_CN"];
26
+ expect(output).toEqual(expected);
27
+ });
28
+
29
+ it("should transform codes containing lang-script", () => {
30
+ // setup
31
+ const input = ["en-Latn", "fr-Latn", "de-Latn", "es-Latn", "it-Latn", "ja-Latn", "ko-Latn", "pt-Latn", "ru-Latn", "zh-Latn"];
32
+
33
+ // execute
34
+ const output = input.map((item) => isoStrapiToLocalazy(item));
35
+
36
+ // verify
37
+ const expected = ["en#Latn", "fr#Latn", "de#Latn", "es#Latn", "it#Latn", "ja#Latn", "ko#Latn", "pt#Latn", "ru#Latn", "zh#Latn"];
38
+ expect(output).toEqual(expected);
39
+ });
40
+
41
+ it("should transform codes containing lang-script-region", () => {
42
+ // setup
43
+ const input = ["en-Latn-US", "fr-Latn-CA", "de-Latn-DE", "es-Latn-ES", "it-Latn-IT", "ja-Latn-JP", "ko-Latn-KR", "pt-Latn-BR", "ru-Latn-RU", "zh-Hant-CN"];
44
+
45
+ // execute
46
+ const output = input.map((item) => isoStrapiToLocalazy(item));
47
+
48
+ // verify
49
+ const expected = ["en_US#Latn", "fr_CA#Latn", "de_DE#Latn", "es_ES#Latn", "it_IT#Latn", "ja_JP#Latn", "ko_KR#Latn", "pt_BR#Latn", "ru_RU#Latn", "zh_CN#Hant"];
50
+ expect(output).toEqual(expected);
51
+ });
52
+ });
53
+
54
+ describe("transform Strapi ISO to Localazy ISO", () => {
55
+ it("should transform codes containing lang only", () => {
56
+ // setup
57
+ const input = ["en", "fr", "de", "es", "it", "ja", "ko", "pt", "ru", "zh"];
58
+
59
+ // execute
60
+ const output = input.map((item) => isoLocalazyToStrapi(item));
61
+
62
+ // verify
63
+ const expected = input;
64
+ expect(output).toEqual(expected);
65
+ });
66
+
67
+ it("should transform codes containing lang-region", () => {
68
+ // setup
69
+ const input = ["en_US", "fr_CA", "de_DE", "es_ES", "it_IT", "ja_JP", "ko_KR", "pt_BR", "ru_RU", "zh_CN"];
70
+
71
+ // execute
72
+ const output = input.map((item) => isoLocalazyToStrapi(item));
73
+
74
+ // verify
75
+ const expected = ["en-US", "fr-CA", "de-DE", "es-ES", "it-IT", "ja-JP", "ko-KR", "pt-BR", "ru-RU", "zh-CN"];
76
+ expect(output).toEqual(expected);
77
+ });
78
+
79
+ it("should transform codes containing lang-script", () => {
80
+ // setup
81
+ const input = ["en#Latn", "fr#Latn", "de#Latn", "es#Latn", "it#Latn", "ja#Latn", "ko#Latn", "pt#Latn", "ru#Latn", "zh#Latn"];
82
+
83
+ // execute
84
+ const output = input.map((item) => isoLocalazyToStrapi(item));
85
+
86
+ // verify
87
+ const expected = ["en-Latn", "fr-Latn", "de-Latn", "es-Latn", "it-Latn", "ja-Latn", "ko-Latn", "pt-Latn", "ru-Latn", "zh-Latn"];
88
+ expect(output).toEqual(expected);
89
+ });
90
+
91
+ it("should transform codes containing lang-script-region", () => {
92
+ // setup
93
+ const input = ["en_US#Latn", "fr_CA#Latn", "de_DE#Latn", "es_ES#Latn", "it_IT#Latn", "ja_JP#Latn", "ko_KR#Latn", "pt_BR#Latn", "ru_RU#Latn", "zh_CN#Hant"];
94
+
95
+ // execute
96
+ const output = input.map((item) => isoLocalazyToStrapi(item));
97
+ // verify
98
+ const expected = ["en-Latn-US", "fr-Latn-CA", "de-Latn-DE", "es-Latn-ES", "it-Latn-IT", "ja-Latn-JP", "ko-Latn-KR", "pt-Latn-BR", "ru-Latn-RU", "zh-Hant-CN"];
99
+ expect(output).toEqual(expected);
100
+ });
101
+ });
102
+ });
@@ -0,0 +1 @@
1
+ export default (value, options = undefined) => new Intl.NumberFormat("en-GB", options).format(value);
@@ -3,7 +3,31 @@ export const isoStrapiToLocalazy = (isoStrapi) => {
3
3
  return null;
4
4
  }
5
5
 
6
- return isoStrapi.replace("_", "-");
6
+ const split = isoStrapi.split("-");
7
+ const language = split[0];
8
+
9
+ const hasRegionAndScript = split.length === 3;
10
+
11
+ if (hasRegionAndScript) {
12
+ const script = split[1];
13
+ const region = split[2];
14
+
15
+ return `${language}_${region}#${script}`;
16
+ }
17
+
18
+ const hasPossiblyRegion = split.length === 2;
19
+
20
+ if (hasPossiblyRegion) {
21
+ const regionOrScript = split[1];
22
+
23
+ // is it script - the way Strapi resolves that
24
+ const isItRegion = regionOrScript.toUpperCase() === regionOrScript;
25
+
26
+ // it is region; otherwise it is script
27
+ return isItRegion ? `${language}_${regionOrScript}` : `${language}#${regionOrScript}`;
28
+ }
29
+
30
+ return isoStrapi.replace("-", "_");
7
31
  };
8
32
 
9
33
  export const isoLocalazyToStrapi = (isoLocalazy) => {
@@ -11,5 +35,24 @@ export const isoLocalazyToStrapi = (isoLocalazy) => {
11
35
  return null;
12
36
  }
13
37
 
14
- return isoLocalazy.replace("-", "_");
38
+ const scriptIndex = isoLocalazy.indexOf("#");
39
+ const hasScript = scriptIndex > -1;
40
+
41
+ if (hasScript) {
42
+ const script = isoLocalazy.substring(scriptIndex + 1);
43
+ const isoLocalazyWithoutScript = isoLocalazy.substring(0, scriptIndex);
44
+ const split = isoLocalazyWithoutScript.split("_");
45
+ const language = split[0];
46
+ const region = split[1];
47
+
48
+ if (!region) {
49
+ return `${language}-${script}`;
50
+ }
51
+
52
+ const isoStrapi = `${language}-${script}-${region.toUpperCase()}`;
53
+
54
+ return isoStrapi;
55
+ }
56
+
57
+ return isoLocalazy.replace("_", "-");
15
58
  };
@@ -12,8 +12,8 @@ import { ThemeProvider } from "@strapi/design-system/ThemeProvider";
12
12
  import { lightTheme } from "@strapi/design-system/themes";
13
13
  import { Box } from "@strapi/design-system/Box";
14
14
  import { Layout } from "@strapi/design-system/Layout";
15
- import { Loader } from "@strapi/design-system/Loader";
16
15
  import { useTranslation } from "react-i18next";
16
+ import Loader from "../../modules/@common/components/PluginPageLoader";
17
17
  import pluginId from "../../pluginId";
18
18
  import Download from "../Download";
19
19
  import Settings from "../Settings";
@@ -5,11 +5,11 @@ import { Button } from "@strapi/design-system/Button";
5
5
  import DownloadIcon from "@strapi/icons/Download";
6
6
  import { Box } from "@strapi/design-system/Box";
7
7
  import { Alert } from "@strapi/design-system/Alert";
8
- import { Loader } from "@strapi/design-system/Loader";
9
8
  import { useTranslation } from "react-i18next";
10
9
  import { Flex } from '@strapi/design-system/Flex';
11
10
  import { Divider } from '@strapi/design-system/Divider';
12
11
  import { Typography } from "@strapi/design-system/Typography";
12
+ import Loader from "../../modules/@common/components/PluginPageLoader";
13
13
  import LocalazyDownloadService from "../../modules/localazy-download/services/localazy-download-service";
14
14
  import areLocalesCompatible from "../../modules/@common/utils/are-locales-compatible";
15
15
  import hasModelChanged from "../../modules/plugin-settings/functions/has-model-changed";
@@ -17,6 +17,7 @@ import TransferReport from "../../modules/@common/components/TransferReport";
17
17
  import ReadDocsButton from "../../modules/localazy-upload/components/ReadDocsButton";
18
18
  import "../../i18n";
19
19
  import { getLocalazyIdentity } from "../../state/localazy-identity";
20
+ import ProductAnalyticsService from "../../modules/@common/services/product-analytics-service";
20
21
 
21
22
  function Download(props) {
22
23
  const { t } = useTranslation();
@@ -44,6 +45,16 @@ function Download(props) {
44
45
  setIsDownloading(true);
45
46
  const result = await LocalazyDownloadService.download();
46
47
  setDownloadResult(result);
48
+
49
+ // track download
50
+ ProductAnalyticsService.trackDownloadToStrapi(
51
+ localazyIdentity.user.id,
52
+ localazyIdentity.project,
53
+ {
54
+ "Target Languages Codes": "all",
55
+ }
56
+ );
57
+
47
58
  setIsDownloading(false);
48
59
  setshowDownloadFinishedModal(true);
49
60
  };
@@ -115,7 +126,7 @@ function Download(props) {
115
126
  >
116
127
  <Divider />
117
128
  </Box>
118
- <Box marginTop={4}>
129
+ <Box marginTop={2}>
119
130
  <Flex gap="2">
120
131
  <Button variant="secondary" onClick={onTranslateInLocalazyClick}>
121
132
  {t("download.translate_in_localazy")}
@@ -6,19 +6,20 @@
6
6
 
7
7
  import React from "react";
8
8
  import PropTypes from "prop-types";
9
- import { Loader } from "@strapi/design-system/Loader";
10
9
  import { Link } from "@strapi/design-system/Link";
11
10
  import { useHistory } from "react-router-dom";
12
11
  import { useTranslation } from "react-i18next";
13
12
  import { HeaderLayout } from "@strapi/design-system/Layout";
14
13
  import { Box } from "@strapi/design-system/Box";
15
14
  import { Typography } from "@strapi/design-system/Typography";
15
+ import Loader from "../../modules/@common/components/PluginPageLoader";
16
16
  import { setLocalazyIdentity } from "../../state/localazy-identity";
17
17
  import LocalazyUserService from "../../modules/user/services/localazy-user-service";
18
18
  import LoginButton from "../../modules/login/components/LoginButton";
19
19
  import redirectToPluginRoute, {
20
20
  PLUGIN_ROUTES,
21
21
  } from "../../modules/@common/utils/redirect-to-plugin-route";
22
+ import ProductAnalyticsService from "../../modules/@common/services/product-analytics-service";
22
23
 
23
24
  import "../../i18n";
24
25
 
@@ -40,6 +41,12 @@ function Login(props) {
40
41
  setLocalazyIdentity(result);
41
42
 
42
43
  if (result.accessToken) {
44
+ // track user login
45
+ ProductAnalyticsService.trackAppConnected(
46
+ result.user.id,
47
+ result.project,
48
+ );
49
+
43
50
  redirectToPluginRoute(PLUGIN_ROUTES.DOWNLOAD, history);
44
51
  }
45
52
  };
@@ -49,11 +56,21 @@ function Login(props) {
49
56
  <HeaderLayout
50
57
  title={props.title}
51
58
  subtitle={props.subtitle}
52
- as="h2"
59
+ as="h1"
53
60
  />
54
61
  {props.isLoading && (<Loader>{t("common.loading_content")}</Loader>)}
55
62
  {!props.isLoading && (
56
- <Box paddingLeft={10}>
63
+ <Box
64
+ marginLeft={10}
65
+ marginRight={10}
66
+ background="neutral0"
67
+ paddingTop={6}
68
+ paddingRight={7}
69
+ paddingBottom={6}
70
+ paddingLeft={7}
71
+ hasRadius
72
+ shadow="tableShadow"
73
+ >
57
74
  <Box>
58
75
  <Typography variant="epsilon" textColor="neutral600">
59
76
  {t("common.localazy_plugin_description")}
@@ -1,12 +1,12 @@
1
1
  import React, { useEffect, useState } from "react";
2
2
  import PropTypes from "prop-types";
3
- import { Loader } from "@strapi/design-system/Loader";
4
3
  import { HeaderLayout } from "@strapi/design-system/Layout";
5
4
  import { Box } from "@strapi/design-system/Box";
6
5
  import { useHistory } from "react-router-dom";
7
6
  import { useTranslation } from "react-i18next";
8
7
  import { Grid } from '@strapi/design-system/Grid';
9
8
  import { Divider } from '@strapi/design-system/Divider';
9
+ import Loader from "../../modules/@common/components/PluginPageLoader";
10
10
  import LogoutButton from "../../modules/login/components/LogoutButton";
11
11
  import redirectToPluginRoute, {
12
12
  PLUGIN_ROUTES,
@@ -16,6 +16,8 @@ import OverviewItem from "../../modules/settings/components/OverviewItem";
16
16
  import OverviewItemLink from "../../modules/settings/components/OverviewItemLink";
17
17
  import PrerequisitiesInfo from "../../modules/settings/components/PrerequisitiesInfo";
18
18
  import ProjectService from "../../modules/@common/services/project-service";
19
+ import ProductAnalyticsService from "../../modules/@common/services/product-analytics-service";
20
+ import formatNumber from "../../modules/@common/utils/format-number";
19
21
 
20
22
  import "../../i18n";
21
23
 
@@ -45,6 +47,12 @@ function Settings(props) {
45
47
  * On logout action
46
48
  */
47
49
  const onLoggedOut = () => {
50
+ // track user logout
51
+ ProductAnalyticsService.trackAppDisconnected(
52
+ localazyIdentity.user.id,
53
+ localazyIdentity.project,
54
+ );
55
+
48
56
  redirectToPluginRoute(PLUGIN_ROUTES.LOGIN, history);
49
57
  };
50
58
 
@@ -56,7 +64,9 @@ function Settings(props) {
56
64
  primaryAction={<LogoutButton onResultFetched={onLoggedOut} />}
57
65
  as="h2"
58
66
  />
59
- {(props.isLoading || isLoading) && (<Loader>{t("common.loading_content")}</Loader>)}
67
+ {(props.isLoading || isLoading) && (
68
+ <Loader>{t("common.loading_content")}</Loader>
69
+ )}
60
70
  {!(props.isLoading || isLoading) && (
61
71
  <Box paddingRight={10} paddingLeft={10}>
62
72
  <Box
@@ -86,7 +96,7 @@ function Settings(props) {
86
96
  <OverviewItem
87
97
  label={t("settings.remaining_organization_keys")}
88
98
  value={
89
- connectedProject.organization.availableKeys - connectedProject.organization.usedKeys
99
+ formatNumber(connectedProject.organization.availableKeys - connectedProject.organization.usedKeys)
90
100
  }
91
101
  />
92
102
  <OverviewItemLink
@@ -9,7 +9,7 @@ import { Button } from "@strapi/design-system/Button";
9
9
  import UploadIcon from "@strapi/icons/Upload";
10
10
  import { Box } from "@strapi/design-system/Box";
11
11
  import { Alert } from "@strapi/design-system/Alert";
12
- import { Loader } from "@strapi/design-system/Loader";
12
+ import Loader from "../../modules/@common/components/PluginPageLoader";
13
13
  import LocalazyUploadService from "../../modules/localazy-upload/services/localazy-upload-service";
14
14
  import areLocalesCompatible from "../../modules/@common/utils/are-locales-compatible";
15
15
  import { getStrapiDefaultLocale, getLocalazySourceLanguage } from "../../modules/@common/utils/get-default-locale";
@@ -21,6 +21,8 @@ import ReadDocsButton from "../../modules/localazy-upload/components/ReadDocsBut
21
21
  import redirectToPluginRoute, {
22
22
  PLUGIN_ROUTES,
23
23
  } from "../../modules/@common/utils/redirect-to-plugin-route";
24
+ import { getLocalazyIdentity } from "../../state/localazy-identity";
25
+ import ProductAnalyticsService from "../../modules/@common/services/product-analytics-service";
24
26
 
25
27
  import "../../i18n";
26
28
 
@@ -38,6 +40,7 @@ function Upload(props) {
38
40
  const [isUploading, setIsUploading] = useState(false);
39
41
  const [strapiDefaultLocale, setStrapiDefaultLocale] = useState(null);
40
42
  const [localazySourceLanguage, setLocalazySourceLanguage] = useState(null);
43
+ const [localazyIdentity] = getLocalazyIdentity();
41
44
 
42
45
  const onChangeSettingsClick = () => {
43
46
  redirectToPluginRoute(PLUGIN_ROUTES.CONTENT_TRANSFER_SETUP);
@@ -49,6 +52,16 @@ function Upload(props) {
49
52
  setIsUploading(true);
50
53
  const result = await LocalazyUploadService.upload();
51
54
  setUploadResult(result);
55
+
56
+ // track upload
57
+ ProductAnalyticsService.trackUploadToLocalazy(
58
+ localazyIdentity.user.id,
59
+ localazyIdentity.project,
60
+ {
61
+ "Source Language Code": localazySourceLanguage.code,
62
+ }
63
+ );
64
+
52
65
  setIsUploading(false);
53
66
  setShowUploadFinishedModal(true);
54
67
  };
@@ -0,0 +1,14 @@
1
+ import createPluginConnectorAxiosInstance from "../utils/createPluginConnectorAxiosInstance";
2
+
3
+ const ANALYTICS_PATH = "/analytics";
4
+ const axiosInstance = createPluginConnectorAxiosInstance();
5
+ export default class AnalyticsService {
6
+ static async trackEvent(event, data) {
7
+ const result = await axiosInstance.post(`${ANALYTICS_PATH}/track`, {
8
+ event,
9
+ ...data,
10
+ });
11
+
12
+ return result.data;
13
+ }
14
+ }
@@ -0,0 +1,45 @@
1
+ /**
2
+ * axios with plugin connector config.
3
+ */
4
+
5
+ import axios from "axios";
6
+ import { config } from "../../../server";
7
+
8
+ const BASE_PLUGIN_PATH = config.default.LOCALAZY_PLUGIN_CONNECTOR_API_URL;
9
+
10
+ const createPluginConnectorAxiosInstance = (baseUrl = null) => {
11
+ if (baseUrl === null) {
12
+ baseUrl = `${BASE_PLUGIN_PATH}`;
13
+ }
14
+
15
+ const instance = axios.create({
16
+ baseURL: baseUrl,
17
+ });
18
+
19
+ instance.interceptors.request.use(
20
+ async (config) => {
21
+ config.headers = {
22
+ Accept: "application/json",
23
+ "Content-Type": "application/json",
24
+ // Strapi plugin id in terms of plugin connector
25
+ "X-Localazy-Plugin-Id": 1,
26
+ };
27
+
28
+ return config;
29
+ },
30
+ (error) => {
31
+ Promise.reject(error);
32
+ }
33
+ );
34
+
35
+ instance.interceptors.response.use(
36
+ (response) => response,
37
+ (error) => {
38
+ throw error;
39
+ }
40
+ );
41
+
42
+ return instance;
43
+ };
44
+
45
+ export default createPluginConnectorAxiosInstance;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@localazy/strapi-plugin",
3
- "version": "0.1.5",
3
+ "version": "0.1.8",
4
4
  "description": "The official Strapi Plugin by Localazy.",
5
5
  "strapi": {
6
6
  "name": "localazy",
@@ -28,8 +28,6 @@
28
28
  },
29
29
  "dependencies": {
30
30
  "@localazy/ts-api": "^1.0.6",
31
- "@strapi/design-system": "^1.0.0",
32
- "@strapi/icons": "^1.0.0",
33
31
  "deep-keys": "^0.5.0",
34
32
  "i18next": "^21.6.13",
35
33
  "isomorphic-fetch": "^3.0.0",
@@ -41,7 +39,9 @@
41
39
  "styled-components": "^5.3.3"
42
40
  },
43
41
  "peerDependencies": {
44
- "@strapi/strapi": "^4.0.0"
42
+ "@strapi/strapi": "^4.0.0",
43
+ "@strapi/design-system": "^1.0.0",
44
+ "@strapi/icons": "^1.0.0"
45
45
  },
46
46
  "devDependencies": {
47
47
  "@babel/plugin-transform-modules-commonjs": "^7.17.7",
@@ -52,8 +52,8 @@
52
52
  "jest": "^27.5.1"
53
53
  },
54
54
  "author": {
55
- "name": "David Vaclavek",
56
- "email": "david@localazy.com",
55
+ "name": "Localazy",
56
+ "email": "team@localazy.com",
57
57
  "url": "https://localazy.com"
58
58
  },
59
59
  "maintainers": [
@@ -2,8 +2,8 @@
2
2
 
3
3
  module.exports = {
4
4
  LOCALAZY_OAUTH_URL: "https://testing.localazy.com/oauth/authorize",
5
- LOCALAZY_OAUTH_APP_CLIENT_ID: "18503917571895066465",
6
- LOCALAZY_PLUGIN_CONNECTOR_API_URL: "http://localhost:3000",
5
+ LOCALAZY_OAUTH_APP_CLIENT_ID: "18503917571895066466",
6
+ LOCALAZY_PLUGIN_CONNECTOR_API_URL: "https://testing.localazy.com/plugin-connector",
7
7
  LOCALAZY_PUBLIC_API_URL: "https://testing.localazy.com/pubapi",
8
8
  LOCALAZY_PLUGIN_ID: "1",
9
9
  LOCALAZY_DEFAULT_FILE_NAME: "strapi.json",
@@ -1,15 +1,20 @@
1
1
  "use strict";
2
2
 
3
3
  // depending on the STRAPI_ADMIN_LOCALAZY_ENV, use the correct config
4
- const config =
5
- process.env.STRAPI_ADMIN_LOCALAZY_ENV === "development"
6
- ? require("./development/index")
7
- : require("./production/index");
4
+ let config = require("./production/index");
5
+
6
+ if (process.env.STRAPI_ADMIN_LOCALAZY_ENV === "local") {
7
+ config = require("./local/index");
8
+ }
9
+
10
+ if (process.env.STRAPI_ADMIN_LOCALAZY_ENV === "development") {
11
+ config = require("./development/index");
12
+ }
8
13
 
9
14
  module.exports = {
10
15
  default: {
11
16
  // Default plugin configuration, merged with the user configuration
12
17
  ...(config || {}),
13
18
  },
14
- validator() {},
19
+ validator() { },
15
20
  };
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+
3
+ module.exports = {
4
+ LOCALAZY_OAUTH_URL: "https://testing.localazy.com/oauth/authorize",
5
+ LOCALAZY_OAUTH_APP_CLIENT_ID: "18503917571895066465",
6
+ LOCALAZY_PLUGIN_CONNECTOR_API_URL: "http://localhost:3000",
7
+ LOCALAZY_PUBLIC_API_URL: "https://testing.localazy.com/pubapi",
8
+ LOCALAZY_PLUGIN_ID: "1",
9
+ LOCALAZY_DEFAULT_FILE_NAME: "strapi.json",
10
+ LOCALAZY_DEFAULT_FILE_PATH: "",
11
+ LOCALAZY_DEFAULT_FILE_EXTENSION: "json",
12
+ LOCALAZY_DEFAULT_LOCALE: "en",
13
+ LOCALAZY_API_USER_JWT_COOKIE_NAME: "LOCALAZY-API-USER-JWT",
14
+ LOCALAZY_API_USER_COOKIE_EXPIRATION: 7,
15
+ };
@@ -25,7 +25,9 @@ module.exports = {
25
25
  const messageReport = [];
26
26
 
27
27
  // Strapi Service
28
- const StrapiService = strapi.plugin("localazy").service("strapiService");
28
+ const StrapiService = strapi
29
+ .plugin("localazy")
30
+ .service("strapiService");
29
31
 
30
32
  // Strapi i18n Service
31
33
  const StrapiI18nService = strapi
@@ -13,17 +13,18 @@ module.exports = ({ strapi }) => ({
13
13
  async createStrapiLocale(ctx, isoLocalazy) {
14
14
  try {
15
15
  const isoStrapi = isoLocalazyToStrapi(isoLocalazy);
16
- const localeName = intlDisplayName(isoLocalazy);
16
+ let localeName = intlDisplayName(isoStrapi);
17
17
 
18
18
  if (!localeName || !isoStrapi) {
19
19
  throw new Error("Invalid locale");
20
20
  }
21
+ localeName = `${localeName} (${isoStrapi})`;
21
22
 
22
23
  const newLocaleCtx = { ...ctx };
23
24
  newLocaleCtx.request.body = {
24
25
  isDefault: false,
25
26
  code: isoStrapi,
26
- name: localeName,
27
+ name: localeName.substring(0, 50), // limit name to 50 characters (given by Strapi)
27
28
  };
28
29
 
29
30
  await strapi
@@ -39,7 +40,6 @@ module.exports = ({ strapi }) => ({
39
40
  parseLocalazyKey(key) {
40
41
  const split = key.split(/\.|\[|\]/);
41
42
  const filteredSplit = split.filter((item) => item !== "");
42
- // return split;
43
43
 
44
44
  return {
45
45
  uid: `${filteredSplit[0]}.${filteredSplit[1]}`,
@@ -0,0 +1,104 @@
1
+ "use strict";
2
+
3
+ const { isoStrapiToLocalazy, isoLocalazyToStrapi } = require("../iso-locales-utils.js");
4
+
5
+ describe("iso-locales-utils.js", () => {
6
+ describe("transform Strapi ISO to Localazy ISO", () => {
7
+ it("should transform codes containing lang only", () => {
8
+ // setup
9
+ const input = ["en", "fr", "de", "es", "it", "ja", "ko", "pt", "ru", "zh"];
10
+
11
+ // execute
12
+ const output = input.map((item) => isoStrapiToLocalazy(item));
13
+
14
+ // verify
15
+ const expected = input;
16
+ expect(output).toEqual(expected);
17
+ });
18
+
19
+ it("should transform codes containing lang-region", () => {
20
+ // setup
21
+ const input = ["en-US", "fr-CA", "de-DE", "es-ES", "it-IT", "ja-JP", "ko-KR", "pt-BR", "ru-RU", "zh-CN"];
22
+
23
+ // execute
24
+ const output = input.map((item) => isoStrapiToLocalazy(item));
25
+
26
+ // verify
27
+ const expected = ["en_US", "fr_CA", "de_DE", "es_ES", "it_IT", "ja_JP", "ko_KR", "pt_BR", "ru_RU", "zh_CN"];
28
+ expect(output).toEqual(expected);
29
+ });
30
+
31
+ it("should transform codes containing lang-script", () => {
32
+ // setup
33
+ const input = ["en-Latn", "fr-Latn", "de-Latn", "es-Latn", "it-Latn", "ja-Latn", "ko-Latn", "pt-Latn", "ru-Latn", "zh-Latn"];
34
+
35
+ // execute
36
+ const output = input.map((item) => isoStrapiToLocalazy(item));
37
+
38
+ // verify
39
+ const expected = ["en#Latn", "fr#Latn", "de#Latn", "es#Latn", "it#Latn", "ja#Latn", "ko#Latn", "pt#Latn", "ru#Latn", "zh#Latn"];
40
+ expect(output).toEqual(expected);
41
+ });
42
+
43
+ it("should transform codes containing lang-script-region", () => {
44
+ // setup
45
+ const input = ["en-Latn-US", "fr-Latn-CA", "de-Latn-DE", "es-Latn-ES", "it-Latn-IT", "ja-Latn-JP", "ko-Latn-KR", "pt-Latn-BR", "ru-Latn-RU", "zh-Hant-CN"];
46
+
47
+ // execute
48
+ const output = input.map((item) => isoStrapiToLocalazy(item));
49
+
50
+ // verify
51
+ const expected = ["en_US#Latn", "fr_CA#Latn", "de_DE#Latn", "es_ES#Latn", "it_IT#Latn", "ja_JP#Latn", "ko_KR#Latn", "pt_BR#Latn", "ru_RU#Latn", "zh_CN#Hant"];
52
+ expect(output).toEqual(expected);
53
+ });
54
+ });
55
+
56
+ describe("transform Strapi ISO to Localazy ISO", () => {
57
+ it("should transform codes containing lang only", () => {
58
+ // setup
59
+ const input = ["en", "fr", "de", "es", "it", "ja", "ko", "pt", "ru", "zh"];
60
+
61
+ // execute
62
+ const output = input.map((item) => isoLocalazyToStrapi(item));
63
+
64
+ // verify
65
+ const expected = input;
66
+ expect(output).toEqual(expected);
67
+ });
68
+
69
+ it("should transform codes containing lang-region", () => {
70
+ // setup
71
+ const input = ["en_US", "fr_CA", "de_DE", "es_ES", "it_IT", "ja_JP", "ko_KR", "pt_BR", "ru_RU", "zh_CN"];
72
+
73
+ // execute
74
+ const output = input.map((item) => isoLocalazyToStrapi(item));
75
+
76
+ // verify
77
+ const expected = ["en-US", "fr-CA", "de-DE", "es-ES", "it-IT", "ja-JP", "ko-KR", "pt-BR", "ru-RU", "zh-CN"];
78
+ expect(output).toEqual(expected);
79
+ });
80
+
81
+ it("should transform codes containing lang-script", () => {
82
+ // setup
83
+ const input = ["en#Latn", "fr#Latn", "de#Latn", "es#Latn", "it#Latn", "ja#Latn", "ko#Latn", "pt#Latn", "ru#Latn", "zh#Latn"];
84
+
85
+ // execute
86
+ const output = input.map((item) => isoLocalazyToStrapi(item));
87
+
88
+ // verify
89
+ const expected = ["en-Latn", "fr-Latn", "de-Latn", "es-Latn", "it-Latn", "ja-Latn", "ko-Latn", "pt-Latn", "ru-Latn", "zh-Latn"];
90
+ expect(output).toEqual(expected);
91
+ });
92
+
93
+ it("should transform codes containing lang-script-region", () => {
94
+ // setup
95
+ const input = ["en_US#Latn", "fr_CA#Latn", "de_DE#Latn", "es_ES#Latn", "it_IT#Latn", "ja_JP#Latn", "ko_KR#Latn", "pt_BR#Latn", "ru_RU#Latn", "zh_CN#Hant"];
96
+
97
+ // execute
98
+ const output = input.map((item) => isoLocalazyToStrapi(item));
99
+ // verify
100
+ const expected = ["en-Latn-US", "fr-Latn-CA", "de-Latn-DE", "es-Latn-ES", "it-Latn-IT", "ja-Latn-JP", "ko-Latn-KR", "pt-Latn-BR", "ru-Latn-RU", "zh-Hant-CN"];
101
+ expect(output).toEqual(expected);
102
+ });
103
+ });
104
+ });
@@ -1,7 +1,4 @@
1
- const { isoStrapiToLocalazy } = require("./iso-locales-utils.js");
2
-
3
- module.exports = (isoCode) => {
4
- const isoDashed = isoStrapiToLocalazy(isoCode);
1
+ module.exports = (isoStrapi) => {
5
2
  let languageNames = new Intl.DisplayNames(["en"], { type: "language" });
6
- return languageNames.of(isoDashed);
3
+ return languageNames.of(isoStrapi);
7
4
  };
@@ -5,7 +5,28 @@ const isoStrapiToLocalazy = (isoStrapi) => {
5
5
  return null;
6
6
  }
7
7
 
8
- return isoStrapi.replace("_", "-");
8
+ const split = isoStrapi.split("-");
9
+ const language = split[0];
10
+
11
+ const hasRegionAndScript = split.length === 3;
12
+ if (hasRegionAndScript) {
13
+ const script = split[1];
14
+ const region = split[2];
15
+ return `${language}_${region}#${script}`;
16
+ }
17
+
18
+ const hasPossiblyRegion = split.length === 2;
19
+ if (hasPossiblyRegion) {
20
+ const regionOrScript = split[1];
21
+
22
+ // is it script - the way Strapi resolves that
23
+ const isItRegion = regionOrScript.toUpperCase() === regionOrScript;
24
+
25
+ // it is region; otherwise it is script
26
+ return isItRegion ? `${language}_${regionOrScript}` : `${language}#${regionOrScript}`;
27
+ }
28
+
29
+ return isoStrapi.replace("-", "_");
9
30
  };
10
31
 
11
32
  const isoLocalazyToStrapi = (isoLocalazy) => {
@@ -13,7 +34,24 @@ const isoLocalazyToStrapi = (isoLocalazy) => {
13
34
  return null;
14
35
  }
15
36
 
16
- return isoLocalazy.replace("-", "_");
37
+ const scriptIndex = isoLocalazy.indexOf("#");
38
+ const hasScript = scriptIndex > -1;
39
+ if (hasScript) {
40
+ const script = isoLocalazy.substring(scriptIndex + 1);
41
+ const isoLocalazyWithoutScript = isoLocalazy.substring(0, scriptIndex);
42
+ const split = isoLocalazyWithoutScript.split("_");
43
+ const language = split[0];
44
+ const region = split[1];
45
+
46
+ if (!region) {
47
+ return `${language}-${script}`;
48
+ }
49
+
50
+ const isoStrapi = `${language}-${script}-${region.toUpperCase()}`;
51
+ return isoStrapi;
52
+ }
53
+
54
+ return isoLocalazy.replace("_", "-");
17
55
  };
18
56
 
19
57
  module.exports = {