diff --git a/README.md b/README.md index cfdf880..83cb4dc 100644 --- a/README.md +++ b/README.md @@ -65,15 +65,15 @@ translate(text, options) .catch(console.error); ``` -| Parameter | Type | Optional | Default | Description | -|-------------------|--------------------|----------|----------|----------------------------------------------------------------------------------------------------------------| -| `text` | `string` | No | - | Source text, phrase or word. | -| `options` | `TranslateOptions` | - | - | The options for translating. | -| `options.from` | `LanguageCode` | Yes | `'auto'` | The language name/ISO 639-1 code to translate from. If none is given, it will auto-detect the source language. | -| `options.to` | `LanguageCode` | Yes | `'auto'` | The language name/ISO 639-1 code to translate to. If none is given, it will translate to English. | -| `options.raw` | `boolean` | Yes | `false` | If `true`, it will return the raw output that was received from Google Translation Api. | -| `options.timeout` | `number` | Yes | `30_000` | Timeout duration for the translation request in milliseconds. | -| `options.retry` | `number` | Yes | `0` | Retry attempts for the translation request in case of failure. | +| Parameter | Type | Optional | Default | Description | +|-------------------|------------------------------------|----------|----------|----------------------------------------------------------------------------------------------------------------| +| `text` | `string` | No | - | Source text, phrase or word. | +| `options` | `TranslateOptions` | - | - | The options for translating. | +| `options.from` | `LanguageCode`, `auto` or `string` | Yes | `'auto'` | The language name/ISO 639-1 code to translate from. If none is given, it will auto-detect the source language. | +| `options.to` | `LanguageCode`, `auto` or `string` | Yes | `'auto'` | The language name/ISO 639-1 code to translate to. If none is given, it will translate to English. | +| `options.raw` | `boolean` | Yes | `false` | If `true`, it will return the raw output that was received from Google Translation Api. | +| `options.timeout` | `number` | Yes | `30_000` | Timeout duration for the translation request in milliseconds. | +| `options.retry` | `number` | Yes | `0` | Retry attempts for the translation request in case of failure. | #### Returns: `Promise` @@ -216,6 +216,20 @@ translate('例子', { to: 'en' }).then(res => { }); ``` +#### Using language name and capitalized correction + +[View Case](example/language.ts) + +```javascript +import translate from '@kabeep/node-translate'; + +// Language name and capitalized correction +translate('例子', { to: 'ENGlish' }).then(res => { + // => example + console.log(res.text); +}); +``` + #### Adaptive translation [View Case](example/detection.ts) diff --git a/README.zh-CN.md b/README.zh-CN.md index 7b1c2fb..a665eba 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -213,6 +213,20 @@ translate('例子', { to: 'en' }).then(res => { }); ``` +#### 使用语言名和大小写修正 + +[View Case](example/language.ts) + +```javascript +import translate from '@kabeep/node-translate'; + +// Language name and capitalized correction +translate('例子', { to: 'ENGlish' }).then(res => { + // => example + console.log(res.text); +}); +``` + #### 自适应翻译 [查看用例](example/detection.ts) diff --git a/example/language.ts b/example/language.ts new file mode 100644 index 0000000..4e9cde1 --- /dev/null +++ b/example/language.ts @@ -0,0 +1,7 @@ +import translate from '../src/index.js'; + +// Language name and capitalized correction +translate('例子', { to: 'ENGlish' }).then(res => { + // => example + console.log(res.text); +}); diff --git a/src/core/iso-639-1-x.ts b/src/core/iso-639-1-x.ts index 74df2e4..0780fd3 100644 --- a/src/core/iso-639-1-x.ts +++ b/src/core/iso-639-1-x.ts @@ -34,7 +34,7 @@ class Iso6391X { * @returns {string} - The name of the language. */ getName(code: string) { - return additionalCodes[code as AdditionalCode]?.name ?? iso6391.getName(code); + return additionalCodes[code.toString() as AdditionalCode]?.name ?? iso6391.getName(code); } /** @@ -51,7 +51,7 @@ class Iso6391X { * @returns {string} - The native name of the language. */ getNativeName(code: string) { - return additionalCodes[code as AdditionalCode]?.nativeName ?? iso6391.getNativeName(code); + return additionalCodes[code.toString() as AdditionalCode]?.nativeName ?? iso6391.getNativeName(code); } /** @@ -68,8 +68,8 @@ class Iso6391X { * @returns {LanguageCode */ getCode(name: string) { - const additionalNames = Object.values(additionalCodes).map((option) => option.name); - const matchIndex = additionalNames.indexOf(name as AdditionalName); + const additionalNames = Object.values(additionalCodes).map((option) => option.name.toLowerCase()); + const matchIndex = additionalNames.indexOf(name.toLowerCase() as AdditionalName); return (Object.keys(additionalCodes)[matchIndex] ?? iso6391.getCode(name)) as LanguageCode; } @@ -91,7 +91,7 @@ class Iso6391X { const [googleLanguages, isoCodes] = [[], []] as [LanguageOption[], string[]]; for (const code of codes) { - if (has(additionalCodes, code)) { + if (has(additionalCodes, code.toLowerCase())) { googleLanguages.push({ code: code as LanguageCode, ...(additionalCodes as Record)[code], @@ -119,7 +119,7 @@ class Iso6391X { * @returns {boolean} - True if the code is valid, false otherwise. */ validate(code: string) { - return iso6391.validate(code) || has(additionalCodes, code); + return iso6391.validate(code) || has(additionalCodes, code.toLowerCase()); } } diff --git a/src/core/translate.ts b/src/core/translate.ts index 0312042..bbeac38 100644 --- a/src/core/translate.ts +++ b/src/core/translate.ts @@ -1,7 +1,6 @@ import { request, type RequestOptions } from '../api/index.js'; -import { getLocale } from '../helper/index.js'; +import { getCode } from '../helper/index.js'; import parse from './parse.js'; -import validate from './validate.js'; /** * Represents options for translating text. @@ -20,17 +19,10 @@ async function translate( text: string, { from = 'auto', to = 'auto', timeout, retry, raw: rawEnabled = false }: TranslateOptions = {}, ) { - from ??= 'auto'; - to = !to || to === 'auto' ? getLocale() : to; - + from = getCode(from); + to = getCode(to, true); text = String(text); - // Check if a language is in supported; if not, throw an error object. - const isValidated = validate(to) && validate(from); - if (!isValidated) { - throw new Error('EVALIDATION'); - } - const response = await request({ from, to, text, timeout, retry }); const data = parse(response); diff --git a/src/helper/get-code.ts b/src/helper/get-code.ts new file mode 100644 index 0000000..6edbd39 --- /dev/null +++ b/src/helper/get-code.ts @@ -0,0 +1,21 @@ +import { iso6391X } from '../core/index.js'; +import validate from '../core/validate.js'; +import getLocale from './get-locale.js'; + +function getCode(codeOrLang?: string, adaptive = false) { + if (!codeOrLang || codeOrLang === 'auto') return adaptive ? getLocale() : 'auto'; + + codeOrLang = codeOrLang.toLowerCase(); + + // Check if a language is in supported; if not, throw an error object. + const isValidated = validate(codeOrLang); + if (isValidated) return codeOrLang; + + // Using Language code from supported name + const code = iso6391X.getCode(codeOrLang); + if (code) return code; + + throw new Error('EVALIDATION'); +} + +export default getCode; diff --git a/src/helper/index.ts b/src/helper/index.ts index 8c6ef8a..b942ab7 100644 --- a/src/helper/index.ts +++ b/src/helper/index.ts @@ -1,2 +1,3 @@ +export { default as getCode } from './get-code.js'; export { default as getLocale } from './get-locale.js'; export { default as mutable, type Mutable } from './mutable.js'; diff --git a/src/shared/additional-codes.constant.ts b/src/shared/additional-codes.constant.ts index 344ffd4..5f8211d 100644 --- a/src/shared/additional-codes.constant.ts +++ b/src/shared/additional-codes.constant.ts @@ -14,11 +14,11 @@ const additionalCodes = { nativeName: 'Cebuan', }, 'zh-cn': { - name: 'Chinese (Simplified)', + name: 'Chinese Simplified', nativeName: '简体中文', }, 'zh-tw': { - name: 'Chinese (Traditional)', + name: 'Chinese Traditional', nativeName: '簡體中文', }, doi: { diff --git a/test/helper/get-code.spec.ts b/test/helper/get-code.spec.ts new file mode 100644 index 0000000..bb977d4 --- /dev/null +++ b/test/helper/get-code.spec.ts @@ -0,0 +1,38 @@ +import { expect, test } from 'vitest'; +import getCode from '../../src/helper/get-code'; +import getLocale from '../../src/helper/get-locale'; + +test('getCode - should return "auto" when no code or language is provided and adaptive is false', () => { + const result = getCode(undefined, false); + expect(result).toBe('auto'); +}); + +test('getCode - should return the locale when no code or language is provided and adaptive is true', () => { + const result = getCode(undefined, true); + const expected = getLocale(); + expect(result).toBe(expected); +}); + +test('getCode - should return the provided code when it is a valid language code', () => { + const result = getCode('en'); + expect(result).toBe('en'); +}); + +test('getCode - should return the provided code when it is a valid language code (uppercase)', () => { + const result = getCode('EN'); + expect(result).toBe('en'); +}); + +test('getCode - should return the provided code when it is a valid language code (mixed case)', () => { + const result = getCode('eN'); + expect(result).toBe('en'); +}); + +test('getCode - should return the provided language code when it is a valid language name', () => { + const result = getCode('English'); + expect(result).toBe('en'); +}); + +test('getCode - should throw an error when the provided code is not valid', () => { + expect(() => getCode('invalid')).toThrowError('EVALIDATION'); +});