Skip to content

Commit

Permalink
chore: rate limiting fix on development environment
Browse files Browse the repository at this point in the history
  • Loading branch information
MiracleUFO committed Sep 25, 2023
1 parent 552c867 commit e1f6a45
Show file tree
Hide file tree
Showing 8 changed files with 77 additions and 105 deletions.
3 changes: 3 additions & 0 deletions .env.development
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
NODE_ENV='development'

TRANSLATE_API_PROXY=
117 changes: 20 additions & 97 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,109 +1,32 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*

# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json

# Runtime data
pids
*.pid
*.seed
*.pid.lock

# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov

# Coverage directory used by tools like istanbul
coverage
*.lcov

# nyc test coverage
.nyc_output

# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# Bower dependency directory (https://bower.io/)
bower_components
# dependencies
/node_modules
/.pnp
.pnp.js

# node-waf configuration
.lock-wscript

# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release

# Dependency directories
node_modules/
jspm_packages/
# dotenv environment variables file
.env.local
.env.development.local
.env.test.local
.env.production.local

# TypeScript v1 declaration files
typings/
# testing
/coverage

# TypeScript cache
*.tsbuildinfo
# production
/build
/dist

# Optional npm cache directory
.npm

# Optional eslint cache
.eslintcache

# Microbundle cache
.rpt2_cache/
.rts2_cache_cjs/
.rts2_cache_es/
.rts2_cache_umd/

# Optional REPL history
.node_repl_history

# Output of 'npm pack'
*.tgz

# Yarn Integrity file
.yarn-integrity

# dotenv environment variables file
.env
.env.test

# parcel-bundler cache (https://parceljs.org/)
.cache

# Next.js build output
.next

# Nuxt.js build / generate output
.nuxt
dist

# Gatsby files
.cache/
# Comment in the public line in if your project uses Gatsby and *not* Next.js
# https://nextjs.org/blog/next-9-1#public-directory-support
# public

# vuepress build output
.vuepress/dist

# Serverless directories
.serverless/

# FuseBox cache
.fusebox/

# DynamoDB Local files
.dynamodb/

# TernJS port file
.tern-port

.dccache
# misc
.DS_Store
lib
*.tgz

npm-debug.log*
yarn-debug.log*
yarn-error.log*
9 changes: 6 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -111,11 +111,14 @@ See [Usage](#to-get-translation-of-text-directly)
- [`to`](#props) *optional*


## SPECIAL CASES
## Special Cases

- [`from`](#props) and [`to`](#props) being the same will return original text (determined by google translation API.)
- [`from`](#props) and [`to`](#props) being empty strings will be extrapolated from 'en' and *user's current browser langauge setting* respectively.
- `text` is not in `from` language and google translate API cannot detect language automatically will return the original text.

## DEVELOPER TESTING
- Some tests in `src/tests` may fail because google translate API sometimes returns synonyms when a string is translated multiple times.
## Developer Testing
- [Install node-modules](#install)
- `npm run test` or `yarn run test`
- Some tests in `src/tests` may fail because google translate API might return synonyms when a string is translated multiple times.
- If `TooManyRequestsError` or Error Code `429` is encountered, update `env` variable `TRANSLATE_API_PROXY` with a correct [proxy](https://free-proxy-list.net/) (with yes in Google column.) This error is due to Google Translate APIs rate limiting per IP address (this limit seems variable, see [discussion](https://github.com/vitalets/google-translate-api/issues/107#issuecomment-1302220214))
24 changes: 24 additions & 0 deletions package-lock.json

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

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
"build:esm": "tsc -p ./configs/tsconfig.esm.json && mv build/esm/index.js build/esm/index.mjs",
"build:cjs": "tsc -p ./configs/tsconfig.cjs.json",
"semantic-release": "semantic-release",
"test": "react-scripts test",
"test": "env-cmd -f .env.local react-scripts test",
"prepack": "npm run build",
"lint": "eslint src --ext .js,.jsx,.tsx,.ts --fix"
},
Expand Down Expand Up @@ -97,6 +97,7 @@
"@testing-library/react": "^14.0.0",
"@testing-library/user-event": "^14.5.0",
"@vitalets/google-translate-api": "^9.0.0",
"env-cmd": "^10.1.0",
"https-proxy-agent": "^7.0.2",
"react": "^18.2.0",
"react-dom": "^18.2.0",
Expand Down
13 changes: 13 additions & 0 deletions src/constants/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
import language from '../types/language';

const { NODE_ENV, 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 DEFAULT_PROPS = {
from: 'en',
to: 'auto',
Expand All @@ -22,6 +31,10 @@ const DEFAULT_BROWSER_LANGUAGE : language = window?.navigator?.language.startsWi
const TRANSLATION_NOT_FOUND_MESSAGE = 'react-g-translator: Err 404: No translation found. Check `to` & `from` props.';

export {
NODE_DEVELOPMENT,
NODE_TEST,
IS_DEVELOPMENT_OR_TEST,
PROXY,
DEFAULT_PROPS,
DEFAULT_QUERY_OPTIONS,
DEFAULT_LANGUAGE_FROM,
Expand Down
2 changes: 0 additions & 2 deletions src/utils/chunkRequest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ const chunkRequest = async (
chunkSize: number = 0,
) => {
const promises = [];
const chunks = [];

for (let i = 0; i < text.length;) {
const endIndex = i + chunkSize;
Expand All @@ -13,7 +12,6 @@ const chunkRequest = async (
// to aid better translation
const endIndexFullSentence = (Math.min(endIndex, text.lastIndexOf('.', endIndex - 1) + 1) || endIndex);
const chunk = (text.slice(i, endIndexFullSentence));
chunks.push(chunk);
promises.push(translationReqFunc(chunk));

// afterthough: next index is the last translated full sentence endIndex
Expand Down
11 changes: 9 additions & 2 deletions src/utils/getTranslation.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,27 @@
import { translate } from '@vitalets/google-translate-api';
import { HttpsProxyAgent } from 'https-proxy-agent';

import chunkRequest from './chunkRequest';
import enableCors from './enableCorsAndLimitRate';

import { IS_DEVELOPMENT_OR_TEST, PROXY } from '../constants';
import language from '../types/language';

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

const translateRequest = async (chunk: string | string[]) => {
// CORS policy overriding (if any)
// CORS policy overriding
enableCors(1);

// translating happens here. ✨ bing! ✨
const translation = await translate(chunk as string, { from, to });
const translation = await translate(chunk as string, { from, to, fetchOptions });
return translation.text;
};

Expand Down

0 comments on commit e1f6a45

Please sign in to comment.