Code Conversion Prompt Templates

AI prompt templates for converting code between languages. Translate Python to JavaScript, Java to Kotlin, and more.

Overview

Code conversion prompts help you translate code between programming languages while preserving functionality, idioms, and best practices. These templates handle common conversions like Python to JavaScript, Java to Kotlin, or legacy code modernization while addressing language-specific features and patterns.

Best Practices

1

Specify both source and target language versions (e.g. Python 3.10 to TypeScript 5.0)

2

Indicate whether you want a literal translation or idiomatic conversion using target language best practices

3

Mention any frameworks or libraries that should be used in the target language

4

Note any features in the source that don't have direct equivalents (e.g. Python decorators to JavaScript)

5

Include information about the runtime environment (Node.js, browser, Deno) for JavaScript/TypeScript conversions

Prompt Templates

1. Python to JavaScript/TypeScript Converter

Convert this Python code to [JavaScript/TypeScript]:

```python
[PYTHON_CODE]
```

Target environment: [ENVIRONMENT]
Module system: [ESM/CommonJS]
TypeScript strictness: [strict/normal] (if TypeScript)

Requirements:
- [REQUIREMENTS]

Preserve the same functionality and handle Python-specific features appropriately.
Convert this Python code to TypeScript:

```python
from dataclasses import dataclass
from typing import Optional, List
from datetime import datetime
import asyncio
import aiohttp

@dataclass
class User:
 id: int
 name: str
 email: str
 created_at: datetime
 roles: List[str]
 manager_id: Optional[int] = None

class UserService:
 def __init__(self, base_url: str, api_key: str):
 self.base_url = base_url
 self.api_key = api_key
 self._session: Optional[aiohttp.ClientSession] = None
 
 async def __aenter__(self):
 self._session = aiohttp.ClientSession(
 headers={"Authorization": f"Bearer {self.api_key}"}
 )
 return self
 
 async def __aexit__(self, *args):
 if self._session:
 await self._session.close()
 
 async def get_user(self, user_id: int) -> Optional[User]:
 async with self._session.get(f"{self.base_url}/users/{user_id}") as resp:
 if resp.status == 404:
 return None
 resp.raise_for_status()
 data = await resp.json()
 return User(**data)
 
 async def get_users_by_role(self, role: str) -> List[User]:
 async with self._session.get(
 f"{self.base_url}/users",
 params={"role": role}
 ) as resp:
 resp.raise_for_status()
 data = await resp.json()
 return [User(**u) for u in data]
 
 async def get_team(self, manager_id: int) -> List[User]:
 users = await self.get_users_by_role("employee")
 return [u for u in users if u.manager_id == manager_id]


async def main():
 async with UserService("https://api.example.com", "secret") as service:
 user = await service.get_user(123)
 if user:
 print(f"Found user: {user.name}")
 team = await service.get_team(user.id)
 print(f"Team size: {len(team)}")
```

Target environment: Node.js 20+
Module system: ESM
TypeScript strictness: strict

Requirements:
- Use native fetch (no axios)
- Use classes with proper TypeScript types
- Handle the async context manager pattern appropriately
```typescript
// types.ts
export interface User {
 id: number;
 name: string;
 email: string;
 createdAt: Date;
 roles: string[];
 managerId: number | null;
}

interface UserApiResponse {
 id: number;
 name: string;
 email: string;
 created_at: string;
 roles: string[];
 manager_id: number | null;
}

// userService.ts
export class UserService {
 private readonly baseUrl: string;
 private readonly apiKey: string;
 private abortController: AbortController | null = null;

 constructor(baseUrl: string, apiKey: string) {
 this.baseUrl = baseUrl;
 this.apiKey = apiKey;
 }

 /**
 * Creates a managed instance that auto-cleans up.
 * TypeScript equivalent of Python's async context manager.
 */
 static async withService<T>(
 baseUrl: string,
 apiKey: string,
 callback: (service: UserService) => Promise<T>
 ): Promise<T> {
 const service = new UserService(baseUrl, apiKey);
 try {
 return await callback(service);
 } finally {
 service.dispose();
 }
 }

 private get headers(): HeadersInit {
 return {
 'Authorization': `Bearer ${this.apiKey}`,
 'Content-Type': 'application/json',
 };
 }

 private createAbortController(): AbortController {
 this.abortController = new AbortController();
 return this.abortController;
 }

 dispose(): void {
 if (this.abortController) {
 this.abortController.abort();
 this.abortController = null;
 }
 }

 private parseUser(data: UserApiResponse): User {
 return {
 id: data.id,
 name: data.name,
 email: data.email,
 createdAt: new Date(data.created_at),
 roles: data.roles,
 managerId: data.manager_id,
 };
 }

 async getUser(userId: number): Promise<User | null> {
 const controller = this.createAbortController();
 
 const response = await fetch(
 `${this.baseUrl}/users/${userId}`,
 {
 headers: this.headers,
 signal: controller.signal,
 }
 );

 if (response.status === 404) {
 return null;
 }

 if (!response.ok) {
 throw new Error(`HTTP ${response.status}: ${response.statusText}`);
 }

 const data: UserApiResponse = await response.json();
 return this.parseUser(data);
 }

 async getUsersByRole(role: string): Promise<User[]> {
 const controller = this.createAbortController();
 const url = new URL(`${this.baseUrl}/users`);
 url.searchParams.set('role', role);

 const response = await fetch(url.toString(), {
 headers: this.headers,
 signal: controller.signal,
 });

 if (!response.ok) {
 throw new Error(`HTTP ${response.status}: ${response.statusText}`);
 }

 const data: UserApiResponse[] = await response.json();
 return data.map((u) => this.parseUser(u));
 }

 async getTeam(managerId: number): Promise<User[]> {
 const users = await this.getUsersByRole('employee');
 return users.filter((u) => u.managerId === managerId);
 }
}

// main.ts
async function main(): Promise<void> {
 await UserService.withService(
 'https://api.example.com',
 'secret',
 async (service) => {
 const user = await service.getUser(123);
 
 if (user) {
 console.log(`Found user: ${user.name}`);
 const team = await service.getTeam(user.id);
 console.log(`Team size: ${team.length}`);
 }
 }
 );
}

main().catch(console.error);
```

