diff --git a/docs/package.json b/docs/package.json index 3044c22..5af249e 100644 --- a/docs/package.json +++ b/docs/package.json @@ -11,14 +11,16 @@ "dependencies": { "@vercel/analytics": "^1.3.1", "ace-builds": "^1.34.2", + "axios": "^1.7.7", + "azure-translator-code": "^1.1.17", "next": "14.2.3", "next-international": "^1.2.4", "react": "^18", "react-ace": "^11.0.1", "react-dom": "^18", - "react-icons": "^5.2.1", + "react-icons": "^5.3.0", "react-syntax-highlighter": "^15.5.0", - "sharp": "^0.33.4", + "sharp": "^0.33.5", "uuid": "^11.0.2" }, "devDependencies": { diff --git a/docs/src/actions/index.ts b/docs/src/actions/index.ts index 449820b..da4192e 100644 --- a/docs/src/actions/index.ts +++ b/docs/src/actions/index.ts @@ -1,8 +1,8 @@ "use server"; +import { translate, translateText } from "azure-translator-code"; + import localesCodes from "@/lib/localesCode"; -import translate from "@/lib/translate"; -import { translateText } from "@/lib/translateText"; import { getScopedI18n } from "@/locales/server"; const key = process.env.AZURE_API_KEY ?? ""; diff --git a/docs/src/lib/translate.ts b/docs/src/lib/translate.ts deleted file mode 100644 index 4ed8ab8..0000000 --- a/docs/src/lib/translate.ts +++ /dev/null @@ -1,162 +0,0 @@ -import type { JSONValue, TranslationType } from "@/types/translations"; - -import { translateText } from "./translateText"; - -export default async function translate( - key: string, - endpoint: string, - location: string, - fromLang: string, - toLangs: string[], - jsonFile: TranslationType, -) { - const translatedJson: TranslationType = {}; - const isArrayBigerThanOne = toLangs.length > 1; - - for (const [jsonKey, jsonValue] of Object.entries(jsonFile)) { - translatedJson[jsonKey] = await translateValue( - jsonValue, - key, - endpoint, - location, - fromLang, - toLangs, - isArrayBigerThanOne, - ); - } - - return translatedJson; -} - -async function translateValue( - value: JSONValue, - key: string, - endpoint: string, - location: string, - fromLang: string, - toLangs: string[], - isArrayBigerThanOne: boolean, -): Promise { - if (isInvalidJSONValue(value)) { - throw new Error("Invalid JSON value"); - } - - if (isNotNeedToTranslate(value)) { - return value; - } else if (isString(value)) { - return await translateString( - value, - key, - endpoint, - location, - fromLang, - toLangs, - isArrayBigerThanOne, - ); - } else if (isArray(value)) { - return await translateArray( - value, - key, - endpoint, - location, - fromLang, - toLangs, - isArrayBigerThanOne, - ); - } else if (isObjectNotNull(value)) { - return await translate( - key, - endpoint, - location, - fromLang, - toLangs, - value as TranslationType, - ); - } else { - return null; - } -} - -async function translateString( - value: string, - key: string, - endpoint: string, - location: string, - fromLang: string, - toLangs: string[], - isArrayBigerThanOne: boolean, -): Promise { - const response = await translateText( - value, - fromLang, - toLangs, - endpoint, - key, - location, - ); - - const translations = response[0].translations; - - const translatedValues = translations.map((translation: any) => { - return translation.text; - }); - - return isArrayBigerThanOne ? translatedValues : translatedValues[0]; -} - -async function translateArray( - array: JSONValue[], - key: string, - endpoint: string, - location: string, - fromLang: string, - toLangs: string[], - isArrayBigerThanOne: boolean, -): Promise { - const translatedArray: (TranslationType | TranslationType[])[] = []; - for (const item of array) { - if (typeof item === "string") { - const translatedItem = await translateString( - item, - key, - endpoint, - location, - fromLang, - toLangs, - isArrayBigerThanOne, - ); - if (translatedItem !== null) { - translatedArray.push( - translatedItem as TranslationType | TranslationType[], - ); - } - } else { - translatedArray.push(item as TranslationType); - } - } - return translatedArray; -} - -function isObjectNotNull(value: JSONValue): value is Record { - return typeof value === "object" && value !== null; -} - -function isString(value: JSONValue): value is string { - return typeof value === "string"; -} - -function isArray(value: JSONValue): value is JSONValue[] { - return Array.isArray(value); -} - -function isNotNeedToTranslate(value: JSONValue): boolean { - const types = ["number", "boolean"]; - - return types.includes(typeof value); -} - -function isInvalidJSONValue(value: JSONValue): value is never { - const invalidTypes = ["function", "symbol", "undefined"]; - - return invalidTypes.includes(typeof value); -} diff --git a/docs/src/lib/translateText.ts b/docs/src/lib/translateText.ts deleted file mode 100644 index ff95c11..0000000 --- a/docs/src/lib/translateText.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { v4 as uuidv4 } from "uuid"; - -import type { TranslationTextFetch } from "@/types/translations"; - -export async function translateText( - text: string, - from: string, - to: string[], - endpoint: string, - key: string, - location: string, -): Promise { - const filteredEndpoint = endpoint.replace(/\/$/, ""); - - const toDestructured = to.map((lang) => `to=${lang}`).join("&"); - - const url = `${filteredEndpoint}/translate?api-version=3.0&from=${from}&${toDestructured}`; - - const response = await fetch(url, { - method: "POST", - body: JSON.stringify([{ text }]), - headers: { - "Ocp-Apim-Subscription-Key": key, - "Ocp-Apim-Subscription-Region": location, - "Content-type": "application/json", - "X-ClientTraceId": uuidv4().toString(), - }, - }); - - const data = await response.json(); - - return data; -} diff --git a/docs/src/types/translations/index.ts b/docs/src/types/translations/index.ts index 691db9c..0476351 100644 --- a/docs/src/types/translations/index.ts +++ b/docs/src/types/translations/index.ts @@ -1,24 +1,3 @@ -/** - * Represents the type of a translation object. - */ -export interface TranslationType { - [key: string]: JSONValue; -} - -export type JSONValue = - | string - | number - | boolean - | null - | JSONArray - | TranslationType - | object; -export interface JSONArray extends Array {} - -export type TranslationTextFetch = { - translations: { text: string; to: string }[]; -}[]; - export type LanguagesCode = | "en" | "pt" diff --git a/docs/yarn.lock b/docs/yarn.lock index a4f127a..15cdfc1 100644 --- a/docs/yarn.lock +++ b/docs/yarn.lock @@ -1068,6 +1068,13 @@ __metadata: languageName: node linkType: hard +"asynckit@npm:^0.4.0": + version: 0.4.0 + resolution: "asynckit@npm:0.4.0" + checksum: 10c0/d73e2ddf20c4eb9337e1b3df1a0f6159481050a5de457c55b14ea2e5cb6d90bb69e004c9af54737a5ee0917fcf2c9e25de67777bbe58261847846066ba75bc9d + languageName: node + linkType: hard + "available-typed-arrays@npm:^1.0.7": version: 1.0.7 resolution: "available-typed-arrays@npm:1.0.7" @@ -1084,6 +1091,17 @@ __metadata: languageName: node linkType: hard +"axios@npm:^1.7.7": + version: 1.7.7 + resolution: "axios@npm:1.7.7" + dependencies: + follow-redirects: "npm:^1.15.6" + form-data: "npm:^4.0.0" + proxy-from-env: "npm:^1.1.0" + checksum: 10c0/4499efc89e86b0b49ffddc018798de05fab26e3bf57913818266be73279a6418c3ce8f9e934c7d2d707ab8c095e837fc6c90608fb7715b94d357720b5f568af7 + languageName: node + linkType: hard + "axobject-query@npm:^4.1.0": version: 4.1.0 resolution: "axobject-query@npm:4.1.0" @@ -1091,6 +1109,16 @@ __metadata: languageName: node linkType: hard +"azure-translator-code@npm:^1.1.17": + version: 1.1.17 + resolution: "azure-translator-code@npm:1.1.17" + dependencies: + axios: "npm:^1.7.7" + uuid: "npm:^10.0.0" + checksum: 10c0/231036038b9109f506f2ef45ae937965cc71992a27c483373e8801522de082ba2e526fdc821792f09868cd92e79dfd52de1d9f24b89d5d022ba0f27dbd15b372 + languageName: node + linkType: hard + "azure-translator-code@workspace:.": version: 0.0.0-use.local resolution: "azure-translator-code@workspace:." @@ -1102,6 +1130,8 @@ __metadata: "@types/uuid": "npm:^9.0.8" "@vercel/analytics": "npm:^1.3.1" ace-builds: "npm:^1.34.2" + axios: "npm:^1.7.7" + azure-translator-code: "npm:^1.1.17" eslint: "npm:^8.57.0" eslint-config-next: "npm:14.2.3" eslint-config-universe: "npm:^12.1.0" @@ -1114,9 +1144,9 @@ __metadata: react: "npm:^18" react-ace: "npm:^11.0.1" react-dom: "npm:^18" - react-icons: "npm:^5.2.1" + react-icons: "npm:^5.3.0" react-syntax-highlighter: "npm:^15.5.0" - sharp: "npm:^0.33.4" + sharp: "npm:^0.33.5" tailwindcss: "npm:^3.4.1" typescript: "npm:^5" uuid: "npm:^11.0.2" @@ -1342,6 +1372,15 @@ __metadata: languageName: node linkType: hard +"combined-stream@npm:^1.0.8": + version: 1.0.8 + resolution: "combined-stream@npm:1.0.8" + dependencies: + delayed-stream: "npm:~1.0.0" + checksum: 10c0/0dbb829577e1b1e839fa82b40c07ffaf7de8a09b935cadd355a73652ae70a88b4320db322f6634a4ad93424292fa80973ac6480986247f1734a1137debf271d5 + languageName: node + linkType: hard + "comma-separated-tokens@npm:^1.0.0": version: 1.0.8 resolution: "comma-separated-tokens@npm:1.0.8" @@ -1506,6 +1545,13 @@ __metadata: languageName: node linkType: hard +"delayed-stream@npm:~1.0.0": + version: 1.0.0 + resolution: "delayed-stream@npm:1.0.0" + checksum: 10c0/d758899da03392e6712f042bec80aa293bbe9e9ff1b2634baae6a360113e708b91326594c8a486d475c69d6259afb7efacdc3537bfcda1c6c648e390ce601b19 + languageName: node + linkType: hard + "detect-libc@npm:^2.0.3": version: 2.0.3 resolution: "detect-libc@npm:2.0.3" @@ -2279,6 +2325,16 @@ __metadata: languageName: node linkType: hard +"follow-redirects@npm:^1.15.6": + version: 1.15.9 + resolution: "follow-redirects@npm:1.15.9" + peerDependenciesMeta: + debug: + optional: true + checksum: 10c0/5829165bd112c3c0e82be6c15b1a58fa9dcfaede3b3c54697a82fe4a62dd5ae5e8222956b448d2f98e331525f05d00404aba7d696de9e761ef6e42fdc780244f + languageName: node + linkType: hard + "for-each@npm:^0.3.3": version: 0.3.3 resolution: "for-each@npm:0.3.3" @@ -2298,6 +2354,17 @@ __metadata: languageName: node linkType: hard +"form-data@npm:^4.0.0": + version: 4.0.1 + resolution: "form-data@npm:4.0.1" + dependencies: + asynckit: "npm:^0.4.0" + combined-stream: "npm:^1.0.8" + mime-types: "npm:^2.1.12" + checksum: 10c0/bb102d570be8592c23f4ea72d7df9daa50c7792eb0cf1c5d7e506c1706e7426a4e4ae48a35b109e91c85f1c0ec63774a21ae252b66f4eb981cb8efef7d0463c8 + languageName: node + linkType: hard + "format@npm:^0.2.0": version: 0.2.2 resolution: "format@npm:0.2.2" @@ -3332,6 +3399,22 @@ __metadata: languageName: node linkType: hard +"mime-db@npm:1.52.0": + version: 1.52.0 + resolution: "mime-db@npm:1.52.0" + checksum: 10c0/0557a01deebf45ac5f5777fe7740b2a5c309c6d62d40ceab4e23da9f821899ce7a900b7ac8157d4548ddbb7beffe9abc621250e6d182b0397ec7f10c7b91a5aa + languageName: node + linkType: hard + +"mime-types@npm:^2.1.12": + version: 2.1.35 + resolution: "mime-types@npm:2.1.35" + dependencies: + mime-db: "npm:1.52.0" + checksum: 10c0/82fb07ec56d8ff1fc999a84f2f217aa46cb6ed1033fefaabd5785b9a974ed225c90dc72fff460259e66b95b73648596dbcc50d51ed69cdf464af2d237d3149b2 + languageName: node + linkType: hard + "minimatch@npm:9.0.3": version: 9.0.3 resolution: "minimatch@npm:9.0.3" @@ -4085,6 +4168,13 @@ __metadata: languageName: node linkType: hard +"proxy-from-env@npm:^1.1.0": + version: 1.1.0 + resolution: "proxy-from-env@npm:1.1.0" + checksum: 10c0/fe7dd8b1bdbbbea18d1459107729c3e4a2243ca870d26d34c2c1bcd3e4425b7bcc5112362df2d93cc7fb9746f6142b5e272fd1cc5c86ddf8580175186f6ad42b + languageName: node + linkType: hard + "punycode@npm:^2.1.0": version: 2.3.1 resolution: "punycode@npm:2.3.1" @@ -4127,7 +4217,7 @@ __metadata: languageName: node linkType: hard -"react-icons@npm:^5.2.1": +"react-icons@npm:^5.3.0": version: 5.3.0 resolution: "react-icons@npm:5.3.0" peerDependencies: @@ -4438,7 +4528,7 @@ __metadata: languageName: node linkType: hard -"sharp@npm:^0.33.4": +"sharp@npm:^0.33.5": version: 0.33.5 resolution: "sharp@npm:0.33.5" dependencies: @@ -5084,6 +5174,15 @@ __metadata: languageName: node linkType: hard +"uuid@npm:^10.0.0": + version: 10.0.0 + resolution: "uuid@npm:10.0.0" + bin: + uuid: dist/bin/uuid + checksum: 10c0/eab18c27fe4ab9fb9709a5d5f40119b45f2ec8314f8d4cf12ce27e4c6f4ffa4a6321dc7db6c515068fa373c075b49691ba969f0010bf37f44c37ca40cd6bf7fe + languageName: node + linkType: hard + "uuid@npm:^11.0.2": version: 11.0.2 resolution: "uuid@npm:11.0.2"