# @andco/sdk/server

> El constructor confidencial, sin sesión y seguro de compartir entre peticiones.


```ts
import { createAndcoInstanceForServer } from "@andco/sdk/server";
```

## createAndcoInstanceForServer

```ts
createAndcoInstanceForServer(options: AndcoServerOptions): AndcoClient
```

Devuelve un `AndcoClient`, no un `AndcoSessionClient`. La diferencia es el punto entero: **una instancia de servidor no guarda sesión**, porque no hay una sola persona detrás de un proceso que atiende a muchas. No tiene `auth`, no tiene `session`, no tiene `rest`.

Eso es lo que la hace segura de crear a nivel de módulo y compartir entre peticiones concurrentes: no existe el campo donde el token de una persona podría quedarse y aparecer en la respuesta de otra.

```ts
export const andco = createAndcoInstanceForServer({
  clientId: process.env.ANDCO_CLIENT_ID!,
  clientSecret: process.env.ANDCO_CLIENT_SECRET!,
});
```

Lanza si se ejecuta en un navegador. El secreto no tiene ningún camino legítimo hacia el cliente, así que fallar ruidosamente es mejor que funcionar.

`AndcoServerOptions` son las opciones de `AndcoClient`: `clientId`, `clientSecret`, `endpointAuth`, `endpointApi`, `apiVersion`, `redirectTo`, `initialScopes`, `fetch`, `transport`.

## El recorrido

```ts
// 1. Prepare
const { data: request } = await andco.oauth.createAuthorizationRequest({
  redirectTo: "https://tuapp.com/auth/callback",
  scopes: ["openid", "email", "profile"],
});

// 2. Store the transaction in YOUR session and send the person off
store(request);
redirect(request.authorizationUrl.href);

// 3. In the callback
const { data: session } = await andco.oauth.exchangeCallback({
  callbackUrl: new URL(req.url),
  request: retrieve(),
});

// 4. Call on that person's behalf
const { data } = await andco.with(session).rest.http.GET("/accounts");
```

El paso 2 no es opcional: `request` lleva el verificador PKCE, que no puede viajar en la URL y no se puede reconstruir.

## with

```ts
with(credentials: AndcoCredentials | AndcoSession | string): AndcoBoundClient
```

Las tres formas responden a tres situaciones reales:

```ts
andco.with("a-bare-access-token"); // the commonest server shape: the token that arrived on the request
andco.with(session); // same lookup, still no refresh
andco.with(myCredentials); // the token lives elsewhere and you know how to get it
```

Ninguna de las dos primeras formas renueva por sí sola: son una consulta directa al token de la sesión. Solo `myCredentials` puede renovar, si tú se lo implementas.

## Transporte de la autorización

```ts
createAndcoInstanceForServer({ clientId, clientSecret, transport: "auto" });
```

`"auto"` usa PAR cuando la URL sería demasiado larga o cuando la petición lleva parámetros que no deben quedar en el historial ni en los registros: `login_hint` y `authorization_details`. `"get"` y `"par"` fuerzan uno u otro.

Un cliente confidencial se autentica en PAR con `client_secret_basic`, con las credenciales codificadas en forma antes del Basic, como pide el RFC 6749.

## Descripción del servidor

```ts
const configuration = await andco.oauth.configuration();
configuration.serverMetadata().issuer;
```

Los endpoints, los algoritmos de firma y la ubicación de las claves se leen del documento que el servidor de autorización publica de sí mismo, no se derivan de `endpointAuth`. Se lee una vez por instancia y se memoriza.