**Conversion Notes:**

1. **Dataclass → Interface**: Python's `@dataclass` becomes a TypeScript `interface`. Added a separate `UserApiResponse` for the API shape with snake_case.

2. **Async Context Manager → Static Factory**: Python's `async with` pattern converted to a `withService` static method that handles cleanup via callback.

3. **Optional → Union with null**: `Optional[int]` becomes `number | null`.

4. **aiohttp → fetch**: Native fetch with AbortController for cancellation support.

5. **Property naming**: Converted snake_case (`created_at`) to camelCase (`createdAt`) with explicit mapping in `parseUser`.

6. **Type assertions**: Used explicit typing on `response.json()` return values.

When migrating Python backend code to Node.js/TypeScript, especially async code with context managers, dataclasses, and type hints.

  • Python's async context managers don't have a direct JS equivalent, use try/finally, using() pattern, or callback wrappers
  • Map Python's snake_case to JavaScript's camelCase but keep API response types matching the actual API
  • Python's Optional[T] should become T | null, not T | undefined, for JSON compatibility

2. Java to Kotlin Converter

Convert this Java code to idiomatic Kotlin:

```java
[JAVA_CODE]
```

Kotlin version: [VERSION]
Target platform: [JVM/Android/Multiplatform]

Preferences:
- [PREFERENCES]

Make full use of Kotlin features like data classes, extension functions, null safety, and coroutines where appropriate.
Convert this Java code to idiomatic Kotlin:

```java
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;

public class OrderProcessor {
 private final OrderRepository orderRepository;
 private final PaymentService paymentService;
 private final NotificationService notificationService;
 
 public OrderProcessor(
 OrderRepository orderRepository,
 PaymentService paymentService,
 NotificationService notificationService) {
 this.orderRepository = orderRepository;
 this.paymentService = paymentService;
 this.notificationService = notificationService;
 }
 
 public CompletableFuture<ProcessingResult> processOrder(Order order) {
 return validateOrder(order)
.thenCompose(validOrder -> paymentService.charge(validOrder.getPaymentMethod(), validOrder.getTotal()))
.thenCompose(paymentResult -> {
 if (paymentResult.isSuccessful()) {
 order.setStatus(OrderStatus.PAID);
 order.setPaymentId(paymentResult.getTransactionId());
 return orderRepository.save(order)
.thenApply(savedOrder -> new ProcessingResult(true, savedOrder, null));
 } else {
 return CompletableFuture.completedFuture(
 new ProcessingResult(false, null, paymentResult.getErrorMessage()));
 }
 })
.thenCompose(result -> {
 if (result.isSuccess() && result.getOrder() != null) {
 return notificationService.sendOrderConfirmation(result.getOrder())
.thenApply(v -> result);
 }
 return CompletableFuture.completedFuture(result);
 })
.exceptionally(ex -> new ProcessingResult(false, null, ex.getMessage()));
 }
 
 private CompletableFuture<Order> validateOrder(Order order) {
 List<String> errors = new ArrayList<>();
 
 if (order.getItems() == null || order.getItems().isEmpty()) {
 errors.add("Order must have at least one item");
 }
 
 if (order.getShippingAddress() == null) {
 errors.add("Shipping address is required");
 }
 
 if (order.getPaymentMethod() == null) {
 errors.add("Payment method is required");
 }
 
 if (!errors.isEmpty()) {
 return CompletableFuture.failedFuture(
 new ValidationException(String.join(", ", errors)));
 }
 
 return CompletableFuture.completedFuture(order);
 }
 
 public List<OrderSummary> getOrderSummaries(List<Order> orders) {
 return orders.stream()
.filter(order -> order.getStatus() != OrderStatus.CANCELLED)
.map(order -> new OrderSummary(
 order.getId(),
 order.getCustomerName(),
 order.getTotal(),
 order.getStatus()))
.sorted(Comparator.comparing(OrderSummary::getTotal).reversed())
.collect(Collectors.toList());
 }
}

public class ProcessingResult {
 private final boolean success;
 private final Order order;
 private final String errorMessage;
 
 public ProcessingResult(boolean success, Order order, String errorMessage) {
 this.success = success;
 this.order = order;
 this.errorMessage = errorMessage;
 }
 
 public boolean isSuccess() { return success; }
 public Order getOrder() { return order; }
 public String getErrorMessage() { return errorMessage; }
}
```

