npm package: @science-and-humans/translation
Description: NestJS library for Google Cloud Translation API integration
Author: Science and Humans
Latest version: 1.0.0

# @science-and-humans/translation

A versatile translation library for Google Cloud Translation API. Works seamlessly with both **NestJS** and **plain Node.js** applications.

[![npm version](https://img.shields.io/npm/v/@science-and-humans/translation.svg)](https://www.npmjs.com/package/@science-and-humans/translation)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

## 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

```bash
npm install @science-and-humans/translation @google-cloud/translate
```

Or with yarn:

```bash
yarn add @science-and-humans/translation @google-cloud/translate
```

## Prerequisites

1. **Google Cloud Account** with Translation API enabled
2. **Service Account Credentials** JSON file
3. **NestJS Application** (v10.x or higher)

### Google Cloud Setup

1. Go to [Google Cloud Console](https://console.cloud.google.com/)
2. Create a new project or select existing one
3. Enable the **Cloud Translation API**
4. Create a service account with "Cloud Translation API User" role
5. Download the JSON credentials file

## Quick Start

Choose your setup based on your application type:

### Option 1: NestJS Application

#### 1. Import the Module

```typescript
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:

```env
GOOGLE_CLOUD_PROJECT_ID=your-project-id
GOOGLE_APPLICATION_CREDENTIALS=./path/to/credentials.json
```

#### 3. Use the Service

```typescript
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

```bash
npm install @science-and-humans/translation
```

#### 2. Create a Client Instance

```typescript
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

```javascript
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

```typescript
// 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

```typescript
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

```typescript
// 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

```typescript
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

```typescript
const detection = await client.detectLanguage('Hola, ¿cómo estás?');

console.log(detection.language); // "es"
console.log(detection.confidence); // 0.99
```

#### Get Supported Languages

```typescript
// 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

```typescript
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

```typescript
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); // 5
```

## API 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 translate
- `options` (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>`
```typescript
{
  translatedText: string;
  originalText: string;
  detectedSourceLanguage?: string;
}
```

#### `translateBatch(texts: string[], options: TranslationOptions): Promise<BatchTranslationResult>`

Translate multiple texts efficiently.

**Parameters:**
- `texts` (string[]): Array of texts to translate
- `options` (TranslationOptions): Same as `translateText`

**Returns:** `Promise<BatchTranslationResult>`
```typescript
{
  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>`
```typescript
{
  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[]>`
```typescript
[
  {
    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 translate
- `options` (TranslationOptions): Translation options
- `excludeKeys?` (string[]): Array of keys to exclude from translation (default: [])
- `maxDepth?` (number): Maximum recursion depth (default: 10)

**Returns:** `Promise<JsonTranslationResult>`
```typescript
{
  original: Record<string, any>;
  translated: Record<string, any>;
  translatedCount: number;
  detectedSourceLanguage?: string;
}
```

## TypeScript Interfaces

```typescript
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

```env
# 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 Credentials
```

### Custom Configuration

If you need custom configuration, you can provide it when creating the module:

```typescript
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_ID`
- `GOOGLE_APPLICATION_CREDENTIALS`

## Error Handling

All methods throw errors that can be caught and handled:

```typescript
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

```typescript
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

```typescript
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

```typescript
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

```typescript
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

1. **Use Batch Translation**: When translating multiple texts, use `translateBatch()` for better performance and cost efficiency.

2. **Cache Results**: Cache translations to reduce API calls:
   ```typescript
   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
   }
   ```

3. **Handle Errors Gracefully**: Always wrap translation calls in try-catch blocks.

4. **Use Auto-Detection Wisely**: Auto-detection is convenient but adds a small overhead. Use explicit source language when known.

5. **Exclude Non-Translatable Fields**: When using `translateJson()`, exclude IDs, URLs, dates, and other non-translatable fields.

6. **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:
- [Google Cloud Translation Pricing](https://cloud.google.com/translate/pricing)
- [Quotas and Limits](https://cloud.google.com/translate/quotas)

## Security

⚠️ **Important Security Notes:**

1. **Never commit credentials**: Keep your Google Cloud credentials file out of version control
2. **Use environment variables**: Store sensitive configuration in environment variables
3. **Rotate keys regularly**: Periodically regenerate your service account keys
4. **Principle of least privilege**: Grant only necessary permissions to your service account
5. **Monitor usage**: Enable audit logging and monitor for unusual activity

## Development

### Building the Library

```bash
npm run build
```

### Running Tests

```bash
npm test
```

### Linting

```bash
npm run lint
```

## Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

## License

MIT License - see the [LICENSE](LICENSE) file for details.

## Support

For issues, questions, or contributions:
- GitHub Issues: [github.com/science-and-humans/translation/issues](https://github.com/science-and-humans/translation/issues)
- Email: contact@scienceandhumans.com

## Versioning

This project follows [Semantic Versioning](https://semver.org/). See [CHANGELOG.md](./CHANGELOG.md) for release history.

### Version Management

The project uses automated semantic versioning with `standard-version`:

```bash
# 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 changes
```

### Commit Convention

We use [Conventional Commits](https://www.conventionalcommits.org/):

```bash
# 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](./VERSIONING.md) and [CONTRIBUTING.md](./CONTRIBUTING.md).

## Related Resources

- [Google Cloud Translation API Documentation](https://cloud.google.com/translate/docs)
- [NestJS Documentation](https://docs.nestjs.com)
- [TypeScript Documentation](https://www.typescriptlang.org/docs)

---

Made with ❤️ by [Science and Humans](https://scienceandhumans.com)