> ## Documentation Index
> Fetch the complete documentation index at: https://docs.insforge.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Referencia de SDK de Funciones

> Invoca funciones serverless con el SDK de TypeScript para InsForge

## Instalación

<CodeGroup>
  ```bash npm theme={null}
  npm install @insforge/sdk@latest
  ```

  ```bash yarn theme={null}
  yarn add @insforge/sdk@latest
  ```

  ```bash pnpm theme={null}
  pnpm add @insforge/sdk@latest
  ```
</CodeGroup>

```javascript theme={null}
import { createClient } from '@insforge/sdk';

const insforge = createClient({
  baseUrl: 'https://your-app.insforge.app',
  anonKey: 'your-anon-key'  // Optional: for public/unauthenticated requests
});
```

Find the anon key with `npx @insforge/cli secrets get ANON_KEY`, or in the dashboard: click **Install** and open **API Keys**.

## invoke()

Invoca una función serverless por slug.

### Parámetros

* `slug` (string, required) - Slug/nombre de la función
* `body` (any, optional) - Cuerpo de la solicitud (serializable en JSON)
* `headers` (object, optional) - Encabezados personalizados
* `method` ('GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE', optional) - Método HTTP (predeterminado: POST)

### Devoluciones

```typescript theme={null}
{
  data: any | null,  // Response from function
  error: Error | null
}
```

<Note>
  El SDK incluye automáticamente el token de autenticación del usuario que ha iniciado sesión.
</Note>

### Ejemplo (POST con cuerpo)

```javascript theme={null}
const { data, error } = await insforge.functions.invoke('hello-world', {
  body: { name: 'World', greeting: 'Hello' }
})

console.log(data)
```

### Salida (POST con cuerpo)

```json theme={null}
{
  "data": {
    "message": "Hello, World!",
    "timestamp": "2024-01-15T10:30:00Z"
  },
  "error": null
}
```

### Ejemplo (solicitud GET)

```javascript theme={null}
const { data, error } = await insforge.functions.invoke('get-stats', {
  method: 'GET'
})

console.log(data)
```

### Salida (solicitud GET)

```json theme={null}
{
  "data": {
    "posts": 500,
    "comments": 1200
  },
  "error": null
}
```

### Ejemplo (con encabezados personalizados)

```javascript theme={null}
const { data, error } = await insforge.functions.invoke('api-endpoint', {
  method: 'PUT',
  body: { id: '123', status: 'active' },
  headers: { 'X-Custom-Header': 'value' }
})
```

### Salida (con encabezados personalizados)

```json theme={null}
{
  "data": {
    "updated": true,
    "id": "123"
  },
  "error": null
}
```

## Ejemplos Completos de Funciones Serverless

### Ejemplo 1: Función Pública (No requiere autenticación)

```typescript theme={null}
import { createClient } from 'npm:@insforge/sdk';

export default async function(req: Request): Promise<Response> {
  const corsHeaders = {
    'Access-Control-Allow-Origin': '*',
    'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',
    'Access-Control-Allow-Headers': 'Content-Type, Authorization'
  };

  if (req.method === 'OPTIONS') {
    return new Response(null, { status: 204, headers: corsHeaders });
  }

  // Create client with anon token - no authentication needed
  const client = createClient({
    baseUrl: Deno.env.get('INSFORGE_BASE_URL'),
    anonKey: Deno.env.get('ANON_KEY')
  });

  // Access public data
  const { data, error } = await client.database
    .from('public_posts')
    .select('*')
    .limit(10);

  return new Response(JSON.stringify({ data }), {
    status: 200,
    headers: { ...corsHeaders, 'Content-Type': 'application/json' }
  });
}
```

### Ejemplo 2: Función Autenticada (Acceder a datos del usuario)

```typescript theme={null}
import { createClient } from 'npm:@insforge/sdk';

export default async function(req: Request): Promise<Response> {
  const corsHeaders = {
    'Access-Control-Allow-Origin': '*',
    'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',
    'Access-Control-Allow-Headers': 'Content-Type, Authorization'
  };

  if (req.method === 'OPTIONS') {
    return new Response(null, { status: 204, headers: corsHeaders });
  }

  // Extract token from request headers
  const authHeader = req.headers.get('Authorization');
  const userToken = authHeader ? authHeader.replace('Bearer ', '') : null;

  // Create client with user's token for authenticated access
  const client = createClient({
    baseUrl: Deno.env.get('INSFORGE_BASE_URL'),
    edgeFunctionToken: userToken
  });

  // Get authenticated user
  const { data: userData } = await client.auth.getCurrentUser();
  if (!userData?.user?.id) {
    return new Response(JSON.stringify({ error: 'Unauthorized' }), {
      status: 401,
      headers: { ...corsHeaders, 'Content-Type': 'application/json' }
    });
  }

  // Access user's private data or create records with user_id
  await client.database.from('user_posts').insert([{
    user_id: userData.user.id,
    content: 'My post'
  }]);

  return new Response(JSON.stringify({ success: true }), {
    status: 200,
    headers: { ...corsHeaders, 'Content-Type': 'application/json' }
  });
}
```