Kotlin version: 1.9+
Target platform: JVM

Preferences:
- Use coroutines instead of CompletableFuture
- Use sealed classes for result types
- Prefer immutable data structures
```kotlin
import kotlinx.coroutines.*

// Sealed class for type-safe results
sealed class ProcessingResult {
 data class Success(val order: Order) : ProcessingResult()
 data class Failure(val errorMessage: String) : ProcessingResult()
}

// Data class replaces Java POJO
data class OrderSummary(
 val id: String,
 val customerName: String,
 val total: Double,
 val status: OrderStatus
)

class OrderProcessor(
 private val orderRepository: OrderRepository,
 private val paymentService: PaymentService,
 private val notificationService: NotificationService
) {
 suspend fun processOrder(order: Order): ProcessingResult {
 return try {
 // Validate
 validateOrder(order)
 
 // Process payment
 val paymentResult = paymentService.charge(
 order.paymentMethod,
 order.total
 )
 
 if (!paymentResult.isSuccessful) {
 return ProcessingResult.Failure(
 paymentResult.errorMessage ?: "Payment failed"
 )
 }
 
 // Update and save order
 val paidOrder = order.copy(
 status = OrderStatus.PAID,
 paymentId = paymentResult.transactionId
 )
 val savedOrder = orderRepository.save(paidOrder)
 
 // Send notification (fire and forget, but log errors)
 launch {
 runCatching {
 notificationService.sendOrderConfirmation(savedOrder)
 }.onFailure { e ->
 // Log but don't fail the order
 println("Failed to send confirmation: ${e.message}")
 }
 }
 
 ProcessingResult.Success(savedOrder)
 
 } catch (e: ValidationException) {
 ProcessingResult.Failure(e.message ?: "Validation failed")
 } catch (e: Exception) {
 ProcessingResult.Failure(e.message ?: "Unknown error")
 }
 }
 
 private fun validateOrder(order: Order) {
 val errors = buildList {
 if (order.items.isNullOrEmpty()) {
 add("Order must have at least one item")
 }
 if (order.shippingAddress == null) {
 add("Shipping address is required")
 }
 if (order.paymentMethod == null) {
 add("Payment method is required")
 }
 }
 
 if (errors.isNotEmpty()) {
 throw ValidationException(errors.joinToString(", "))
 }
 }
 
 fun getOrderSummaries(orders: List<Order>): List<OrderSummary> =
 orders
.filter { it.status != OrderStatus.CANCELLED }
.map { order ->
 OrderSummary(
 id = order.id,
 customerName = order.customerName,
 total = order.total,
 status = order.status
 )
 }
.sortedByDescending { it.total }
}

// Extension function for cleaner Result handling
inline fun <T> ProcessingResult.onSuccess(action: (Order) -> T): T? {
 return when (this) {
 is ProcessingResult.Success -> action(order)
 is ProcessingResult.Failure -> null
 }
}

inline fun ProcessingResult.onFailure(action: (String) -> Unit): ProcessingResult {
 if (this is ProcessingResult.Failure) {
 action(errorMessage)
 }
 return this
}

// Usage example
suspend fun main() = coroutineScope {
 val processor = OrderProcessor(
 orderRepository = InMemoryOrderRepository(),
 paymentService = StripePaymentService(),
 notificationService = EmailNotificationService()
 )
 
 val order = Order(
 id = "123",
 items = listOf(OrderItem("SKU-001", 2)),
 shippingAddress = Address("123 Main St"),
 paymentMethod = PaymentMethod.CreditCard("4111...")
 )
 
 when (val result = processor.processOrder(order)) {
 is ProcessingResult.Success -> {
 println("Order ${result.order.id} processed successfully")
 }
 is ProcessingResult.Failure -> {
 println("Order failed: ${result.errorMessage}")
 }
 }
}
```

**Key Kotlin Improvements:**

1. **Coroutines vs CompletableFuture**: `suspend fun` replaces `CompletableFuture<T>`, making async code sequential and readable.

2. **Sealed Classes**: `ProcessingResult` as a sealed class provides exhaustive `when` expressions and type-safe error handling.

3. **Data Classes**: `OrderSummary` is now a one-liner with auto-generated `equals`, `hashCode`, `copy`, etc.

4. **Null Safety**: Kotlin's `?` operator handles nulls explicitly. `isNullOrEmpty()` replaces verbose null checks.

5. **Collection Operations**: `buildList`, `sortedByDescending`, and `joinToString` are more idiomatic than Java streams.

