# Gemini Generative AI

A TypeScript based npm package providing a type-safe interface for integrating Google Gemini API text generation into **React**, **Vue**, **Angular**, and other JavaScript Projects

## Installation

```
npm install gemini-genai
```

## Usage

### Basic Example (JavaScript/TypeScript)

```
import { generateText } from 'gemini-genai';

async function main() {
  const apiKey = process.env.GEMINI_API_KEY; // Use API key from .env

  if (!apiKey) {
    console.error("API key not found in .env.GEMINI_API_KEY");
    return;
  }

  const prompt = 'Tell me a short story about a cat.';

  try {
    const result = await generateText(apiKey, prompt);

    if (result.text) {
      console.log('Generated Text:', result.text);
    } else if (result.error) {
      console.error('Error:', result.error.message);
    }
  } catch (error) {
    console.error('An unexpected error occurred:', error);
  }
}

main();
```

**⚠️ Security Warning: Never expose your Google Gemini API key directly in client-side code for production applications. Use environment variables (`.env`) or a backend proxy to handle API requests.**

### Using with Vue 3

```
<template>
  <div>
    <input v-model="prompt" placeholder="Enter your prompt" />
    <button @click="handleGenerate">Generate Text</button>

    <div v-if="loading">Loading...</div>
    <div v-if="error">{{ error }}</div>
    <div v-if="textResult">{{ textResult }}</div>
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue';
import { generateText } from 'gemini-genai';

const prompt = ref('');
const textResult = ref<string | null>(null);
const error = ref<string | null>(null);
const loading = ref(false);
const apiKey = import.meta.env.VITE_GEMINI_API_KEY; // Use API key from .env (Vite)

const handleGenerate = async () => {
  loading.value = true;
  error.value = null;
  textResult.value = null;

  try {
    const result = await generateText(apiKey, prompt.value);

    if (result.text) {
      textResult.value = result.text;
    } else if (result.error) {
      error.value = result.error.message;
    }
  } catch (err) {
    error.value = 'An unexpected error occurred.';
    console.error(err);
  } finally {
    loading.value = false;
  }
};
</script>
```

### Using with React

```
import React, { useState } from 'react';
import { generateText } from 'gemini-genai';

function GenAiComponent() {
  const [prompt, setPrompt] = useState('');
  const [textResult, setTextResult] = useState(null);
  const [error, setError] = useState(null);
  const [loading, setLoading] = useState(false);
  const apiKey = process.env.REACT_APP_GEMINI_API_KEY; // Use API key from .env (React)

  const handleGenerate = async () => {
    setLoading(true);
    setError(null);
    setTextResult(null);

    try {
      const result = await generateText(apiKey, prompt);

      if (result.text) {
        setTextResult(result.text);
      } else if (result.error) {
        setError(result.error.message);
      }
    } catch (err) {
      setError('An unexpected error occurred.');
      console.error(err);
    } finally {
      setLoading(false);
    }
  };

  return (
    <div>
      <input value={prompt} onChange={(e) => setPrompt(e.target.value)} />
      <button onClick={handleGenerate}>Generate Text</button>

      {loading && <div>Loading...</div>}
      {error && <div>{error}</div>}
      {textResult && <div>{textResult}</div>}
    </div>
  );
}

export default GenAiComponent;
```

### Using with Angular

```
import { Component } from '@angular/core';
import { generateText } from 'gemini-genai';
import { environment } from '../environments/environment'; // Import environment variables

@Component({
  selector: 'app-gemini-genai',
  template: `
    <div>
      <input [(ngModel)]="prompt" placeholder="Enter your prompt" />
      <button (click)="handleGenerate()">Generate Text</button>

      <div *ngIf="loading">Loading...</div>
      <div *ngIf="error">{{ error }}</div>
      <div *ngIf="textResult">{{ textResult }}</div>
    </div>
  `,
})
export class GenAiComponent {
  prompt = '';
  textResult: string | null = null;
  error: string | null = null;
  loading = false;
  apiKey = environment.geminiApiKey; // Access API key from environment

  async handleGenerate() {
    this.loading = true;
    this.error = null;
    this.textResult = null;

    try {
      const result = await generateText(this.apiKey, this.prompt);

      if (result.text) {
        this.textResult = result.text;
      } else if (result.error) {
        this.error = result.error.message;
      }
    } catch (err) {
      this.error = 'An unexpected error occurred.';
      console.error(err);
    } finally {
      this.loading = false;
    }
  }
}
```

## API

```
generateText(apiKey: string, prompt: string): Promise<{ text: string | null; error: Error | null }>
```

- **apiKey**: Your Google Gemini API key (string).
- **prompt**: The Gemini API (string) text prompt.
- **Returns**: A promise that resolves to an object with `text` (generated text or `null`) and `error` (error object or `null`).

## Important Notes

- **API Key Security:** **Never expose your API key directly in client-side code for production applications.** Use environment variables (`.env`) or a backend proxy to handle API requests.
  - **Vue:** Use `import.meta.env.VITE_GEMINI_API_KEY` to access your API key from `.env`.
  - **React:** Use `process.env.REACT_APP_GEMINI_API_KEY` to access your API key from `.env`.
  - **Node.js/TypeScript:** Use `process.env.GEMINI_API_KEY` to access your API key from `.env`.
  - **Angular:** Use environment variables (`src/environments/environment.ts`).
- **Error Handling:** Implement robust error handling to handle API errors and network issues gracefully.
- **Loading States:** Manage loading states effectively to provide a good user experience.

## License

MIT
