# @agroshine/ags-web-http

Cliente HTTP centralizado para todas las aplicaciones web de AgroShine.

Encapsula la instancia de Axios, la autenticación por token, el unwrap del envelope `{ success, data }` del gateway y el manejo del error 401. Las apps solo importan las funciones `fetch*` que necesitan — sin configurar Axios, sin instanciar repositorios, sin lógica de auth.

> Documentación completa de módulos y tipos: [DOCS.md](https://github.com/AgroShine/ags-web-http/blob/main/DOCS.md)

---

## Instalación

```bash
pnpm add @agroshine/ags-web-http
```

```bash
npm install @agroshine/ags-web-http
```

---

## Configuración inicial

Llama a `createHttpConfig()` **una sola vez** al arrancar la app, antes de cualquier llamada HTTP. El lugar correcto es `src/main.tsx`.

```ts
// src/main.tsx
import { createHttpConfig } from '@agroshine/ags-web-http';

createHttpConfig({
  clientId: 'web_admin',           // 'web_admin' | 'web_client'
  onUnauthorized: () => {
    clearQueryCache();
    toast.error('Sesión expirada');
    window.location.href = '/login';
  },
});
```

> **URL base:** por defecto el paquete lee `VITE_API_URL` de las variables de entorno. Si tu app no usa Vite (Next.js, Webpack), pasa `baseURL` explícitamente — tiene prioridad sobre el entorno.

### Opciones de `createHttpConfig`

| Opción | Tipo | Requerido | Descripción |
|--------|------|-----------|-------------|
| `clientId` | `'web_admin' \| 'web_client'` | ✅ | Identifica la app en el header `auth` del gateway |
| `baseURL` | `string` | — | URL base del API. Tiene prioridad sobre `VITE_API_URL` |
| `onUnauthorized` | `() => void` | — | Se ejecuta cuando el API responde 401 |
| `tokenKey` | `string` | — | Clave en `localStorage` donde está el JWT. Por defecto: `'uuid'` |
| `tokenStorage` | `TokenStorage` | — | Adaptador de almacenamiento del token |
| `timeout` | `number` | — | Timeout por request en ms. Por defecto: `15000` |
| `signingKey` | `string` | — | Clave HMAC compartida con el gateway |
| `maxRetries` | `number` | — | Reintentos en red/5xx en métodos idempotentes. Por defecto: `2` |

---

## Comportamiento automático

### Autenticación por token

El paquete lee el JWT de `localStorage` (clave `uuid` por defecto) y lo adjunta como `Authorization: Bearer <token>` en cada request que requiere auth.

### Unwrap del envelope del gateway

El gateway responde con `{ success: boolean, data: T }`. El paquete desenvuelve esto automáticamente — las funciones `fetch*` retornan `AxiosResponse<T>` directamente.

### Manejo del error 401

Cuando el API responde `401 Unauthorized`:
1. Se elimina el token de `localStorage`
2. Se llama al `onUnauthorized` definido en `createHttpConfig`
3. Un flag `isRedirecting` evita múltiples redirects simultáneos

---

## Desarrollo

```bash
pnpm install      # instalar dependencias
pnpm build        # compilar el paquete
pnpm dev          # modo watch
pnpm typecheck    # verificar tipos
pnpm format       # formatear código
pnpm test:run     # ejecutar tests
```

---

## Agregar un nuevo módulo del backend

Cuando el backend exponga un nuevo recurso (ej. `/config/health`):

**1. Crear el archivo del módulo:**

```ts
// src/health/index.ts
import { createRepo } from '../core/factory';
import type { IHealth } from '../types/health';

export async function fetchHealth() {
  return createRepo('/config/health', true).GET<object, IHealth[]>();
}
```

**2. Agregar el tipo en `src/types/`:**

```ts
// src/types/health.ts
export interface IHealth {
  _id: string;
  // ...
}
```

**3. Registrar el entry en `tsup.config.ts`:**

```ts
entry: {
  // ... entradas existentes
  'health/index': 'src/health/index.ts',
},
```

**4. Agregar el export en `package.json`:**

```json
"./health": {
  "types": "./dist/health/index.d.ts",
  "import": "./dist/health/index.js",
  "require": "./dist/health/index.cjs"
}
```

**5. Exportar el tipo en `src/types/index.ts` y liberar una versión:**

```bash
pnpm build   # validar que compila
# commit con conventional-commits (feat/fix/…) y push a main
# semantic-release crea el tag y publica la nueva versión en npm automáticamente
```

Las apps consumidoras actualizan con:

```bash
pnpm update @agroshine/ags-web-http
```