6. **Expression Bodies**: Single-expression functions use `=` syntax.

7. **Extension Functions**: Added `onSuccess`/`onFailure` extensions for fluent result handling.

8. **Immutability**: Using `copy()` on data classes instead of setters.

When migrating Java codebases to Kotlin, especially Android projects or backend services looking to use Kotlin's conciseness and safety features.

  • Don't just translate line-by-line, Kotlin's idioms often combine multiple Java statements
  • Use sealed classes instead of boolean success flags for result types
  • Replace CompletableFuture chains with sequential suspend functions for readability

3. JavaScript to TypeScript Migration

Migrate this JavaScript code to TypeScript:

```javascript
[JAVASCRIPT_CODE]
```

TypeScript config:
- Strict mode: [yes/no]
- Target: [ES2020/ES2022/ESNext]

Context:
[CONTEXT_ABOUT_USAGE]

Add proper types, interfaces, and handle any implicit 'any' types. Preserve runtime behavior exactly.
Migrate this JavaScript code to TypeScript:

```javascript
const EventEmitter = require('events');

class DataLoader extends EventEmitter {
 constructor(options = {}) {
 super();
 this.cache = new Map();
 this.batchSize = options.batchSize || 100;
 this.batchDelay = options.batchDelay || 10;
 this.loader = options.loader;
 this.pendingKeys = [];
 this.pendingResolvers = new Map();
 this.batchTimeout = null;
 }

 async load(key) {
 // Return cached value if available
 if (this.cache.has(key)) {
 return this.cache.get(key);
 }

 // Check if already pending
 if (this.pendingResolvers.has(key)) {
 return this.pendingResolvers.get(key).promise;
 }

 // Create deferred promise
 let resolve, reject;
 const promise = new Promise((res, rej) => {
 resolve = res;
 reject = rej;
 });

 this.pendingResolvers.set(key, { promise, resolve, reject });
 this.pendingKeys.push(key);

 // Schedule batch
 this.scheduleBatch();

 return promise;
 }

 async loadMany(keys) {
 return Promise.all(keys.map(key => this.load(key)));
 }

 scheduleBatch() {
 if (this.batchTimeout) return;

 this.batchTimeout = setTimeout(() => {
 this.executeBatch();
 }, this.batchDelay);
 }

 async executeBatch() {
 this.batchTimeout = null;
 const keys = this.pendingKeys.splice(0, this.batchSize);
 
 if (keys.length === 0) return;

 this.emit('batch', { keys, count: keys.length });

 try {
 const results = await this.loader(keys);
 
 keys.forEach((key, index) => {
 const value = results[index];
 this.cache.set(key, value);
 
 const resolver = this.pendingResolvers.get(key);
 if (resolver) {
 resolver.resolve(value);
 this.pendingResolvers.delete(key);
 }
 });

 this.emit('loaded', { keys, results });
 } catch (error) {
 keys.forEach(key => {
 const resolver = this.pendingResolvers.get(key);
 if (resolver) {
 resolver.reject(error);
 this.pendingResolvers.delete(key);
 }
 });

 this.emit('error', { keys, error });
 }

 // Process remaining keys
 if (this.pendingKeys.length > 0) {
 this.scheduleBatch();
 }
 }

 clear(key) {
 if (key) {
 this.cache.delete(key);
 } else {
 this.cache.clear();
 }
 }

 prime(key, value) {
 this.cache.set(key, value);
 }
}

module.exports = { DataLoader };
```

TypeScript config:
- Strict mode: yes
- Target: ES2022

