# Types

The `@aziontech/types` package is the Azion Lib library of TypeScript types for code that runs on [Azion Runtime](/en/documentation/devtools/runtime/). It declares the handler shapes of a function, the request with its metadata, and the context a handler receives. The package holds types only: its JavaScript module exports nothing and makes no API call, so you import every name with `import type`.

Install the package:

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

The TypeScript samples on this page import their types with `import type`. The metadata sample runs in Node.js, and the handler samples run inside a function served locally with [azion dev](/en/documentation/devtools/cli/dev-command/).

> **Note**
>
> Under `azion dev`, `request.metadata` is absent, so the handler samples on this page read it with optional chaining (`metadata?.`). Locally, a module `firewall` handler receives a `ctx` that holds only `waitUntil`. For the metadata a deployed function reads, refer to [Metadata API](/en/documentation/devtools/runtime/api-reference/metadata/).

---

## AzionRuntimeRequestMetadata

The metadata object that [AzionRuntimeRequest](#azionruntimerequest) carries in `metadata`. The interface declares 26 keys, every one a required `string`, plus a string index signature that types any other key.

| Property                    | Type     | Required | Description                                                   |
| --------------------------- | -------- | -------- | ------------------------------------------------------------- |
| `geoip_asn`                 | `string` | Yes      | Autonomous system number.                                     |
| `geoip_city`                | `string` | Yes      | City code.                                                    |
| `geoip_city_continent_code` | `string` | Yes      | Continent code of the city.                                   |
| `geoip_city_country_code`   | `string` | Yes      | Country code of the city.                                     |
| `geoip_city_country_name`   | `string` | Yes      | Country name of the city.                                     |
| `geoip_continent_code`      | `string` | Yes      | Continent code.                                               |
| `geoip_country_code`        | `string` | Yes      | Country code.                                                 |
| `geoip_country_name`        | `string` | Yes      | Country name.                                                 |
| `geoip_region`              | `string` | Yes      | Region code.                                                  |
| `geoip_region_name`         | `string` | Yes      | Region name.                                                  |
| `remote_addr`               | `string` | Yes      | IP address of the client.                                     |
| `remote_port`               | `string` | Yes      | TCP port of the client.                                       |
| `remote_user`               | `string` | Yes      | User given in the URL.                                        |
| `server_protocol`           | `string` | Yes      | Protocol of the request.                                      |
| `server_fingerprint`        | `string` | Yes      | Server TLS fingerprint.                                       |
| `server_fingerprint_ja4h`   | `string` | Yes      | Server JA4H fingerprint.                                      |
| `ssl_cipher`                | `string` | Yes      | TLS cipher of the session.                                    |
| `ssl_protocol`              | `string` | Yes      | TLS protocol of the session.                                  |
| `client_fingerprint`        | `string` | Yes      | Client fingerprint.                                           |
| `client_id`                 | `string` | Yes      | Identifier of the Azion account that owns the workload.       |
| `configuration_id`          | `string` | Yes      | Identifier of the workload that received the request.         |
| `edge_connector_id`         | `string` | Yes      | —                                                             |
| `function_id`               | `string` | Yes      | Identifier of the function that runs for the request.         |
| `http_ssl_ja4`              | `string` | Yes      | JA4 TLS fingerprint of the request.                           |
| `request_id`                | `string` | Yes      | Unique ID of the request.                                     |
| `solution_id`               | `string` | Yes      | Internal identifier of the solution that handles the request. |
| `[key: string]`             | `string` | No       | Any other key of the object.                                  |

An object literal typed as `AzionRuntimeRequestMetadata` must carry all 26 keys, or `tsc` stops with error `TS2740` and names the missing ones. To type an object that holds some of the keys, wrap the interface in `Partial`.

This sample builds a metadata object with 16 of the keys:

```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');
```

Output:

```text
16 fields
```

---

## AzionRuntimeRequest

The request a module handler receives: the standard [Request](/en/documentation/devtools/runtime/api-reference/request/) with a `metadata` property.

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

| Property   | Type                                                          | Required | Description                  |
| ---------- | ------------------------------------------------------------- | -------- | ---------------------------- |
| `metadata` | [`AzionRuntimeRequestMetadata`](#azionruntimerequestmetadata) | Yes      | The metadata of the request. |

---

## AzionRuntimeModule

The default export of a function in the module form: an object with a `fetch` handler, a `firewall` handler, or both. The module form is the handler shape [Handlers](/en/documentation/devtools/runtime/api-reference/handlers/) recommends.

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

| Property   | Type                                                                                     | Required | Description                                    |
| ---------- | ---------------------------------------------------------------------------------------- | -------- | ---------------------------------------------- |
| `fetch`    | `(request: AzionRuntimeRequest, env?: null, ctx?: AzionRuntimeCtx) => Promise<Response>` | No       | The handler Azion Runtime calls for a request. |
| `firewall` | `(request: AzionRuntimeRequest, env?: null, ctx?: AzionRuntimeCtx) => Promise<Response>` | No       | The firewall handler, as the type declares it. |

This function checks its default export against the type with `satisfies`, and responds with the city of the client:

```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;
```

Served locally with `azion dev`, where the request carries no metadata, a request returns:

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

Hello from an unknown city
```

The function logs:

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

---

## AzionRuntimeCtx

The context that [AzionRuntimeModule](#azionruntimemodule) declares as the third argument of both handlers.

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

| Property    | Type                                  | Required | Description                                    |
| ----------- | ------------------------------------- | -------- | ---------------------------------------------- |
| `waitUntil` | `(promise: Promise<unknown>) => void` | Yes      | Extends the execution until `promise` settles. |
| `args`      | `Record<string, unknown>`             | No       | The args of the function instance.             |

---

## AzionFetchEvent

The event a listener registered with [addEventListener](/en/documentation/devtools/runtime/api-reference/add-eventlistener/) for the `fetch` type receives. It extends the standard `Event`.

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

| Property      | Type                                                  | Required | Description                                                     |
| ------------- | ----------------------------------------------------- | -------- | --------------------------------------------------------------- |
| `request`     | `Request & { metadata: AzionRuntimeRequestMetadata }` | Yes      | The request, with its [metadata](#azionruntimerequestmetadata). |
| `waitUntil`   | `(promise: Promise<unknown>) => void`                 | Yes      | Declared by the type.                                           |
| `respondWith` | `(response: Response \| Promise<Response>) => void`   | Yes      | Sets the response the function sends to the client.             |

In a JavaScript function, a JSDoc comment applies the type to the event. This listener responds with the city of the client:

```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`));
});
```

Served locally with `azion dev`, the listener returns the same response as the [AzionRuntimeModule](#azionruntimemodule) sample and logs the same three lines:

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

Hello from an unknown city
```

---

## FetchEventListener

The type of a listener for the `fetch` event.

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

| Parameter | Type                                  | Required | Description                     |
| --------- | ------------------------------------- | -------- | ------------------------------- |
| `event`   | [`AzionFetchEvent`](#azionfetchevent) | Yes      | The `fetch` event.              |
| `args`    | `Record<string, unknown>`             | No       | The args the listener receives. |

---

## AzionFirewallEvent

The event type the package declares for a firewall listener. It extends [AzionFetchEvent](#azionfetchevent) with three methods.

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

| Property                              | Type                                      | Required | Description                       |
| ------------------------------------- | ----------------------------------------- | -------- | --------------------------------- |
| `deny`                                | `() => void`                              | Yes      | Declared by the type.             |
| `drop`                                | `() => void`                              | Yes      | Declared by the type.             |
| `continue`                            | `() => void`                              | Yes      | Declared by the type.             |
| `request`, `waitUntil`, `respondWith` | as in [AzionFetchEvent](#azionfetchevent) | Yes      | Inherited from `AzionFetchEvent`. |

---

## AzionRuntimeFirewallCtx

The context type the package declares for firewall modules. It extends [AzionRuntimeCtx](#azionruntimectx) with three methods. [AzionRuntimeModule](#azionruntimemodule) types the `ctx` of its `firewall` handler as `AzionRuntimeCtx`, not as this type.

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

| Property    | Type                                  | Required | Description                                         |
| ----------- | ------------------------------------- | -------- | --------------------------------------------------- |
| `deny`      | `() => void`                          | Yes      | Declared by the type.                               |
| `continue`  | `() => void`                          | Yes      | Declared by the type.                               |
| `drop`      | `() => void`                          | Yes      | Declared by the type.                               |
| `waitUntil` | `(promise: Promise<unknown>) => void` | Yes      | Inherited from [AzionRuntimeCtx](#azionruntimectx). |
| `args`      | `Record<string, unknown>`             | No       | Inherited from [AzionRuntimeCtx](#azionruntimectx). |

---

## FirewallEventListener

The type of a listener for the firewall event.

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

| Parameter | Type                                        | Required | Description                     |
| --------- | ------------------------------------------- | -------- | ------------------------------- |
| `event`   | [`AzionFirewallEvent`](#azionfirewallevent) | Yes      | The firewall event.             |
| `args`    | `Record<string, unknown>`                   | No       | The args the listener receives. |

---

## Azion namespace

The package also exports the `Azion` namespace, which declares the `Azion.Storage` and `Azion.Sql` namespaces. For the runtime APIs these names describe, refer to [Object Storage API](/en/documentation/devtools/runtime/api-reference/storage/) and [SQL Database API](/en/documentation/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>;
    }
  }
}
```

---

## Related resources

- [Azion Lib](/en/documentation/devtools/azion-lib.md): The libraries Azion Lib ships and the package that carries each one.
- [Handlers](/en/documentation/devtools/runtime/api-reference/handlers.md): The handler shapes Azion Runtime calls, and the request, env, and ctx a handler receives.
- [Metadata API](/en/documentation/devtools/runtime/api-reference/metadata.md): The metadata keys a deployed function reads from the request, with what each one holds.
- [Azion CLI dev](/en/documentation/devtools/cli/dev-command.md): Serve a function locally and test a handler before you deploy it.
