# Types

O pacote `@aziontech/types` é a biblioteca da Azion Lib de tipos TypeScript para código que roda no [Azion Runtime](/pt-br/documentacao/devtools/runtime/). Ele declara os formatos de handler de uma function, a requisição com seus metadados e o contexto que um handler recebe. O pacote contém apenas tipos: seu módulo JavaScript não exporta nada e não faz nenhuma chamada de API, por isso você importa cada nome com `import type`.

Instale o pacote:

```bash
npm install @aziontech/types
```

Os exemplos em TypeScript desta página importam seus tipos com `import type`. O exemplo de metadados roda no Node.js, e os exemplos de handler rodam dentro de uma function servida localmente com o [azion dev](/pt-br/documentacao/devtools/cli/dev-comando/).

> **nota**
>
> No `azion dev`, `request.metadata` não existe, por isso os exemplos de handler desta página o leem com optional chaining (`metadata?.`). Localmente, um handler `firewall` de módulo recebe um `ctx` que contém apenas `waitUntil`. Para os metadados que uma function com deploy feito lê, consulte [API de metadados](/pt-br/documentacao/devtools/runtime/api-reference/metadata/).

---

## AzionRuntimeRequestMetadata

O objeto de metadados que [AzionRuntimeRequest](#azionruntimerequest) carrega em `metadata`. A interface declara 26 chaves, todas do tipo `string` e obrigatórias, mais uma assinatura de índice de string que tipa qualquer outra chave.

| Propriedade                 | Tipo     | Obrigatório | Descrição                                                |
| --------------------------- | -------- | ----------- | -------------------------------------------------------- |
| `geoip_asn`                 | `string` | Sim         | Número do sistema autônomo.                              |
| `geoip_city`                | `string` | Sim         | Código da cidade.                                        |
| `geoip_city_continent_code` | `string` | Sim         | Código do continente da cidade.                          |
| `geoip_city_country_code`   | `string` | Sim         | Código do país da cidade.                                |
| `geoip_city_country_name`   | `string` | Sim         | Nome do país da cidade.                                  |
| `geoip_continent_code`      | `string` | Sim         | Código do continente.                                    |
| `geoip_country_code`        | `string` | Sim         | Código do país.                                          |
| `geoip_country_name`        | `string` | Sim         | Nome do país.                                            |
| `geoip_region`              | `string` | Sim         | Código da região.                                        |
| `geoip_region_name`         | `string` | Sim         | Nome da região.                                          |
| `remote_addr`               | `string` | Sim         | Endereço IP do cliente.                                  |
| `remote_port`               | `string` | Sim         | Porta TCP do cliente.                                    |
| `remote_user`               | `string` | Sim         | Usuário informado na URL.                                |
| `server_protocol`           | `string` | Sim         | Protocolo da requisição.                                 |
| `server_fingerprint`        | `string` | Sim         | Fingerprint TLS do servidor.                             |
| `server_fingerprint_ja4h`   | `string` | Sim         | Fingerprint JA4H do servidor.                            |
| `ssl_cipher`                | `string` | Sim         | Cifra TLS da sessão.                                     |
| `ssl_protocol`              | `string` | Sim         | Protocolo TLS da sessão.                                 |
| `client_fingerprint`        | `string` | Sim         | Fingerprint do cliente.                                  |
| `client_id`                 | `string` | Sim         | Identificador da conta Azion dona do workload.           |
| `configuration_id`          | `string` | Sim         | Identificador do workload que recebeu a requisição.      |
| `edge_connector_id`         | `string` | Sim         | —                                                        |
| `function_id`               | `string` | Sim         | Identificador da function que roda para a requisição.    |
| `http_ssl_ja4`              | `string` | Sim         | Fingerprint TLS JA4 da requisição.                       |
| `request_id`                | `string` | Sim         | ID único da requisição.                                  |
| `solution_id`               | `string` | Sim         | Identificador interno da solução que trata a requisição. |
| `[key: string]`             | `string` | Não         | Qualquer outra chave do objeto.                          |

Um objeto literal tipado como `AzionRuntimeRequestMetadata` precisa carregar as 26 chaves, ou o `tsc` para com o erro `TS2740` e nomeia as que faltam. Para tipar um objeto que contém parte das chaves, envolva a interface em `Partial`.

Este exemplo monta um objeto de metadados com 16 das chaves:

```typescript
import type { AzionRuntimeRequestMetadata } from '@aziontech/types';

const requestMetadata: Partial<AzionRuntimeRequestMetadata> = {
  geoip_asn: '12345',
  geoip_city: 'Sao Paulo',
  geoip_city_continent_code: 'SA',
  geoip_city_country_code: 'BR',
  geoip_city_country_name: 'Brazil',
  geoip_continent_code: 'SA',
  geoip_country_code: 'BR',
  geoip_country_name: 'Brazil',
  geoip_region: 'SP',
  geoip_region_name: 'Sao Paulo',
  remote_addr: '192.0.2.1',
  remote_port: '443',
  remote_user: 'user',
  server_protocol: 'HTTP/1.1',
  ssl_cipher: 'ECDHE-RSA-AES128-GCM-SHA256',
  ssl_protocol: 'TLSv1.2',
};
console.log(Object.keys(requestMetadata).length, 'fields');
```

Saída:

```text
16 fields
```

---

## AzionRuntimeRequest

A requisição que um handler de módulo recebe: o [Request](/pt-br/documentacao/devtools/runtime/api-reference/request/) padrão com uma propriedade `metadata`.

```typescript
type AzionRuntimeRequest = Request & {
  metadata: AzionRuntimeRequestMetadata;
};
```

| Propriedade | Tipo                                                          | Obrigatório | Descrição                   |
| ----------- | ------------------------------------------------------------- | ----------- | --------------------------- |
| `metadata`  | [`AzionRuntimeRequestMetadata`](#azionruntimerequestmetadata) | Sim         | Os metadados da requisição. |

---

## AzionRuntimeModule

O export padrão de uma function no formato de módulo: um objeto com um handler `fetch`, um handler `firewall` ou ambos. O formato de módulo é o formato de handler que [Handlers](/pt-br/documentacao/devtools/runtime/api-reference/handlers/) recomenda.

```typescript
interface AzionRuntimeModule {
  fetch?: (request: AzionRuntimeRequest, env?: null, ctx?: AzionRuntimeCtx) => Promise<Response>;
  firewall?: (request: AzionRuntimeRequest, env?: null, ctx?: AzionRuntimeCtx) => Promise<Response>;
}
```

| Propriedade | Tipo                                                                                     | Obrigatório | Descrição                                                |
| ----------- | ---------------------------------------------------------------------------------------- | ----------- | -------------------------------------------------------- |
| `fetch`     | `(request: AzionRuntimeRequest, env?: null, ctx?: AzionRuntimeCtx) => Promise<Response>` | Não         | O handler que o Azion Runtime chama para uma requisição. |
| `firewall`  | `(request: AzionRuntimeRequest, env?: null, ctx?: AzionRuntimeCtx) => Promise<Response>` | Não         | O handler de firewall, como o tipo o declara.            |

Esta function verifica seu export padrão contra o tipo com `satisfies` e responde com a cidade do cliente:

```typescript
import type { AzionRuntimeModule, AzionRuntimeRequest } from '@aziontech/types';

export default {
  async fetch(request: AzionRuntimeRequest): Promise<Response> {
    const { metadata } = request;
    console.log('Request URL:', request.url);
    console.log('Client IP:', metadata?.remote_addr);
    console.log('GeoIP City:', metadata?.geoip_city);
    return new Response(`Hello from ${metadata?.geoip_city ?? 'an unknown city'}\n`);
  },
} satisfies AzionRuntimeModule;
```

Com a function servida localmente com `azion dev`, em que a requisição não carrega metadados, uma requisição retorna:

```text
$ curl http://localhost:3333/types
HTTP/1.1 200 OK
content-type: text/plain;charset=UTF-8

Hello from an unknown city
```

A function registra no log:

```text
Request URL: http://localhost:3333/types
Client IP: undefined
GeoIP City: undefined
```

---

## AzionRuntimeCtx

O contexto que [AzionRuntimeModule](#azionruntimemodule) declara como terceiro argumento dos dois handlers.

```typescript
interface AzionRuntimeCtx {
  waitUntil: (promise: Promise<unknown>) => void;
  args?: Record<string, unknown>;
}
```

| Propriedade | Tipo                                  | Obrigatório | Descrição                                                         |
| ----------- | ------------------------------------- | ----------- | ----------------------------------------------------------------- |
| `waitUntil` | `(promise: Promise<unknown>) => void` | Sim         | Estende a execução até que `promise` seja resolvida ou rejeitada. |
| `args`      | `Record<string, unknown>`             | Não         | Os args da function instance.                                     |

---

## AzionFetchEvent

O evento que um listener registrado com [addEventListener](/pt-br/documentacao/devtools/runtime/api-reference/add-eventlistener/) para o tipo `fetch` recebe. Ele estende o `Event` padrão.

```typescript
interface AzionFetchEvent extends Event {
  request: Request & {
    metadata: AzionRuntimeRequestMetadata;
  };
  waitUntil: (promise: Promise<unknown>) => void;
  respondWith: (response: Response | Promise<Response>) => void;
}
```

| Propriedade   | Tipo                                                  | Obrigatório | Descrição                                                         |
| ------------- | ----------------------------------------------------- | ----------- | ----------------------------------------------------------------- |
| `request`     | `Request & { metadata: AzionRuntimeRequestMetadata }` | Sim         | A requisição, com seus [metadados](#azionruntimerequestmetadata). |
| `waitUntil`   | `(promise: Promise<unknown>) => void`                 | Sim         | Declarado pelo tipo.                                              |
| `respondWith` | `(response: Response \| Promise<Response>) => void`   | Sim         | Define a resposta que a function envia ao cliente.                |

Em uma function JavaScript, um comentário JSDoc aplica o tipo ao evento. Este listener responde com a cidade do cliente:

```javascript
/** @typedef {import('@aziontech/types').AzionFetchEvent} AzionFetchEvent */

addEventListener('fetch', (/** @type {AzionFetchEvent} */ event) => {
  const { request } = event;
  const metadata = request.metadata;

  console.log('Request URL:', request.url);
  console.log('Client IP:', metadata?.remote_addr);
  console.log('GeoIP City:', metadata?.geoip_city);

  event.respondWith(new Response(`Hello from ${metadata?.geoip_city ?? 'an unknown city'}\n`));
});
```

Com a function servida localmente com `azion dev`, o listener retorna a mesma resposta do exemplo de [AzionRuntimeModule](#azionruntimemodule) e registra no log as mesmas três linhas:

```text
$ curl http://localhost:3333/types
HTTP/1.1 200 OK
content-type: text/plain;charset=UTF-8

Hello from an unknown city
```

---

## FetchEventListener

O tipo de um listener para o evento `fetch`.

```typescript
type FetchEventListener = (event: AzionFetchEvent, args?: Record<string, unknown>) => void | Promise<void>;
```

| Parâmetro | Tipo                                  | Obrigatório | Descrição                      |
| --------- | ------------------------------------- | ----------- | ------------------------------ |
| `event`   | [`AzionFetchEvent`](#azionfetchevent) | Sim         | O evento `fetch`.              |
| `args`    | `Record<string, unknown>`             | Não         | Os args que o listener recebe. |

---

## AzionFirewallEvent

O tipo de evento que o pacote declara para um listener de firewall. Ele estende [AzionFetchEvent](#azionfetchevent) com três métodos.

```typescript
interface AzionFirewallEvent extends AzionFetchEvent {
  deny: () => void;
  drop: () => void;
  continue: () => void;
}
```

| Propriedade                           | Tipo                                        | Obrigatório | Descrição                      |
| ------------------------------------- | ------------------------------------------- | ----------- | ------------------------------ |
| `deny`                                | `() => void`                                | Sim         | Declarado pelo tipo.           |
| `drop`                                | `() => void`                                | Sim         | Declarado pelo tipo.           |
| `continue`                            | `() => void`                                | Sim         | Declarado pelo tipo.           |
| `request`, `waitUntil`, `respondWith` | como em [AzionFetchEvent](#azionfetchevent) | Sim         | Herdados de `AzionFetchEvent`. |

---

## AzionRuntimeFirewallCtx

O tipo de contexto que o pacote declara para módulos de firewall. Ele estende [AzionRuntimeCtx](#azionruntimectx) com três métodos. [AzionRuntimeModule](#azionruntimemodule) tipa o `ctx` do seu handler `firewall` como `AzionRuntimeCtx`, não como este tipo.

```typescript
interface AzionRuntimeFirewallCtx extends AzionRuntimeCtx {
  deny: () => void;
  continue: () => void;
  drop: () => void;
}
```

| Propriedade | Tipo                                  | Obrigatório | Descrição                                       |
| ----------- | ------------------------------------- | ----------- | ----------------------------------------------- |
| `deny`      | `() => void`                          | Sim         | Declarado pelo tipo.                            |
| `continue`  | `() => void`                          | Sim         | Declarado pelo tipo.                            |
| `drop`      | `() => void`                          | Sim         | Declarado pelo tipo.                            |
| `waitUntil` | `(promise: Promise<unknown>) => void` | Sim         | Herdado de [AzionRuntimeCtx](#azionruntimectx). |
| `args`      | `Record<string, unknown>`             | Não         | Herdado de [AzionRuntimeCtx](#azionruntimectx). |

---

## FirewallEventListener

O tipo de um listener para o evento de firewall.

```typescript
type FirewallEventListener = (event: AzionFirewallEvent, args?: Record<string, unknown>) => void | Promise<void>;
```

| Parâmetro | Tipo                                        | Obrigatório | Descrição                      |
| --------- | ------------------------------------------- | ----------- | ------------------------------ |
| `event`   | [`AzionFirewallEvent`](#azionfirewallevent) | Sim         | O evento de firewall.          |
| `args`    | `Record<string, unknown>`                   | Não         | Os args que o listener recebe. |

---

## Namespace Azion

O pacote também exporta o namespace `Azion`, que declara os namespaces `Azion.Storage` e `Azion.Sql`. Para as APIs do runtime que esses nomes descrevem, consulte [Object Storage API](/pt-br/documentacao/devtools/runtime/api-reference/storage/) e [SQL Database API](/pt-br/documentacao/devtools/runtime/api-reference/sql-database/).

```typescript
declare namespace Azion {
  namespace Storage {
    type ContentObjectStorage = ArrayBuffer | ReadableStream | string | Uint8Array;
    interface StorageInstance {
      list(): Promise<{
        entries: {
          key: string;
          content_length?: number;
        }[];
      }>;
      put(key: string, value: ContentObjectStorage, options?: {
        'content-length'?: string;
        'content-type'?: string;
      }): Promise<void>;
      delete(key: string): Promise<void>;
      get(key: string): Promise<StorageObject>;
    }
    interface StorageObject {
      arrayBuffer(): Promise<ArrayBuffer>;
      metadata: Map<string, string>;
      contentType: string;
      contentLength: number;
    }
  }
  namespace Sql {
    interface Connection {
      query: (sql: string) => Promise<Rows>;
      execute: (sql: string) => Promise<null>;
    }
    interface Rows {
      next: () => Promise<Row>;
      columnCount: () => number;
      columnName: (index: number) => string;
      columnType: (index: number) => string;
    }
    interface Row {
      columnName: (index: number) => string;
      columnType: (index: number) => string;
      getValue: (index: number) => any;
      getString: (index: number) => string;
    }
    interface Database {
      connection: Connection;
      open?: (name: string) => Promise<Connection>;
    }
  }
}
```

---

## Recursos relacionados

- [Azion Lib](/pt-br/documentacao/devtools/azion-lib.md): As bibliotecas que a Azion Lib oferece e o pacote que contém cada uma.
- [Handlers](/pt-br/documentacao/devtools/runtime/api-reference/handlers.md): Os formatos de handler que o Azion Runtime chama e a requisição, o env e o ctx que um handler recebe.
- [API de metadados](/pt-br/documentacao/devtools/runtime/api-reference/metadata.md): As chaves de metadados que uma function com deploy feito lê da requisição, com o que cada uma contém.
- [Azion CLI dev](/pt-br/documentacao/devtools/cli/dev-comando.md): Sirva uma function localmente e teste um handler antes de fazer o deploy.