Context:
- This is a generic data batching/caching utility similar to Facebook's DataLoader
- Keys can be strings, numbers, or objects (need to be serializable)
- Values can be any type, determined by the loader function
- Used in GraphQL resolvers to batch database queries
```typescript
import { EventEmitter } from 'events';

// Generic types for flexible key and value types
export type BatchLoader<K, V> = (keys: K[]) => Promise<(V | Error)[]>;

export interface DataLoaderOptions<K, V> {
 batchSize?: number;
 batchDelay?: number;
 loader: BatchLoader<K, V>;
 cacheKeyFn?: (key: K) => string;
}

interface DeferredPromise<V> {
 promise: Promise<V>;
 resolve: (value: V) => void;
 reject: (reason: Error) => void;
}

// Event types for type-safe event handling
export interface DataLoaderEvents<K, V> {
 batch: { keys: K[]; count: number };
 loaded: { keys: K[]; results: (V | Error)[] };
 error: { keys: K[]; error: Error };
}

export class DataLoader<K = string, V = unknown> extends EventEmitter {
 private readonly cache: Map<string, V>;
 private readonly batchSize: number;
 private readonly batchDelay: number;
 private readonly loader: BatchLoader<K, V>;
 private readonly cacheKeyFn: (key: K) => string;
 private pendingKeys: K[];
 private readonly pendingResolvers: Map<string, DeferredPromise<V>>;
 private batchTimeout: ReturnType<typeof setTimeout> | null;

 constructor(options: DataLoaderOptions<K, V>) {
 super();
 this.cache = new Map();
 this.batchSize = options.batchSize ?? 100;
 this.batchDelay = options.batchDelay ?? 10;
 this.loader = options.loader;
 this.cacheKeyFn = options.cacheKeyFn ?? ((key: K) => String(key));
 this.pendingKeys = [];
 this.pendingResolvers = new Map();
 this.batchTimeout = null;
 }

 async load(key: K): Promise<V> {
 const cacheKey = this.cacheKeyFn(key);

 // Return cached value if available
 if (this.cache.has(cacheKey)) {
 return this.cache.get(cacheKey) as V;
 }

 // Check if already pending
 const existing = this.pendingResolvers.get(cacheKey);
 if (existing) {
 return existing.promise;
 }

 // Create deferred promise
 const deferred = this.createDeferredPromise<V>();

 this.pendingResolvers.set(cacheKey, deferred);
 this.pendingKeys.push(key);

 // Schedule batch
 this.scheduleBatch();

 return deferred.promise;
 }

 async loadMany(keys: K[]): Promise<(V | Error)[]> {
 const results = await Promise.allSettled(keys.map((key) => this.load(key)));
 
 return results.map((result) => {
 if (result.status === 'fulfilled') {
 return result.value;
 }
 return result.reason instanceof Error 
 ? result.reason 
 : new Error(String(result.reason));
 });
 }

 private createDeferredPromise<T>(): DeferredPromise<T> {
 let resolve!: (value: T) => void;
 let reject!: (reason: Error) => void;
 
 const promise = new Promise<T>((res, rej) => {
 resolve = res;
 reject = rej;
 });

 return { promise, resolve, reject };
 }

 private scheduleBatch(): void {
 if (this.batchTimeout !== null) return;

 this.batchTimeout = setTimeout(() => {
 void this.executeBatch();
 }, this.batchDelay);
 }

 private async executeBatch(): Promise<void> {
 this.batchTimeout = null;
 const keys = this.pendingKeys.splice(0, this.batchSize);

 if (keys.length === 0) return;

 this.emit('batch', { keys, count: keys.length });

 try {
 const results = await this.loader(keys);

 if (results.length !== keys.length) {
 throw new Error(
 `DataLoader must return the same number of results as keys. ` +
 `Expected ${keys.length}, got ${results.length}`
 );
 }

 keys.forEach((key, index) => {
 const cacheKey = this.cacheKeyFn(key);
 const value = results[index];

 const resolver = this.pendingResolvers.get(cacheKey);
 if (resolver) {
 if (value instanceof Error) {
 resolver.reject(value);
 } else {
 this.cache.set(cacheKey, value);
 resolver.resolve(value);
 }
 this.pendingResolvers.delete(cacheKey);
 }
 });

 this.emit('loaded', { keys, results });
 } catch (error) {
 const err = error instanceof Error ? error : new Error(String(error));
 
 keys.forEach((key) => {
 const cacheKey = this.cacheKeyFn(key);
 const resolver = this.pendingResolvers.get(cacheKey);
 if (resolver) {
 resolver.reject(err);
 this.pendingResolvers.delete(cacheKey);
 }
 });

 this.emit('error', { keys, error: err });
 }

 // Process remaining keys
 if (this.pendingKeys.length > 0) {
 this.scheduleBatch();
 }
 }

 clear(key?: K): void {
 if (key !== undefined) {
 const cacheKey = this.cacheKeyFn(key);
 this.cache.delete(cacheKey);
 } else {
 this.cache.clear();
 }
 }

 prime(key: K, value: V): void {
 const cacheKey = this.cacheKeyFn(key);
 this.cache.set(cacheKey, value);
 }

 // Type-safe event methods
 override on<E extends keyof DataLoaderEvents<K, V>>(
 event: E,
 listener: (payload: DataLoaderEvents<K, V>[E]) => void
 ): this {
 return super.on(event, listener);
 }

 override emit<E extends keyof DataLoaderEvents<K, V>>(
 event: E,
 payload: DataLoaderEvents<K, V>[E]
 ): boolean {
 return super.emit(event, payload);
 }
}

// Usage example with type inference
type User = { id: string; name: string };

const userLoader = new DataLoader<string, User>({
 loader: async (ids) => {
 // Batch fetch users from database
 const users = await db.users.findMany({ where: { id: { in: ids } } });
 // Return in same order as requested keys
 return ids.map(id => users.find(u => u.id === id) ?? new Error(`User ${id} not found`));
 },
 batchDelay: 16,
});

// Type-safe usage
const user = await userLoader.load('123'); // user: User
const users = await userLoader.loadMany(['1', '2', '3']); // users: (User | Error)[]
```

**Migration Notes:**

1. **Generic Types**: Added `<K, V>` generics for key and value types with sensible defaults.

2. **Required loader**: Made `loader` required in options (was implicitly required but not enforced).

3. **Cache key function**: Added `cacheKeyFn` option for complex key types (objects).

