Skip to content

Commit

Permalink
perf(proxying): fix Buffer not found issue by using proxy
Browse files Browse the repository at this point in the history
This fixes the broken behavior of the component library.

BREAKING CHANGE
Moved translation request to proxy servers. Issues with translation package necessitated moving some request logic to a proxy
  • Loading branch information
MiracleUFO committed Oct 11, 2023
1 parent 04e3a66 commit a6e0b06
Show file tree
Hide file tree
Showing 8 changed files with 86 additions and 79 deletions.
2 changes: 1 addition & 1 deletion .env.development
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
NODE_ENV=development

TRANSLATE_API_PROXY=
TEST_TRANSLATE_API_PROXY=
13 changes: 8 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,20 @@ A modern, *free*, *lightweight* npm package for translating react apps (pages an
- Allows for custom language list files. (Coming in v2.0.0)

## Install
```npm install react-g-translator```
```npm install @miracleufo/react-g-translator```

or with yarn

```yarn add react-g-translator```
```yarn add @miracleufo/react-g-translator```

## Usage

> DISCLAIMER!
To be 100% legal please use the official [Google Translate API](https://cloud.google.com/translate). This project is mainly for pet projects and prototyping 😉. Also, only use the most recent version of this package.

### To translate whole component:
```jsx
import Translator from 'react-g-translator';
import Translator from '@miracleufo/react-g-translator';

return (
<Translator from='en' to='es'>
Expand All @@ -34,7 +37,7 @@ return (

### To translate specific text inline:
```jsx
import { Translate } from 'react-g-translator';
import { Translate } from '@miracleufo/react-g-translator';

return (
<div>
Expand All @@ -48,7 +51,7 @@ return (

### To get translation of text directly:
```jsx
import { getTranslation } from 'react-g-translator';
import { getTranslation } from '@miracleufo/react-g-translator';

const helloInIgbo = await getTranslation('Hello', 'en', 'ig');

Expand Down
54 changes: 1 addition & 53 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,6 @@
"@testing-library/jest-dom": "^6.1.3",
"@testing-library/react": "^14.0.0",
"@testing-library/user-event": "^14.5.0",
"@vitalets/google-translate-api": "^9.0.0",
"crypto-js": "^4.1.1",
"env-cmd": "^10.1.0",
"https-proxy-agent": "^7.0.2",
Expand Down
1 change: 1 addition & 0 deletions rollup.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ const mainConfig = {
],
external: ['react', 'react-dom'],
plugins: [
// @ts-ignore
peerDepsExternal(),
nodeResolve(),
commonjs(),
Expand Down
10 changes: 7 additions & 3 deletions src/constants/index.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import language from '../types/language';

const { NODE_ENV, TRANSLATE_API_PROXY } = process.env;
const { NODE_ENV, TEST_TRANSLATE_API_PROXY } = process.env;

// NODE ENVIRONMENT
const NODE_DEVELOPMENT = 'development';
const NODE_TEST = 'test';
const IS_DEVELOPMENT_OR_TEST = NODE_ENV && [NODE_DEVELOPMENT, NODE_TEST].includes(NODE_ENV);

const PROXY = TRANSLATE_API_PROXY;
const PROXY_URL = 'https://react-g-translator-proxy.vercel.app/api';
const PROXY_URL_ALT = 'https://react-g-translator-proxy-express.onrender.com/translate';
const PROXY_URL_TEST = TEST_TRANSLATE_API_PROXY;

const DEFAULT_PROPS = {
from: 'en',
Expand Down Expand Up @@ -41,7 +43,9 @@ export {
NODE_DEVELOPMENT,
NODE_TEST,
IS_DEVELOPMENT_OR_TEST,
PROXY,
PROXY_URL,
PROXY_URL_ALT,
PROXY_URL_TEST,
DEFAULT_PROPS,
DEFAULT_QUERY_OPTIONS,
DEFAULT_LANGUAGE_FROM,
Expand Down
22 changes: 6 additions & 16 deletions src/utils/getTranslation.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,19 @@
import { translate } from '@vitalets/google-translate-api';
import { HttpsProxyAgent } from 'https-proxy-agent';
import throttle from 'lodash/throttle';

import chunkRequest from './chunkRequest';
import {
PROXY,
CHARACTER_LIMIT,
DEBOUNCE_RATE,
IS_DEVELOPMENT_OR_TEST,
} from '../constants';
import translate from './translate';

import { CHARACTER_LIMIT, DEBOUNCE_RATE } from '../constants';
import language from '../types/language';

const getTranslation = async (
text: string | string[],
from?: language,
to?: language,
) : Promise<string | undefined> => {
// opts for development / testing
// in case `TooManyRequestsError` or Error Code `429`
const fetchOptions = IS_DEVELOPMENT_OR_TEST && PROXY && { agent: new HttpsProxyAgent(PROXY) };

// translating happens here. ✨ bing! ✨
const translateRequest = async (chunk: string | string[]) => {
const translation = await translate(chunk as string, { from, to, fetchOptions });
return translation.text;
// translating happens here. ✨ bing! ✨
const translation = await translate(chunk as string, from, to);
return JSON.parse(translation)?.text ?? '';
};

return throttle(
Expand Down
62 changes: 62 additions & 0 deletions src/utils/translate.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import { HttpsProxyAgent } from 'https-proxy-agent';
import getErrorInTranslationMessage from './getErrorInTranslationMessage';
import {
IS_DEVELOPMENT_OR_TEST,
PROXY_URL,
PROXY_URL_ALT,
PROXY_URL_TEST,
} from '../constants';
import language from '../types/language';

const translate = async (text: string, from?: language, to?: language) => {
// option for development / testing
// in case of `TooManyRequestsError` (Error Code `429`)
const fetchOptions = (
IS_DEVELOPMENT_OR_TEST && PROXY_URL_TEST && { agent: new HttpsProxyAgent(PROXY_URL_TEST) }
);

let response;
try {
response = await fetch(PROXY_URL, {
credentials: 'omit',
mode: 'cors',
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(
{
text,
from,
to,
fetchOptions,
},
),
});
} catch (error) {
// If the first request failed, try with the second proxy
response = await fetch(PROXY_URL_ALT, {
credentials: 'omit',
mode: 'cors',
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(
{
text,
from,
to,
fetchOptions,
},
),
});
}

if (response.status === 200) return response.json();

const error = new Error(`${response.status} - ${response.statusText}`);
throw getErrorInTranslationMessage(error);
};

export default translate;

0 comments on commit a6e0b06

Please sign in to comment.