@science-and-humans/translation
v1.0.0
Published
NestJS library for Google Cloud Translation API integration
Downloads
4
Readme
@science-and-humans/translation
A versatile translation library for Google Cloud Translation API. Works seamlessly with both NestJS and plain Node.js applications.
Features
- 🌍 Text Translation: Translate text between 100+ languages
- 📦 Batch Translation: Efficiently translate multiple texts at once
- 🔍 Language Detection: Automatically detect the source language
- 📋 Supported Languages: Get list of all available languages
- 🎯 JSON Translation: Recursively translate JSON objects while preserving structure
- ⚡ Async/Promise-based: Built on modern async patterns
- 🔧 Dual Usage: Works in both NestJS and plain Node.js applications
- 🎨 NestJS Native: Fully integrated with NestJS dependency injection
- 🚀 Standalone Client: Use without any framework dependencies
- 🛡️ TypeScript: Full TypeScript support with type definitions
Installation
npm install @science-and-humans/translation @google-cloud/translateOr with yarn:
yarn add @science-and-humans/translation @google-cloud/translatePrerequisites
- Google Cloud Account with Translation API enabled
- Service Account Credentials JSON file
- NestJS Application (v10.x or higher)
Google Cloud Setup
- Go to Google Cloud Console
- Create a new project or select existing one
- Enable the Cloud Translation API
- Create a service account with "Cloud Translation API User" role
- Download the JSON credentials file
Quick Start
Choose your setup based on your application type:
Option 1: NestJS Application
1. Import the Module
import { Module } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';
import { TranslationModule } from '@science-and-humans/translation';
@Module({
imports: [
ConfigModule.forRoot({
isGlobal: true,
}),
TranslationModule,
],
})
export class AppModule {}2. Configure Environment Variables
Create a .env file:
GOOGLE_CLOUD_PROJECT_ID=your-project-id
GOOGLE_APPLICATION_CREDENTIALS=./path/to/credentials.json3. Use the Service
import { Injectable } from '@nestjs/common';
import { TranslationService } from '@science-and-humans/translation';
@Injectable()
export class MyService {
constructor(private readonly translationService: TranslationService) {}
async translateText() {
const result = await this.translationService.translateText('Hello, world!', {
from: 'en',
to: 'es',
});
console.log(result.translatedText); // "¡Hola, mundo!"
}
}Option 2: Plain Node.js Application
1. Install the Package
npm install @science-and-humans/translation2. Create a Client Instance
import { TranslationClient } from '@science-and-humans/translation';
// Create client with configuration
const translationClient = new TranslationClient({
projectId: 'your-project-id',
keyFilename: './path/to/credentials.json',
});
// Use the client
async function translate() {
const result = await translationClient.translateText('Hello, world!', {
from: 'en',
to: 'es',
});
console.log(result.translatedText); // "¡Hola, mundo!"
}
translate();3. JavaScript (CommonJS) Example
const { TranslationClient } = require('@science-and-humans/translation');
const client = new TranslationClient({
projectId: 'your-project-id',
keyFilename: './credentials.json',
});
async function main() {
const result = await client.translateText('Hello', { to: 'fr' });
console.log(result.translatedText); // "Bonjour"
}
main();Usage Examples
NestJS Examples
Basic Translation
// In a NestJS service
constructor(private translationService: TranslationService) {}
// Translate with explicit source language
const result = await this.translationService.translateText('Hello, world!', {
from: 'en',
to: 'es',
});
console.log(result.translatedText); // "¡Hola, mundo!"
console.log(result.originalText); // "Hello, world!"Node.js Examples
Basic Translation
import { TranslationClient } from '@science-and-humans/translation';
const client = new TranslationClient({
projectId: 'your-project-id',
keyFilename: './credentials.json',
});
// Translate with explicit source language
const result = await client.translateText('Hello, world!', {
from: 'en',
to: 'es',
});
console.log(result.translatedText); // "¡Hola, mundo!"
console.log(result.originalText); // "Hello, world!"Auto-Detect Source Language
// Works the same in both NestJS and Node.js
// Omit 'from' to auto-detect
const result = await client.translateText('Bonjour', {
to: 'en',
});
console.log(result.translatedText); // "Hello"
console.log(result.detectedSourceLanguage); // "fr"Batch Translation
const texts = ['Hello', 'Good morning', 'How are you?'];
const batchResult = await client.translateBatch(texts, {
from: 'en',
to: 'fr',
});
batchResult.translations.forEach((translation) => {
console.log(`${translation.originalText} → ${translation.translatedText}`);
});
// Output:
// Hello → Bonjour
// Good morning → Bonjour
// How are you? → Comment allez-vous?Language Detection
const detection = await client.detectLanguage('Hola, ¿cómo estás?');
console.log(detection.language); // "es"
console.log(detection.confidence); // 0.99Get Supported Languages
// Get languages in English
const languages = await client.getSupportedLanguages('en');
languages.forEach((lang) => {
console.log(`${lang.code}: ${lang.name}`);
});
// Output:
// af: Afrikaans
// sq: Albanian
// ar: Arabic
// ...Translate HTML Content
const htmlContent = '<p>Hello <strong>world</strong>!</p>';
const result = await client.translateText(htmlContent, {
from: 'en',
to: 'es',
format: 'html',
});
console.log(result.translatedText); // "<p>¡Hola <strong>mundo</strong>!</p>"Translate JSON Objects
const data = {
title: 'Welcome to our website',
description: 'This is a translation service',
features: ['Fast', 'Accurate', 'Reliable'],
price: 99.99,
metadata: {
category: 'Technology',
author: 'John Doe',
},
};
const result = await client.translateJson(
data,
{
from: 'en',
to: 'es',
},
['author'], // Exclude these keys from translation
10, // Max depth
);
console.log(result.translated);
// {
// title: "Bienvenido a nuestro sitio web",
// description: "Este es un servicio de traducción",
// features: ["Rápido", "Preciso", "Confiable"],
// price: 99.99,
// metadata: {
// category: "Tecnología",
// author: "John Doe" // Excluded from translation
// }
// }
console.log(result.translatedCount); // 5API Reference
Both TranslationService (for NestJS) and TranslationClient (for Node.js) provide the same methods with identical signatures.
Methods
translateText(text: string, options: TranslationOptions): Promise<TranslationResult>
Translate a single text.
Parameters:
text(string): The text to translateoptions(TranslationOptions):from?(string): Source language code (optional, auto-detect if not provided)to(string): Target language code (required)format?('text' | 'html'): Format of the text (default: 'text')
Returns: Promise<TranslationResult>
{
translatedText: string;
originalText: string;
detectedSourceLanguage?: string;
}translateBatch(texts: string[], options: TranslationOptions): Promise<BatchTranslationResult>
Translate multiple texts efficiently.
Parameters:
texts(string[]): Array of texts to translateoptions(TranslationOptions): Same astranslateText
Returns: Promise<BatchTranslationResult>
{
translations: TranslationResult[];
}detectLanguage(text: string): Promise<LanguageDetection>
Detect the language of a given text.
Parameters:
text(string): The text to detect language for
Returns: Promise<LanguageDetection>
{
language: string;
confidence: number;
}getSupportedLanguages(target?: string): Promise<SupportedLanguage[]>
Get a list of supported languages.
Parameters:
target?(string): Language code to get language names in that language
Returns: Promise<SupportedLanguage[]>
[
{
code: string;
name: string;
}
]translateJson(data: Record<string, any>, options: TranslationOptions, excludeKeys?: string[], maxDepth?: number): Promise<JsonTranslationResult>
Recursively translate all string values in a JSON object.
Parameters:
data(object): The JSON object to translateoptions(TranslationOptions): Translation optionsexcludeKeys?(string[]): Array of keys to exclude from translation (default: [])maxDepth?(number): Maximum recursion depth (default: 10)
Returns: Promise<JsonTranslationResult>
{
original: Record<string, any>;
translated: Record<string, any>;
translatedCount: number;
detectedSourceLanguage?: string;
}TypeScript Interfaces
interface TranslationOptions {
from?: string; // Source language code
to: string; // Target language code
format?: 'text' | 'html'; // Format type
}
interface TranslationResult {
translatedText: string;
originalText: string;
detectedSourceLanguage?: string;
}
interface BatchTranslationResult {
translations: TranslationResult[];
}
interface LanguageDetection {
language: string;
confidence: number;
}
interface SupportedLanguage {
code: string;
name: string;
}Common Language Codes
| Code | Language | |------|----------| | en | English | | es | Spanish | | fr | French | | de | German | | it | Italian | | pt | Portuguese | | ru | Russian | | ja | Japanese | | ko | Korean | | zh | Chinese (Simplified) | | zh-TW | Chinese (Traditional) | | ar | Arabic | | hi | Hindi |
For a complete list, use the getSupportedLanguages() method.
Configuration
Environment Variables
# Required
GOOGLE_CLOUD_PROJECT_ID=your-project-id
GOOGLE_APPLICATION_CREDENTIALS=./path/to/credentials.json
# Optional - if deploying to Google Cloud Platform
# Leave empty to use Application Default CredentialsCustom Configuration
If you need custom configuration, you can provide it when creating the module:
import { Module } from '@nestjs/common';
import { ConfigModule, ConfigService } from '@nestjs/config';
import { TranslationModule } from '@science-and-humans/translation';
@Module({
imports: [
ConfigModule.forRoot(),
TranslationModule,
],
})
export class AppModule {}The service will automatically read from ConfigService:
GOOGLE_CLOUD_PROJECT_IDGOOGLE_APPLICATION_CREDENTIALS
Error Handling
All methods throw errors that can be caught and handled:
try {
const result = await translationService.translateText('Hello', {
to: 'es',
});
console.log(result.translatedText);
} catch (error) {
console.error('Translation failed:', error.message);
// Handle error appropriately
}Use Cases
1. Multi-Language E-commerce
async translateProductCatalog(products: Product[], targetLang: string) {
for (const product of products) {
const translated = await this.translationService.translateJson(
product,
{ to: targetLang },
['id', 'sku', 'price', 'image_url'],
);
// Save translated product
await this.saveProduct(translated.translated, targetLang);
}
}2. Content Management System
async translateArticle(article: Article, languages: string[]) {
const translations = {};
for (const lang of languages) {
translations[lang] = await this.translationService.translateJson(
article,
{ from: 'en', to: lang },
['id', 'author', 'created_at', 'slug'],
);
}
return translations;
}3. Real-time Chat Translation
async translateMessage(message: string, targetLang: string) {
const result = await this.translationService.translateText(message, {
to: targetLang,
});
return {
original: message,
translated: result.translatedText,
sourceLang: result.detectedSourceLanguage,
};
}4. User-Generated Content
async moderateAndTranslate(comment: string) {
// Detect language
const detection = await this.translationService.detectLanguage(comment);
// Translate to English for moderation if needed
if (detection.language !== 'en') {
const result = await this.translationService.translateText(comment, {
from: detection.language,
to: 'en',
});
return result.translatedText;
}
return comment;
}Best Practices
Use Batch Translation: When translating multiple texts, use
translateBatch()for better performance and cost efficiency.Cache Results: Cache translations to reduce API calls:
const cacheKey = `${text}_${sourceLang}_${targetLang}`; let translation = await cache.get(cacheKey); if (!translation) { translation = await translationService.translateText(text, { from, to }); await cache.set(cacheKey, translation, 3600); // Cache for 1 hour }Handle Errors Gracefully: Always wrap translation calls in try-catch blocks.
Use Auto-Detection Wisely: Auto-detection is convenient but adds a small overhead. Use explicit source language when known.
Exclude Non-Translatable Fields: When using
translateJson(), exclude IDs, URLs, dates, and other non-translatable fields.Monitor Usage: Set up billing alerts in Google Cloud Console to monitor API usage.
Performance
- Single Translation: ~100-200ms per request
- Batch Translation: ~150-300ms for 10-100 texts (much more efficient)
- Language Detection: ~50-100ms per request
Actual performance depends on text length, network latency, and Google Cloud region.
Pricing
Google Cloud Translation API has usage-based pricing. Please refer to:
Security
⚠️ Important Security Notes:
- Never commit credentials: Keep your Google Cloud credentials file out of version control
- Use environment variables: Store sensitive configuration in environment variables
- Rotate keys regularly: Periodically regenerate your service account keys
- Principle of least privilege: Grant only necessary permissions to your service account
- Monitor usage: Enable audit logging and monitor for unusual activity
Development
Building the Library
npm run buildRunning Tests
npm testLinting
npm run lintContributing
Contributions are welcome! Please feel free to submit a Pull Request.
License
MIT License - see the LICENSE file for details.
Support
For issues, questions, or contributions:
- GitHub Issues: github.com/science-and-humans/translation/issues
- Email: [email protected]
Versioning
This project follows Semantic Versioning. See CHANGELOG.md for release history.
Version Management
The project uses automated semantic versioning with standard-version:
# Create a release (analyzes commits for version bump)
npm run release
# Or specify the bump type
npm run release:patch # Bug fixes
npm run release:minor # New features
npm run release:major # Breaking changesCommit Convention
We use Conventional Commits:
# Use interactive commit helper
npm run commit
# Or follow the format manually
git commit -m "feat: add new feature"
git commit -m "fix: correct bug"For more details, see VERSIONING.md and CONTRIBUTING.md.
Related Resources
Made with ❤️ by Science and Humans