4. **Strict null checks**: Used `ReturnType<typeof setTimeout>` for timer type compatibility.

5. **Result validation**: Added check that loader returns same number of results as keys.

6. **Error handling**: Loader can now return `Error` instances for per-key failures.

7. **Type-safe events**: Overrode `on` and `emit` for typed event payloads.

When adding TypeScript to an existing JavaScript project, especially for complex classes with generics, event emitters, or deferred promises.

  • Use the definite assignment assertion (!) sparingly, only when you're certain the value will be assigned before use
  • Add generics with defaults so existing JS consumers don't need to specify types
  • Override EventEmitter methods for type-safe events instead of declaration merging

4. Legacy Code Modernization

Modernize this legacy [SOURCE_LANGUAGE] code to current [TARGET_VERSION] standards:

```[LANGUAGE]
[LEGACY_CODE]
```

Current patterns to adopt:
[MODERN_PATTERNS]

Constraints:
- [CONSTRAINTS]

Preserve all functionality while updating syntax and patterns to modern equivalents.
Modernize this legacy JavaScript code to current ES2023 standards:

```javascript
var UserManager = (function() {
 var users = [];
 var callbacks = {};
 
 function generateId() {
 return 'user_' + Date.now() + '_' + Math.random().toString(36).substr(2, 9);
 }
 
 function findUserIndex(id) {
 for (var i = 0; i < users.length; i++) {
 if (users[i].id === id) {
 return i;
 }
 }
 return -1;
 }
 
 return {
 addUser: function(name, email, role) {
 var user = {
 id: generateId(),
 name: name,
 email: email,
 role: role || 'user',
 createdAt: new Date(),
 active: true
 };
 users.push(user);
 this.trigger('userAdded', user);
 return user;
 },
 
 removeUser: function(id) {
 var index = findUserIndex(id);
 if (index !== -1) {
 var removed = users.splice(index, 1)[0];
 this.trigger('userRemoved', removed);
 return removed;
 }
 return null;
 },
 
 updateUser: function(id, updates) {
 var index = findUserIndex(id);
 if (index !== -1) {
 for (var key in updates) {
 if (updates.hasOwnProperty(key)) {
 users[index][key] = updates[key];
 }
 }
 users[index].updatedAt = new Date();
 this.trigger('userUpdated', users[index]);
 return users[index];
 }
 return null;
 },
 
 getUser: function(id) {
 var index = findUserIndex(id);
 return index !== -1 ? users[index] : null;
 },
 
 getUsers: function(filter) {
 if (!filter) return users.slice();
 
 return users.filter(function(user) {
 for (var key in filter) {
 if (filter.hasOwnProperty(key) && user[key] !== filter[key]) {
 return false;
 }
 }
 return true;
 });
 },
 
 on: function(event, callback) {
 if (!callbacks[event]) {
 callbacks[event] = [];
 }
 callbacks[event].push(callback);
 },
 
 off: function(event, callback) {
 if (callbacks[event]) {
 callbacks[event] = callbacks[event].filter(function(cb) {
 return cb !== callback;
 });
 }
 },
 
 trigger: function(event, data) {
 var self = this;
 if (callbacks[event]) {
 callbacks[event].forEach(function(callback) {
 setTimeout(function() {
 callback.call(self, data);
 }, 0);
 });
 }
 }
 };
})();
```

Current patterns to adopt:
- ES6+ class syntax
- Const/let instead of var
- Arrow functions where appropriate
- Template literals
- Destructuring
- Optional chaining and nullish coalescing
- Modern array methods
- Private class fields

Constraints:
- Must work in browsers (no Node.js-specific features)
- No external dependencies
- Maintain the same public API
```javascript
class UserManager {
 // Private fields (ES2022)
 #users = [];
 #callbacks = new Map();

 // Private method for ID generation
 #generateId() {
 return `user_${Date.now()}_${Math.random().toString(36).slice(2, 11)}`;
 }

 // Private method to find user
 #findUser(id) {
 return this.#users.find(user => user.id === id);
 }

 #findUserIndex(id) {
 return this.#users.findIndex(user => user.id === id);
 }

 addUser(name, email, role = 'user') {
 const user = {
 id: this.#generateId(),
 name,
 email,
 role,
 createdAt: new Date(),
 active: true,
 };
 
 this.#users.push(user);
 this.trigger('userAdded', user);
 return user;
 }

 removeUser(id) {
 const index = this.#findUserIndex(id);
 
 if (index === -1) return null;
 
 const [removed] = this.#users.splice(index, 1);
 this.trigger('userRemoved', removed);
 return removed;
 }

 updateUser(id, updates) {
 const user = this.#findUser(id);
 
 if (!user) return null;
 
 // Object.assign for cleaner property copying
 Object.assign(user, updates, { updatedAt: new Date() });
 this.trigger('userUpdated', user);
 return user;
 }

 getUser(id) {
 return this.#findUser(id) ?? null;
 }

 getUsers(filter) {
 if (!filter) return [...this.#users];
 
 // Convert filter to entries for cleaner comparison
 const filterEntries = Object.entries(filter);
 
 return this.#users.filter(user =>
 filterEntries.every(([key, value]) => user[key] === value)
 );
 }

 on(event, callback) {
 const listeners = this.#callbacks.get(event) ?? [];
 listeners.push(callback);
 this.#callbacks.set(event, listeners);
 
 // Return unsubscribe function (modern pattern)
 return () => this.off(event, callback);
 }

 off(event, callback) {
 const listeners = this.#callbacks.get(event);
 
 if (!listeners) return;
 
 const filtered = listeners.filter(cb => cb !== callback);
 
 if (filtered.length > 0) {
 this.#callbacks.set(event, filtered);
 } else {
 this.#callbacks.delete(event);
 }
 }

 trigger(event, data) {
 const listeners = this.#callbacks.get(event);
 
 listeners?.forEach(callback => {
 // queueMicrotask is more appropriate than setTimeout(0)
 queueMicrotask(() => callback(data));
 });
 }

 // Additional modern conveniences
 
 get count() {
 return this.#users.length;
 }

 get activeUsers() {
 return this.#users.filter(({ active }) => active);
 }

 // Make iterable
 *[Symbol.iterator]() {
 yield* this.#users;
 }

 // JSON serialization
 toJSON() {
 return [...this.#users];
 }
}

// Singleton export pattern (maintains backward compatibility)
const userManager = new UserManager();

// Usage examples:
// const user = userManager.addUser('John', 'john@example.com');
// const unsubscribe = userManager.on('userUpdated', (user) => console.log(user));
// userManager.updateUser(user.id, { name: 'John Doe' });
// unsubscribe();
// 
// // Iterate all users
// for (const user of userManager) {
// console.log(user.name);
// }

export { UserManager, userManager };
```

**Modernization Changes:**

| Legacy Pattern | Modern Equivalent |
|---------------|------------------|
| IIFE module | ES6 class with private fields |
| `var` | `const`/`let` |
| `function()` callbacks | Arrow functions |
| `for` loops | `find()`, `findIndex()`, `filter()` |
| `for...in` with hasOwnProperty | `Object.entries()` + `every()` |
| String concatenation | Template literals |
| `\|\|` for defaults | Default parameters, `??` |
| `setTimeout(fn, 0)` | `queueMicrotask()` |
| Manual object copy | `Object.assign()` |
| `.slice()` for copy | Spread `[...array]` |
| Object as map | `Map` |
| `.substr()` | `.slice()` (substr is deprecated) |

**New Features Added:**
- `on()` returns unsubscribe function
- `count` and `activeUsers` getters
- `Symbol.iterator` for `for...of` loops
- `toJSON()` for JSON.stringify support

When updating legacy JavaScript (ES5, jQuery-era code) to modern standards while maintaining backward compatibility with existing consumers.

  • Private class fields (#) are well-supported now, use them instead of closure-based privacy
  • queueMicrotask() is better than setTimeout(0) for deferring synchronous callbacks
  • Return unsubscribe functions from event subscriptions, it's the modern pattern

5. SQL Dialect Converter

Convert this [SOURCE_SQL] query to [TARGET_SQL]:

```sql
[SQL_QUERY]
```

Target database version: [VERSION]

Additional requirements:
- [REQUIREMENTS]

Handle syntax differences, function mappings, and any dialect-specific features.
Convert this MySQL query to PostgreSQL:

```sql
SELECT 
 u.id,
 u.username,
 u.email,
 GROUP_CONCAT(DISTINCT r.name ORDER BY r.name SEPARATOR ', ') AS roles,
 COUNT(DISTINCT o.id) AS order_count,
 IFNULL(SUM(o.total), 0) AS lifetime_value,
 DATE_FORMAT(u.created_at, '%Y-%m-%d') AS join_date,
 DATEDIFF(NOW(), u.last_login) AS days_since_login
FROM users u
LEFT JOIN user_roles ur ON u.id = ur.user_id
LEFT JOIN roles r ON ur.role_id = r.id
LEFT JOIN orders o ON u.id = o.user_id 
 AND o.status IN ('completed', 'shipped')
 AND o.created_at >= DATE_SUB(NOW(), INTERVAL 1 YEAR)
WHERE u.active = 1
 AND u.email REGEXP '^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$'
GROUP BY u.id, u.username, u.email, u.created_at, u.last_login
HAVING order_count > 0 OR roles LIKE '%admin%'
ORDER BY lifetime_value DESC
LIMIT 100 OFFSET 20;
```

Target database version: PostgreSQL 15

Additional requirements:
- Use modern PostgreSQL syntax
- Optimize for performance where possible
```sql
SELECT 
 u.id,
 u.username,
 u.email,
 -- GROUP_CONCAT → STRING_AGG with DISTINCT and ORDER BY
 STRING_AGG(DISTINCT r.name, ', ' ORDER BY r.name) AS roles,
 COUNT(DISTINCT o.id) AS order_count,
 -- IFNULL → COALESCE (ANSI standard)
 COALESCE(SUM(o.total), 0) AS lifetime_value,
 -- DATE_FORMAT → TO_CHAR
 TO_CHAR(u.created_at, 'YYYY-MM-DD') AS join_date,
 -- DATEDIFF → DATE subtraction (returns interval, extract days)
 EXTRACT(DAY FROM (NOW() - u.last_login))::INTEGER AS days_since_login
FROM users u
LEFT JOIN user_roles ur ON u.id = ur.user_id
LEFT JOIN roles r ON ur.role_id = r.id
LEFT JOIN orders o ON u.id = o.user_id 
 AND o.status IN ('completed', 'shipped')
 -- DATE_SUB → INTERVAL subtraction
 AND o.created_at >= NOW() - INTERVAL '1 year'
-- WHERE active = 1 → PostgreSQL boolean or explicit comparison
WHERE u.active = TRUE
 -- REGEXP → ~ operator (POSIX regex)
 AND u.email ~ '^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$'
GROUP BY u.id, u.username, u.email, u.created_at, u.last_login
-- Can reference aliases in HAVING in PostgreSQL
HAVING COUNT(DISTINCT o.id) > 0 
 OR STRING_AGG(DISTINCT r.name, ', ' ORDER BY r.name) LIKE '%admin%'
ORDER BY lifetime_value DESC
LIMIT 100 OFFSET 20;
```

**Optimized Version with CTEs:**

```sql
-- Using CTEs for better readability and potential optimization
WITH user_orders AS (
 SELECT 
 user_id,
 COUNT(*) AS order_count,
 SUM(total) AS lifetime_value
 FROM orders
 WHERE status IN ('completed', 'shipped')
 AND created_at >= NOW() - INTERVAL '1 year'
 GROUP BY user_id
),
user_roles_agg AS (
 SELECT 
 ur.user_id,
 STRING_AGG(DISTINCT r.name, ', ' ORDER BY r.name) AS roles
 FROM user_roles ur
 JOIN roles r ON ur.role_id = r.id
 GROUP BY ur.user_id
)
SELECT 
 u.id,
 u.username,
 u.email,
 COALESCE(ura.roles, '') AS roles,
 COALESCE(uo.order_count, 0) AS order_count,
 COALESCE(uo.lifetime_value, 0) AS lifetime_value,
 TO_CHAR(u.created_at, 'YYYY-MM-DD') AS join_date,
 EXTRACT(DAY FROM (NOW() - u.last_login))::INTEGER AS days_since_login
FROM users u
LEFT JOIN user_roles_agg ura ON u.id = ura.user_id
LEFT JOIN user_orders uo ON u.id = uo.user_id
WHERE u.active = TRUE
 AND u.email ~ '^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$'
 AND (uo.order_count > 0 OR ura.roles LIKE '%admin%')
ORDER BY lifetime_value DESC
LIMIT 100 OFFSET 20;
```

**Conversion Reference:**

| MySQL | PostgreSQL | Notes |
|-------|------------|-------|
| `GROUP_CONCAT(x SEPARATOR ',')` | `STRING_AGG(x, ',')` | ORDER BY goes inside STRING_AGG |
| `IFNULL(x, y)` | `COALESCE(x, y)` | COALESCE is ANSI standard |
| `DATE_FORMAT(d, '%Y-%m-%d')` | `TO_CHAR(d, 'YYYY-MM-DD')` | Different format codes |
| `DATEDIFF(d1, d2)` | `d1 - d2` or `EXTRACT(DAY FROM (d1 - d2))` | Returns interval by default |
| `DATE_SUB(d, INTERVAL n UNIT)` | `d - INTERVAL 'n unit'` | Quoted interval syntax |
| `REGEXP 'pattern'` | `~ 'pattern'` | POSIX regex operator |
| `= 1` (boolean) | `= TRUE` or `IS TRUE` | PostgreSQL has real booleans |
| `LIMIT m OFFSET n` | `LIMIT m OFFSET n` | Same syntax (also supports `LIMIT m, n` → must convert) |

When migrating databases between different SQL dialects (MySQL to PostgreSQL, SQL Server to MySQL, etc.) or when writing queries that need to work across multiple database systems.

  • CTEs (WITH clauses) often perform better in PostgreSQL than complex joins with aggregates
  • PostgreSQL's regex operator (~) is case-sensitive; use ~* for case-insensitive
  • Always test converted queries with EXPLAIN ANALYZE to verify performance

Common Mistakes to Avoid

Translating code literally without adopting target language idioms, resulting in 'Python written in JavaScript' style code

Missing null/optional handling differences, Python's None, JavaScript's null/undefined, and Kotlin's null-safety all behave differently

Ignoring async model differences, Python's asyncio, JavaScript's event loop, and Kotlin's coroutines have different patterns

Frequently Asked Questions

Code conversion prompts help you translate code between programming languages while preserving functionality, idioms, and best practices. These templates handle common conversions like Python to JavaScript, Java to Kotlin, or legacy code modernization while addressing language-specific features and patterns.

Related Templates

Have your own prompt to optimize?