> ## Documentation Index
> Fetch the complete documentation index at: https://private-7c7dfe99-fix-nav-issues.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

> Cliente oficial de JS para conectarse a ClickHouse.

# ClickHouse JS

export const ExperimentalBadge = () => {
  return <div className="experimentalBadge">
            <div className="experimentalIcon">
            <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
                <path strokeWidth="1.25" d="M5.5 2H10.5" stroke="currentColor" strokeLinecap="round" strokeLinejoin="round" />
                <path strokeWidth="1.25" d="M9.50015 2V6.19625L13.4283 12.7425C13.4738 12.8183 13.4985 12.9049 13.4996 12.9934C13.5008 13.0818 13.4785 13.169 13.435 13.246C13.3914 13.323 13.3283 13.3871 13.2519 13.4317C13.1755 13.4764 13.0886 13.4999 13.0002 13.5H3.00015C2.91164 13.5 2.8247 13.4766 2.74822 13.432C2.67174 13.3874 2.60847 13.3233 2.56487 13.2463C2.52126 13.1693 2.49889 13.082 2.50004 12.9935C2.50119 12.905 2.52582 12.8184 2.5714 12.7425L6.50015 6.19625V2" stroke="currentColor" strokeLinecap="round" strokeLinejoin="round" />
                <path strokeWidth="1.25" d="M4.47656 9.56754C5.30344 9.41254 6.47656 9.47942 7.99969 10.25C10.0153 11.2707 11.4216 11.0569 12.2184 10.7282" stroke="currentColor" strokeLinecap="round" strokeLinejoin="round" />
            </svg>
        </div>
            Experimental feature. <u><a href="/docs/beta-and-experimental-features#experimental-features">Learn more.</a></u>
        </div>;
};

El cliente oficial de JS para conectarse a ClickHouse.
El cliente está escrito en TypeScript y proporciona tipos para la API pública del cliente.

No tiene dependencias, está optimizado para ofrecer el máximo rendimiento y se ha probado con varias versiones y configuraciones de ClickHouse (nodo único on-premise, cluster on-premise y ClickHouse Cloud).

Hay dos versiones distintas del cliente disponibles para diferentes entornos:

* `@clickhouse/client` - solo Node.js
* `@clickhouse/client-web` - navegadores (Chrome/Firefox), Cloudflare Workers

Si usas TypeScript, asegúrate de que sea al menos la [versión 4.5](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-4-5.html), que habilita la [sintaxis de importación y exportación en línea](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-4-5.html#type-modifiers-on-import-names).

El código fuente del cliente está disponible en el [repositorio de GitHub de ClickHouse-JS](https://github.com/ClickHouse/clickhouse-js).

<Info>
  **Skills para agentes de IA**

  El cliente de JS incluye skills para agentes de IA que pueden ayudar a los agentes de programación a trabajar con el cliente. Instálalas con:

  ```sh theme={null}
  npm skills add ClickHouse/clickhouse-js
  ```
</Info>

<div id="environment-requirements-nodejs">
  ## Requisitos del entorno (node.js)
</div>

Node.js debe estar disponible en el entorno para ejecutar el cliente.
El cliente es compatible con todas las [versiones](https://github.com/nodejs/release#readme) de Node.js con mantenimiento activo.

En cuanto una versión de Node.js se acerca a su fin de vida útil, el cliente deja de ofrecer compatibilidad con ella, ya que se considera obsoleta e insegura.

Compatibilidad con las versiones actuales de Node.js:

| Versión de Node.js | ¿Compatible?            |
| ------------------ | ----------------------- |
| 24.x               | ✔                       |
| 22.x               | ✔                       |
| 20.x               | ✔                       |
| 18.x               | Compatibilidad limitada |

<div id="environment-requirements-web">
  ## Requisitos del entorno (web)
</div>

La versión web del cliente se ha probado oficialmente con las versiones más recientes de los navegadores Chrome y Firefox, y puede usarse como dependencia, por ejemplo, en aplicaciones React/Vue/Angular o en Cloudflare Workers.

<div id="installation">
  ## Instalación
</div>

Para instalar la última versión estable del cliente de Node.js, ejecuta:

```sh theme={null}
npm i @clickhouse/client
```

Instalación de la versión web:

```sh theme={null}
npm i @clickhouse/client-web
```

<div id="compatibility-with-clickhouse">
  ## Compatibilidad con ClickHouse
</div>

| Versión del cliente | ClickHouse |
| ------------------- | ---------- |
| 1.12.0              | 24.8+      |

Es probable que el cliente también funcione con versiones más antiguas; sin embargo, esta compatibilidad se ofrece sobre la base del mejor esfuerzo y no está garantizada. Si tiene una versión de ClickHouse anterior a la 23.3, consulte la [política de seguridad de ClickHouse](https://github.com/ClickHouse/ClickHouse/blob/master/SECURITY.md) y considere actualizarla.

<div id="examples">
  ## Ejemplos
</div>

Nuestro objetivo es abarcar varios escenarios de uso del cliente mediante los [ejemplos](https://github.com/ClickHouse/clickhouse-js/blob/main/examples) del repositorio del cliente.

Puedes consultar un resumen en el [README de ejemplos](https://github.com/ClickHouse/clickhouse-js/blob/main/examples/README.md#overview).

Si algo no está claro o falta en los ejemplos o en la documentación siguiente, no dudes en [contactarnos](/es/integrations/language-clients/js#contact-us).

<div id="client-api">
  ### API del cliente
</div>

La mayoría de los ejemplos deberían ser compatibles tanto con Node.js como con la versión web del cliente, salvo que se indique explícitamente lo contrario.

<div id="creating-a-client-instance">
  #### Crear una instancia de cliente
</div>

Puedes crear tantas instancias de cliente como necesites con la factoría `createClient`:

```ts theme={null}
import { createClient } from '@clickhouse/client' // o '@clickhouse/client-web'

const client = createClient({
  /* configuración */
})
```

Si tu entorno no admite módulos ESM, puedes usar en su lugar la sintaxis CJS:

```ts theme={null}
const { createClient } = require('@clickhouse/client');

const client = createClient({
  /* configuración */
})
```

Se puede [preconfigurar](/es/integrations/language-clients/js#configuration) una instancia de cliente durante su creación.

<div id="configuration">
  #### Configuración
</div>

Al crear una instancia de cliente, se pueden ajustar los siguientes parámetros de conexión:

| Ajuste                                                                   | Descripción                                                                                 | Valor predeterminado                                                        | Véase también                                                                                                                  |                                                                                                               |
| ------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------- |
| **url**?: string                                                         | La URL de una instancia de ClickHouse.                                                      | `http://localhost:8123`                                                     | [Documentación sobre la configuración de URL](/es/integrations/language-clients/js#url-configuration)                          |                                                                                                               |
| **pathname**?: string                                                    | Una ruta opcional para agregar a la URL de ClickHouse después de que el cliente la procese. | `''`                                                                        | [Documentación sobre proxy con una ruta](/es/integrations/language-clients/js#proxy-with-a-pathname)                           |                                                                                                               |
| **request\_timeout**?: number                                            | El tiempo de espera de la solicitud, en milisegundos.                                       | `30_000`                                                                    | -                                                                                                                              |                                                                                                               |
| **compression**?: `{ **response**?: boolean; **request**?: boolean }`    | Activa la compresión.                                                                       | -                                                                           | [Documentación sobre compresión](/es/integrations/language-clients/js#compression)                                             |                                                                                                               |
| **username**?: string                                                    | El nombre del usuario en cuyo nombre se realizan las solicitudes.                           | `default`                                                                   | -                                                                                                                              |                                                                                                               |
| **password**?: string                                                    | La contraseña del usuario.                                                                  | `''`                                                                        | -                                                                                                                              |                                                                                                               |
| **application**?: string                                                 | El nombre de la aplicación que usa el cliente de Node.js.                                   | `clickhouse-js`                                                             | -                                                                                                                              |                                                                                                               |
| **database**?: string                                                    | El nombre de la base de datos que se va a usar.                                             | `default`                                                                   | -                                                                                                                              |                                                                                                               |
| **clickhouse\_settings**?: ClickHouseSettings                            | Ajustes de ClickHouse que se aplican a todas las solicitudes.                               | `{}`                                                                        | -                                                                                                                              |                                                                                                               |
| **log**?: `{ **LoggerClass**?: Logger, **level**?: ClickHouseLogLevel }` | Configuración de los logs internos del cliente.                                             | -                                                                           | [Documentación sobre logging](/es/integrations/language-clients/js#logging-nodejs-only)                                        |                                                                                                               |
| **session\_id**?: string                                                 | ID de sesión opcional de ClickHouse que se envía con cada solicitud.                        | -                                                                           | -                                                                                                                              |                                                                                                               |
| **keep\_alive**?: `{ **enabled**?: boolean }`                            | Está habilitado de forma predeterminada tanto en Node.js como en la versión web.            | -                                                                           | -                                                                                                                              |                                                                                                               |
| **http\_headers**?: `Record<string, string>`                             | Cabeceras HTTP adicionales para las solicitudes salientes a ClickHouse.                     | -                                                                           | [Documentación sobre reverse proxy con authentication](/es/integrations/language-clients/js#reverse-proxy-with-authentication) |                                                                                                               |
| **roles**?: string                                                       | string\[]                                                                                   | Nombres de roles de ClickHouse que se adjuntan a las solicitudes salientes. | -                                                                                                                              | [Uso de roles con la interfaz HTTP](/es/concepts/features/interfaces/http#setting-role-with-query-parameters) |

<div id="nodejs-specific-configuration-parameters">
  #### Parámetros de configuración específicos de Node.js
</div>

| Configuración                                                               | Descripción                                                                       | Valor predeterminado                       | Véase también                                                                                                                                  |                                                                                                                       |
| --------------------------------------------------------------------------- | --------------------------------------------------------------------------------- | ------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- |
| **max\_open\_connections**?: number                                         | Número máximo de sockets abiertos permitidos por host.                            | `10`                                       | -                                                                                                                                              |                                                                                                                       |
| **tls**?: `{ **ca_cert**: Buffer, **cert**?: Buffer, **key**?: Buffer }`    | Configura los certificados TLS.                                                   | -                                          | [Documentación de TLS](/es/integrations/language-clients/js#tls-certificates-nodejs-only)                                                      |                                                                                                                       |
| **keep\_alive**?: `{ **enabled**?: boolean, **idle_socket_ttl**?: number }` | -                                                                                 | -                                          | [Documentación de Keep Alive](/es/integrations/language-clients/js#keep-alive-configuration-nodejs-only)                                       |                                                                                                                       |
| **http\_agent**?: http.Agent                                                | https.Agent <br /><ExperimentalBadge />                                           | Agente HTTP personalizado para el cliente. | -                                                                                                                                              | [Documentación del agente HTTP](/es/integrations/language-clients/js#custom-httphttps-agent-experimental-nodejs-only) |
| **set\_basic\_auth\_header**?: boolean <br /><ExperimentalBadge />          | Establece el encabezado `Authorization` con credenciales de autenticación básica. | `true`                                     | [uso de esta opción en la documentación del agente HTTP](/es/integrations/language-clients/js#custom-httphttps-agent-experimental-nodejs-only) |                                                                                                                       |

<div id="url-configuration">
  ### Configuración de la URL
</div>

<Warning>
  La configuración de la URL *siempre* sobrescribirá los valores codificados y, en ese caso, se registrará una advertencia.
</Warning>

Es posible configurar la mayoría de los parámetros de la instancia del cliente mediante una URL. El formato de la URL es `http[s]://[username:password@]hostname:port[/database][?param1=value1&param2=value2]`. En casi todos los casos, el nombre de un parámetro concreto refleja su ruta en la interfaz de opciones de configuración, con algunas excepciones. Se admiten los siguientes parámetros:

| Parámetro                                   | Type                                                                  |
| ------------------------------------------- | --------------------------------------------------------------------- |
| `pathname`                                  | una cadena arbitraria.                                                |
| `application_id`                            | una cadena arbitraria.                                                |
| `session_id`                                | una cadena arbitraria.                                                |
| `request_timeout`                           | número no negativo.                                                   |
| `max_open_connections`                      | número no negativo, mayor que cero.                                   |
| `compression_request`                       | booleano. Véase más abajo (1)                                         |
| `compression_response`                      | booleano.                                                             |
| `log_level`                                 | valores permitidos: `OFF`, `TRACE`, `DEBUG`, `INFO`, `WARN`, `ERROR`. |
| `keep_alive_enabled`                        | booleano.                                                             |
| `clickhouse_setting_*` or `ch_*`            | véase más abajo (2)                                                   |
| `http_header_*`                             | véase más abajo (3)                                                   |
| (solo Node.js) `keep_alive_idle_socket_ttl` | número no negativo.                                                   |

* (1) Para los valores booleanos, los valores válidos son `true`/`1` y `false`/`0`.
* (2) A cualquier parámetro con el prefijo `clickhouse_setting_` o `ch_` se le eliminará este prefijo y el resto se añadirá a `clickhouse_settings` del cliente. Por ejemplo, `?ch_async_insert=1&ch_wait_for_async_insert=1` será lo mismo que:

```ts theme={null}
createClient({
  clickhouse_settings: {
    async_insert: 1,
    wait_for_async_insert: 1,
  },
})
```

Nota: los valores booleanos de `clickhouse_settings` deben pasarse como `1`/`0` en la URL.

* (3) Igual que (2), pero para la configuración de `http_header`. Por ejemplo, `?http_header_x-clickhouse-auth=foobar` será equivalente a:

```ts theme={null}
createClient({
  http_headers: {
    'x-clickhouse-auth': 'foobar',
  },
})
```

<div id="connecting">
  ### Conectarse
</div>

<div id="gather-your-connection-details">
  #### Reúne los datos de conexión
</div>

Para conectarse a ClickHouse con HTTP(S), necesita esta información:

| Parámetro(s)              | Descripción                                                                                                                       |
| ------------------------- | --------------------------------------------------------------------------------------------------------------------------------- |
| `HOST` and `PORT`         | Normalmente, el puerto es 8443 cuando se usa TLS o 8123 cuando no se usa TLS.                                                     |
| `DATABASE NAME`           | De forma predeterminada, existe una base de datos llamada `default`; use el nombre de la base de datos a la que desea conectarse. |
| `USERNAME` and `PASSWORD` | De forma predeterminada, el nombre de usuario es `default`. Use el nombre de usuario adecuado para su caso de uso.                |

Los detalles de su servicio de ClickHouse Cloud están disponibles en la consola de ClickHouse Cloud.
Seleccione un servicio y haga clic en **Connect**:

<Image img="/images/_snippets/cloud-connect-button.png" size="md" alt="Botón Connect del servicio de ClickHouse Cloud" border />

Elija **HTTPS**. Los detalles de conexión se muestran en un comando `curl` de ejemplo.

<Image img="/images/_snippets/connection-details-https.png" size="md" alt="Detalles de conexión HTTPS de ClickHouse Cloud" border />

Si usa ClickHouse autogestionado, los detalles de conexión los establece su administrador de ClickHouse.

<div id="connection-overview">
  #### Resumen de la conexión
</div>

El cliente establece una conexión mediante el protocolo HTTP o HTTPS. La compatibilidad con RowBinary está en desarrollo; consulta la [incidencia relacionada](https://github.com/ClickHouse/clickhouse-js/issues/216).

El siguiente ejemplo muestra cómo configurar una conexión a ClickHouse Cloud. Se asume que los valores de `url` (incluidos
el protocolo y el puerto) y `password` se especifican mediante variables de entorno, y que se usa el usuario `default`.

**Ejemplo:** Crear una instancia del cliente de Node.js usando variables de entorno para la configuración.

```ts theme={null}
import { createClient } from '@clickhouse/client'

const client = createClient({
  url: process.env.CLICKHOUSE_HOST ?? 'http://localhost:8123',
  username: process.env.CLICKHOUSE_USER ?? 'default',
  password: process.env.CLICKHOUSE_PASSWORD ?? '',
})
```

El repositorio del cliente contiene varios ejemplos que utilizan variables de entorno, como [crear una tabla en ClickHouse Cloud](https://github.com/ClickHouse/clickhouse-js/blob/main/examples/node/schema-and-deployments/create_table_cloud.ts), [usar inserciones asíncronas](https://github.com/ClickHouse/clickhouse-js/blob/main/examples/node/coding/async_insert.ts), entre muchos otros.

<div id="connection-pool-nodejs-only">
  #### Pool de conexiones (solo Node.js)
</div>

Para evitar la sobrecarga de establecer una conexión en cada solicitud, el cliente crea un pool de conexiones a ClickHouse para reutilizarlas mediante un mecanismo Keep-Alive. De forma predeterminada, Keep-Alive está habilitado y el tamaño del pool de conexiones se establece en `10`, pero puede cambiarlo con la [opción de configuración](/es/integrations/language-clients/js#configuration) `max_open_connections`.

No hay garantía de que se use la misma conexión del pool en consultas posteriores, a menos que el usuario establezca `max_open_connections: 1`. Esto rara vez es necesario, pero puede serlo en casos en los que se usen tablas temporales.

Véase también: [Configuración de Keep-Alive](/es/integrations/language-clients/js#keep-alive-configuration-nodejs-only).

<div id="query-id">
  ### ID de consulta
</div>

Cada método que envía una consulta o una instrucción (`command`, `exec`, `insert`, `select`) devolverá `query_id` en el resultado. El cliente asigna este identificador único a cada consulta y puede ser útil para recuperar los datos de `system.query_log`,
si está habilitado en la [configuración del servidor](/es/reference/settings/server-settings/settings), o para cancelar consultas de larga ejecución (consulta [el ejemplo](https://github.com/ClickHouse/clickhouse-js/blob/main/examples/node/troubleshooting/cancel_query.ts)). Si es necesario, el usuario puede sobrescribir `query_id` en los parámetros de los métodos `command`/`query`/`exec`/`insert`.

<Tip>
  Si sobrescribes el parámetro `query_id`, debes garantizar que sea único en cada llamada. Un UUID aleatorio es una buena opción.
</Tip>

<div id="base-parameters-for-all-client-methods">
  ### Parámetros base para todos los métodos del cliente
</div>

Hay varios parámetros que se pueden aplicar a todos los métodos del cliente ([query](/es/integrations/language-clients/js#query-method)/[command](/es/integrations/language-clients/js#command-method)/[insert](/es/integrations/language-clients/js#insert-method)/[exec](/es/integrations/language-clients/js#exec-method)).

```ts theme={null}
interface BaseQueryParams {
  // Ajustes de ClickHouse que se pueden aplicar a nivel de consulta.
  clickhouse_settings?: ClickHouseSettings
  // Parámetros para el enlace de consultas.
  query_params?: Record<string, unknown>
  // Instancia de AbortSignal para cancelar una consulta en curso.
  abort_signal?: AbortSignal
  // Sobrescritura de query_id; si no se especifica, se generará automáticamente un identificador aleatorio.
  query_id?: string
  // Sobrescritura de session_id; si no se especifica, el id de sesión se tomará de la configuración del cliente.
  session_id?: string
  // Sobrescritura de credenciales; si no se especifica, se usarán las credenciales del cliente.
  auth?: { username: string, password: string }
  // Lista específica de roles para usar en esta consulta. Sobrescribe los roles definidos en la configuración del cliente.
  role?: string | Array<string>
}
```

<div id="query-method">
  ### Método de consulta
</div>

Se utiliza para la mayoría de las Sentencias que pueden devolver una respuesta, como `SELECT`, o para enviar DDLs como `CREATE TABLE`, y debe esperarse con `await`. Se espera que el conjunto de resultados devuelto se procese en la aplicación.

<Note>
  Hay un método específico, [insert](/es/integrations/language-clients/js#insert-method), para insertar datos, y [command](/es/integrations/language-clients/js#command-method) para DDLs.
</Note>

```ts theme={null}
interface QueryParams extends BaseQueryParams {
  // Consulta a ejecutar que podría devolver algunos datos.
  query: string
  // Formato del conjunto de datos resultante. Por defecto: JSON.
  format?: DataFormat
}

interface ClickHouseClient {
  query(params: QueryParams): Promise<ResultSet>
}
```

Véase también: [Parámetros base para todos los métodos del cliente](/es/integrations/language-clients/js#base-parameters-for-all-client-methods).

<Tip>
  No especifiques la cláusula FORMAT en `query`; usa el parámetro `format` en su lugar.
</Tip>

<div id="result-set-and-row-abstractions">
  #### Abstracciones de conjuntos de resultados y filas
</div>

`ResultSet` proporciona varios métodos prácticos para procesar datos en tu aplicación.

La implementación de `ResultSet` para Node.js utiliza internamente `Stream.Readable`, mientras que la versión web usa la API web `ReadableStream`.

Puedes consumir el `ResultSet` llamando a los métodos `text` o `json` de `ResultSet` y cargar en memoria el conjunto completo de filas devueltas por la consulta.

Debes empezar a consumir el `ResultSet` lo antes posible, ya que mantiene abierto el flujo de respuesta y, en consecuencia, mantiene ocupada la conexión subyacente. El cliente no almacena en búfer los datos entrantes para evitar un uso excesivo de memoria por parte de la aplicación.

Como alternativa, si es demasiado grande para caber en memoria de una sola vez, puedes llamar al método `stream` y procesar los datos en modo streaming. En ese caso, cada fragmento de la respuesta se transformará en arrays de filas relativamente pequeños, un fragmento cada vez (el tamaño de este array depende del tamaño de cada fragmento que el cliente reciba del servidor, que puede variar, y del tamaño de cada fila).

Consulta la lista de [formatos de datos compatibles](/es/integrations/language-clients/js#supported-data-formats) para determinar cuál es el mejor formato para el streaming en tu caso. Por ejemplo, si quieres transmitir objetos JSON, podrías elegir [JSONEachRow](/es/reference/formats/JSON/JSONEachRow), y cada fila se analizará como un objeto de JS o, quizá, el formato más compacto [JSONCompactColumns](/es/reference/formats/JSON/JSONCompactColumns), que hará que cada fila sea un array compacto de valores. Consulta también: [archivos en streaming](/es/integrations/language-clients/js#streaming-files-nodejs-only).

<Warning>
  Si el `ResultSet` o su flujo no se consumen por completo, se destruirán después del periodo de inactividad de `request_timeout`.
</Warning>

```ts theme={null}
interface BaseResultSet<Stream> {
  // Ver la sección "Query ID" más arriba
  query_id: string

  // Consume el stream completo y obtiene el contenido como una cadena de texto
  // Se puede usar con cualquier DataFormat
  // Solo debe llamarse una vez
  text(): Promise<string>

  // Consume el stream completo y parsea el contenido como un objeto JS
  // Solo se puede usar con formatos JSON
  // Solo debe llamarse una vez
  json<T>(): Promise<T>

  // Devuelve un stream legible para respuestas que admiten streaming
  // Cada iteración sobre el stream proporciona un array de Row[] en el DataFormat seleccionado
  // Solo debe llamarse una vez
  stream(): Stream
}

interface Row {
  // Obtiene el contenido de la fila como una cadena de texto simple
  text: string

  // Parsea el contenido de la fila como un objeto JS
  json<T>(): T
}
```

**Ejemplo:** (Node.js/Web) Una consulta cuyo resultado es un conjunto de datos en formato `JSONEachRow`, que consume todo el flujo y analiza el contenido como objetos de JS.
[Código fuente](https://github.com/ClickHouse/clickhouse-js/blob/main/examples/node/coding/array_json_each_row.ts).

```ts theme={null}
const resultSet = await client.query({
  query: 'SELECT * FROM my_table',
  format: 'JSONEachRow',
})
const dataset = await resultSet.json() // o `row.text` para evitar parsear JSON
```

**Ejemplo:** (solo para Node.js) Transmisión en streaming del resultado de una consulta en formato `JSONEachRow` mediante el enfoque clásico `on('data')`. Se puede usar indistintamente con la sintaxis `for await const`. [Código fuente](https://github.com/ClickHouse/clickhouse-js/blob/main/examples/node/performance/select_streaming_json_each_row.ts).

```ts theme={null}
const rows = await client.query({
  query: 'SELECT number FROM system.numbers_mt LIMIT 5',
  format: 'JSONEachRow', // o JSONCompactEachRow, JSONStringsEachRow, etc.
})
const stream = rows.stream()
stream.on('data', (rows: Row[]) => {
  rows.forEach((row: Row) => {
    console.log(row.json()) // o `row.text` para evitar parsear JSON
  })
})
await new Promise((resolve, reject) => {
  stream.on('end', () => {
    console.log('¡Completado!')
    resolve(0)
  })
  stream.on('error', reject)
})
```

**Ejemplo:** (solo para Node.js) resultado de una consulta en streaming en formato `CSV` usando el enfoque clásico `on('data')`. Se puede usar indistintamente con la sintaxis `for await const`.
[Código fuente](https://github.com/ClickHouse/clickhouse-js/blob/main/examples/node/performance/select_streaming_text_line_by_line.ts)

```ts theme={null}
const resultSet = await client.query({
  query: 'SELECT number FROM system.numbers_mt LIMIT 5',
  format: 'CSV', // o TabSeparated, CustomSeparated, etc.
})
const stream = resultSet.stream()
stream.on('data', (rows: Row[]) => {
  rows.forEach((row: Row) => {
    console.log(row.text)
  })
})
await new Promise((resolve, reject) => {
  stream.on('end', () => {
    console.log('Completed!')
    resolve(0)
  })
  stream.on('error', reject)
})
```

**Ejemplo:** (solo para Node.js) Resultado de la consulta en streaming como objetos de JS en formato `JSONEachRow`, consumidos con la sintaxis `for await const`. Esto puede usarse indistintamente con el enfoque clásico `on('data')`.
[Código fuente](https://github.com/ClickHouse/clickhouse-js/blob/main/examples/node/performance/select_streaming_json_each_row_for_await.ts).

```ts theme={null}
const resultSet = await client.query({
  query: 'SELECT number FROM system.numbers LIMIT 10',
  format: 'JSONEachRow', // o JSONCompactEachRow, JSONStringsEachRow, etc.
})
for await (const rows of resultSet.stream()) {
  rows.forEach(row => {
    console.log(row.json())
  })
}
```

<Note>
  La sintaxis `for await const` requiere algo menos de código que el enfoque `on('data')`, pero puede afectar negativamente al rendimiento.
  Consulta [este issue en el repositorio de Node.js](https://github.com/nodejs/node/issues/31979) para obtener más detalles.
</Note>

**Ejemplo:** (Solo web) Iteración sobre el `ReadableStream` de objetos.

```ts theme={null}
const resultSet = await client.query({
  query: 'SELECT * FROM system.numbers LIMIT 10',
  format: 'JSONEachRow'
})

const reader = resultSet.stream().getReader()
while (true) {
  const { done, value: rows } = await reader.read()
  if (done) { break }
  rows.forEach(row => {
    console.log(row.json())
  })
}
```

<div id="insert-method">
  ### Método insert
</div>

Este es el método principal para insertar datos.

```ts theme={null}
export interface InsertResult {
  query_id: string
  executed: boolean
}

interface ClickHouseClient {
  insert(params: InsertParams): Promise<InsertResult>
}
```

El tipo de retorno es mínimo, ya que no esperamos que el servidor devuelva ningún dato y consumimos el flujo de respuesta de inmediato.

Si se proporciona un array vacío al método insert, la sentencia insert no se enviará al servidor; en su lugar, el método se resolverá inmediatamente con `{ query_id: '...', executed: false }`. Si en este caso no se proporcionó `query_id` en los parámetros del método, en el resultado será una cadena vacía, ya que devolver un UUID aleatorio generado por el cliente podría resultar confuso, porque la consulta con ese `query_id` no existirá en la tabla `system.query_log`.

Si la sentencia insert se envió al servidor, la marca `executed` será `true`.

<div id="insert-method-and-streaming-in-nodejs">
  #### Método insert y streaming en Node.js
</div>

Puede funcionar tanto con un `Stream.Readable` como con un `Array<T>` simple, según el [formato de datos](/es/integrations/language-clients/js#supported-data-formats) especificado para el método `insert`. Consulte también esta sección sobre el [streaming de archivos](/es/integrations/language-clients/js#streaming-files-nodejs-only).

Se debe usar `await` con el método `insert`; sin embargo, es posible especificar un flujo de entrada y esperar la operación `insert` más adelante, solo cuando el flujo haya finalizado (lo que también resolverá la promesa de `insert`). Esto puede ser útil para listeners de eventos y casos similares, pero el manejo de errores puede resultar complejo, con muchos casos límite en el lado del cliente. En su lugar, considere usar [async inserts](/es/concepts/features/operations/insert/asyncinserts), como se muestra en [este ejemplo](https://github.com/ClickHouse/clickhouse-js/blob/main/examples/node/performance/async_insert_without_waiting.ts).

<Tip>
  Si tiene una sentencia INSERT personalizada que sea difícil de modelar con este método, considere usar el [método `command`](/es/integrations/language-clients/js#command-method).

  Puede ver cómo se usa en los ejemplos [INSERT INTO ... VALUES](https://github.com/ClickHouse/clickhouse-js/blob/main/examples/node/coding/insert_values_and_functions.ts) o [INSERT INTO ... SELECT](https://github.com/ClickHouse/clickhouse-js/blob/main/examples/node/coding/insert_from_select.ts).
</Tip>

```ts theme={null}
interface InsertParams<T> extends BaseQueryParams {
  // Nombre de la tabla en la que se insertarán los datos
  table: string
  // Un conjunto de datos a insertar.
  values: ReadonlyArray<T> | Stream.Readable
  // Formato del conjunto de datos a insertar.
  format?: DataFormat
  // Permite especificar en qué columnas se insertarán los datos.
  // - Un array como `['a', 'b']` generará: `INSERT INTO table (a, b) FORMAT DataFormat`
  // - Un objeto como `{ except: ['a', 'b'] }` generará: `INSERT INTO table (* EXCEPT (a, b)) FORMAT DataFormat`
  // De forma predeterminada, los datos se insertan en todas las columnas de la tabla,
  // y la sentencia generada será: `INSERT INTO table FORMAT DataFormat`.
  columns?: NonEmptyArray<string> | { except: NonEmptyArray<string> }
}
```

Véase también: [Parámetros base para todos los métodos del cliente](/es/integrations/language-clients/js#base-parameters-for-all-client-methods).

<Warning>
  Una solicitud cancelada con `abort_signal` no garantiza que no se haya realizado la inserción de datos, ya que el servidor podría haber recibido parte de los datos enviados en streaming antes de la cancelación.
</Warning>

**Ejemplo:** (Node.js/Web) Insertar un array de valores.
[Código fuente](https://github.com/ClickHouse/clickhouse-js/blob/main/examples/node/coding/array_json_each_row.ts).

```ts theme={null}
await client.insert({
  table: 'my_table',
  // la estructura debe coincidir con el formato deseado, JSONEachRow en este ejemplo
  values: [
    { id: 42, name: 'foo' },
    { id: 42, name: 'bar' },
  ],
  format: 'JSONEachRow',
})
```

**Ejemplo:** (solo para Node.js) Insertar un flujo desde un archivo CSV.
[Código fuente](https://github.com/ClickHouse/clickhouse-js/blob/main/examples/node/performance/insert_file_stream_csv.ts). Véase también: [streaming de archivos](/es/integrations/language-clients/js#streaming-files-nodejs-only).

```ts theme={null}
await client.insert({
  table: 'my_table',
  values: fs.createReadStream('./path/to/a/file.csv'),
  format: 'CSV',
})
```

**Ejemplo**: Excluya ciertas columnas de la sentencia INSERT.

Dada una definición de tabla como:

```sql theme={null}
CREATE OR REPLACE TABLE mytable
(id UInt32, message String)
ENGINE MergeTree()
ORDER BY (id)
```

Insertar solo una columna específica:

```ts theme={null}
// Sentencia generada: INSERT INTO mytable (message) FORMAT JSONEachRow
await client.insert({
  table: 'mytable',
  values: [{ message: 'foo' }],
  format: 'JSONEachRow',
  // El valor de la columna `id` en esta fila será cero (valor predeterminado para UInt32)
  columns: ['message'],
})
```

Excluir ciertas columnas:

```ts theme={null}
// Sentencia generada: INSERT INTO mytable (* EXCEPT (message)) FORMAT JSONEachRow
await client.insert({
  table: tableName,
  values: [{ id: 144 }],
  format: 'JSONEachRow',
  // El valor de la columna `message` para esta fila será una cadena vacía
  columns: {
    except: ['message'],
  },
})
```

Consulta el [código fuente](https://github.com/ClickHouse/clickhouse-js/blob/main/examples/node/coding/insert_exclude_columns.ts) para obtener más detalles.

**Ejemplo**: Insertar en una base de datos distinta de la especificada para la instancia del cliente. [Código fuente](https://github.com/ClickHouse/clickhouse-js/blob/main/examples/node/coding/insert_into_different_db.ts).

```ts theme={null}
await client.insert({
  table: 'mydb.mytable', // Nombre completamente calificado que incluye la base de datos
  values: [{ id: 42, message: 'foo' }],
  format: 'JSONEachRow',
})
```

<div id="web-version-limitations">
  #### Limitaciones de la versión web
</div>

Actualmente, los inserts en `@clickhouse/client-web` solo funcionan con los formatos `Array<T>` y `JSON*`.
La inserción de streams aún no es compatible con la versión web debido a la compatibilidad limitada de los navegadores.

En consecuencia, la interfaz `InsertParams` para la versión web es ligeramente distinta de la versión de Node.js,
ya que `values` se limita únicamente al tipo `ReadonlyArray<T>`:

```ts theme={null}
interface InsertParams<T> extends BaseQueryParams {
  // Nombre de la tabla en la que se insertarán los datos
  table: string
  // Un conjunto de datos a insertar.
  values: ReadonlyArray<T>
  // Formato del conjunto de datos a insertar.
  format?: DataFormat
  // Permite especificar en qué columnas se insertarán los datos.
  // - Un array como `['a', 'b']` generará: `INSERT INTO table (a, b) FORMAT DataFormat`
  // - Un objeto como `{ except: ['a', 'b'] }` generará: `INSERT INTO table (* EXCEPT (a, b)) FORMAT DataFormat`
  // Por defecto, los datos se insertan en todas las columnas de la tabla,
  // y la sentencia generada será: `INSERT INTO table FORMAT DataFormat`.
  columns?: NonEmptyArray<string> | { except: NonEmptyArray<string> }
}
```

Esto puede cambiar en el futuro. Véase también: [Parámetros base para todos los métodos de cliente](/es/integrations/language-clients/js#base-parameters-for-all-client-methods).

<div id="command-method">
  ### Método Command
</div>

Se puede usar con sentencias que no producen ninguna salida, cuando la cláusula FORMAT no es aplicable o cuando no te interesa la respuesta en absoluto. Un ejemplo de este tipo de sentencia puede ser `CREATE TABLE` o `ALTER TABLE`.

Debe usarse con `await`.

El flujo de respuesta se destruye de inmediato, lo que significa que se libera el socket subyacente.

```ts theme={null}
interface CommandParams extends BaseQueryParams {
  // Sentencia a ejecutar.
  query: string
}

interface CommandResult {
  query_id: string
}

interface ClickHouseClient {
  command(params: CommandParams): Promise<CommandResult>
}
```

Véase también: [Base parameters for all client methods](/es/integrations/language-clients/js#base-parameters-for-all-client-methods).

**Ejemplo:** (Node.js/Web) Crear una tabla en ClickHouse Cloud.
[Código fuente](https://github.com/ClickHouse/clickhouse-js/blob/main/examples/node/schema-and-deployments/create_table_cloud.ts).

```ts theme={null}
await client.command({
  query: `
    CREATE TABLE IF NOT EXISTS my_cloud_table
    (id UInt64, name String)
    ORDER BY (id)
  `,
  // Recomendado para uso en clúster para evitar situaciones en las que un error de procesamiento de consulta ocurra después del código de respuesta, 
  // y las cabeceras HTTP ya hayan sido enviadas al cliente.
  // Ver https://clickhouse.com/docs/interfaces/http/#response-buffering
  clickhouse_settings: {
    wait_end_of_query: 1,
  },
})
```

**Ejemplo:** (Node.js/Web) Crear una tabla en una instancia de ClickHouse autogestionada.
[Código fuente](https://github.com/ClickHouse/clickhouse-js/blob/main/examples/node/schema-and-deployments/create_table_single_node.ts).

```ts theme={null}
await client.command({
  query: `
    CREATE TABLE IF NOT EXISTS my_table
    (id UInt64, name String)
    ENGINE MergeTree()
    ORDER BY (id)
  `,
})
```

**Ejemplo:** (Node.js/Web) INSERT FROM SELECT

```ts theme={null}
await client.command({
  query: `INSERT INTO my_table SELECT '42'`,
})
```

<Warning>
  Una solicitud cancelada mediante `abort_signal` no garantiza que el servidor no haya ejecutado la sentencia.
</Warning>

<div id="exec-method">
  ### Método `exec`
</div>

Si tienes una consulta personalizada que no encaja en `query`/`insert`
y te interesa el resultado, puedes usar `exec` como alternativa a `command`.

`exec` devuelve un flujo legible que DEBE consumirse o destruirse del lado de la aplicación.

```ts theme={null}
interface ExecParams extends BaseQueryParams {
  // Sentencia a ejecutar.
  query: string
}

interface ClickHouseClient {
  exec(params: ExecParams): Promise<QueryResult>
}
```

Véase también: [Parámetros base para todos los métodos del cliente](/es/integrations/language-clients/js#base-parameters-for-all-client-methods).

El tipo de retorno de stream es distinto en las versiones de Node.js y web.

Node.js:

```ts theme={null}
export interface QueryResult {
  stream: Stream.Readable
  query_id: string
}
```

Web:

```ts theme={null}
export interface QueryResult {
  stream: ReadableStream
  query_id: string
}
```

<div id="ping">
  ### Ping
</div>

El método `ping`, proporcionado para comprobar el estado de conectividad, devuelve `true` si el servidor es accesible.

Si el servidor no es accesible, el error subyacente también se incluye en el resultado.

```ts theme={null}
type PingResult =
  | { success: true }
  | { success: false; error: Error }

/** Parámetros para la solicitud de comprobación de estado - usando el endpoint integrado `/ping`. 
 *  Este es el comportamiento predeterminado para la versión de Node.js. */
export type PingParamsWithEndpoint = {
  select: false
  /** Instancia de AbortSignal para cancelar una solicitud en curso. */
  abort_signal?: AbortSignal
  /** Cabeceras HTTP adicionales para incluir en esta solicitud en particular. */
  http_headers?: Record<string, string>
}
/** Parámetros para la solicitud de comprobación de estado - usando una consulta SELECT.
 *  Este es el comportamiento predeterminado para la versión Web, ya que el endpoint `/ping` no admite CORS.
 *  La mayoría de los parámetros estándar del método `query`, p. ej., `query_id`, `abort_signal`, `http_headers`, etc., funcionarán,
 *  excepto `query_params`, cuyo uso no tiene sentido en este método. */
export type PingParamsWithSelectQuery = { select: true } & Omit<
  BaseQueryParams,
  'query_params'
>
export type PingParams = PingParamsWithEndpoint | PingParamsWithSelectQuery

interface ClickHouseClient {
  ping(params?: PingParams): Promise<PingResult>
}
```

Ping puede ser útil para comprobar si el servidor está disponible al iniciar la aplicación, especialmente con ClickHouse Cloud, donde una instancia puede estar inactiva y reactivarse tras un ping; en ese caso, quizá te convenga reintentarlo varias veces con una pausa entre intentos.

Ten en cuenta que, de forma predeterminada, la versión de Node.js usa el endpoint `/ping`, mientras que la versión web usa una consulta sencilla `SELECT 1` para lograr un resultado similar, ya que el endpoint `/ping` no admite CORS.

**Ejemplo:** (Node.js/Web) Un ping sencillo a la instancia del servidor ClickHouse. Nota: en la versión web, los errores capturados serán diferentes.
[Código fuente](https://github.com/ClickHouse/clickhouse-js/blob/main/examples/ping.ts).

```ts theme={null}
const result = await client.ping();
if (!result.success) {
  // procesar result.error
}
```

**Ejemplo:** Si también quieres comprobar las credenciales al llamar al método `ping`, o especificar parámetros adicionales como `query_id`, puedes usarlo de la siguiente manera:

```ts theme={null}
const result = await client.ping({ select: true, /* query_id, abort_signal, http_headers, u otros parámetros de consulta */ });
```

El método `ping` admitirá la mayoría de los parámetros estándar del método `query`; consulta la definición de tipos `PingParamsWithSelectQuery`.

<div id="close-nodejs-only">
  ### Close (solo Node.js)
</div>

Cierra todas las conexiones abiertas y libera los recursos. No tiene efecto en la versión web.

```ts theme={null}
await client.close()
```

<div id="streaming-files-nodejs-only">
  ## Archivos en streaming (solo Node.js)
</div>

Hay varios ejemplos de streaming de archivos con formatos de datos populares (NDJSON, CSV, Parquet) en el repositorio del cliente.

* [Streaming desde un archivo NDJSON](https://github.com/ClickHouse/clickhouse-js/blob/main/examples/node/performance/insert_file_stream_ndjson.ts)
* [Streaming desde un archivo CSV](https://github.com/ClickHouse/clickhouse-js/blob/main/examples/node/performance/insert_file_stream_csv.ts)
* [Streaming desde un archivo Parquet](https://github.com/ClickHouse/clickhouse-js/blob/main/examples/node/performance/insert_file_stream_parquet.ts)
* [Streaming a un archivo Parquet](https://github.com/ClickHouse/clickhouse-js/blob/main/examples/node/performance/select_parquet_as_file.ts)

El streaming de otros formatos a un archivo debería ser similar a la de Parquet,
la única diferencia estará en el formato utilizado en la llamada a `query` (`JSONEachRow`, `CSV`, etc.) y en el nombre del archivo de salida.

<div id="supported-data-formats">
  ## Formatos de datos compatibles
</div>

El cliente maneja formatos de datos JSON o de texto.

Si especifica `format` como uno de la familia de formatos JSON (`JSONEachRow`, `JSONCompactEachRow`, etc.), el cliente serializará y deserializará los datos durante la comunicación por la red.

Los datos proporcionados en los formatos de texto "raw" (familias `CSV`, `TabSeparated` y `CustomSeparated`) se envían por la red sin transformaciones adicionales.

<Tip>
  Puede haber confusión entre JSON como formato general y el [formato JSON de ClickHouse](/es/reference/formats/JSON/JSON).

  El cliente admite objetos JSON en streaming con formatos como [JSONEachRow](/es/reference/formats/JSON/JSONEachRow) (consulte la tabla de resumen para ver otros formatos aptos para streaming; consulte también los `select_streaming_` [ejemplos en el repositorio del cliente](https://github.com/ClickHouse/clickhouse-js/tree/main/examples/node)).

  Lo que ocurre es que formatos como [ClickHouse JSON](/es/reference/formats/JSON/JSON) y algunos otros se representan como un único objeto en la respuesta y el cliente no puede transmitirlos en streaming.
</Tip>

| Formato                                    | Entrada (array) | Entrada (objeto) | Entrada/Salida (flujo) | Salida (JSON) | Salida (texto) |
| ------------------------------------------ | --------------- | ---------------- | ---------------------- | ------------- | -------------- |
| JSON                                       | ❌               | ✔️               | ❌                      | ✔️            | ✔️             |
| JSONCompact                                | ❌               | ✔️               | ❌                      | ✔️            | ✔️             |
| JSONObjectEachRow                          | ❌               | ✔️               | ❌                      | ✔️            | ✔️             |
| JSONColumnsWithMetadata                    | ❌               | ✔️               | ❌                      | ✔️            | ✔️             |
| JSONStrings                                | ❌               | ❌️               | ❌                      | ✔️            | ✔️             |
| JSONCompactStrings                         | ❌               | ❌                | ❌                      | ✔️            | ✔️             |
| JSONEachRow                                | ✔️              | ❌                | ✔️                     | ✔️            | ✔️             |
| JSONEachRowWithProgress                    | ❌️              | ❌                | ✔️ ❗- ver abajo        | ✔️            | ✔️             |
| JSONStringsEachRow                         | ✔️              | ❌                | ✔️                     | ✔️            | ✔️             |
| JSONCompactEachRow                         | ✔️              | ❌                | ✔️                     | ✔️            | ✔️             |
| JSONCompactStringsEachRow                  | ✔️              | ❌                | ✔️                     | ✔️            | ✔️             |
| JSONCompactEachRowWithNames                | ✔️              | ❌                | ✔️                     | ✔️            | ✔️             |
| JSONCompactEachRowWithNamesAndTypes        | ✔️              | ❌                | ✔️                     | ✔️            | ✔️             |
| JSONCompactStringsEachRowWithNames         | ✔️              | ❌                | ✔️                     | ✔️            | ✔️             |
| JSONCompactStringsEachRowWithNamesAndTypes | ✔️              | ❌                | ✔️                     | ✔️            | ✔️             |
| CSV                                        | ❌               | ❌                | ✔️                     | ❌             | ✔️             |
| CSVWithNames                               | ❌               | ❌                | ✔️                     | ❌             | ✔️             |
| CSVWithNamesAndTypes                       | ❌               | ❌                | ✔️                     | ❌             | ✔️             |
| TabSeparated                               | ❌               | ❌                | ✔️                     | ❌             | ✔️             |
| TabSeparatedRaw                            | ❌               | ❌                | ✔️                     | ❌             | ✔️             |
| TabSeparatedWithNames                      | ❌               | ❌                | ✔️                     | ❌             | ✔️             |
| TabSeparatedWithNamesAndTypes              | ❌               | ❌                | ✔️                     | ❌             | ✔️             |
| CustomSeparated                            | ❌               | ❌                | ✔️                     | ❌             | ✔️             |
| CustomSeparatedWithNames                   | ❌               | ❌                | ✔️                     | ❌             | ✔️             |
| CustomSeparatedWithNamesAndTypes           | ❌               | ❌                | ✔️                     | ❌             | ✔️             |
| Parquet                                    | ❌               | ❌                | ✔️                     | ❌             | ✔️❗- ver abajo |

Para Parquet, el caso de uso principal de las consultas `select` probablemente sea escribir el flujo resultante en un archivo. Consulta [el ejemplo](https://github.com/ClickHouse/clickhouse-js/blob/main/examples/node/performance/select_parquet_as_file.ts) en el repositorio del cliente.

`JSONEachRowWithProgress` es un formato solo de salida que permite informar del progreso en el flujo. Consulta [este ejemplo](https://github.com/ClickHouse/clickhouse-js/blob/main/examples/node/performance/select_json_each_row_with_progress.ts) para obtener más detalles.

La lista completa de formatos de entrada y salida de ClickHouse está disponible
[aquí](/es/reference/formats).

<div id="supported-clickhouse-data-types">
  ## Tipos de datos de ClickHouse compatibles
</div>

<Note>
  El tipo de JS correspondiente se aplica a cualquier formato `JSON*`, excepto a los que representan todo como una cadena (p. ej., `JSONStringEachRow`)
</Note>

| Tipo                   | Estado          | tipo de JS                 |
| ---------------------- | --------------- | -------------------------- |
| UInt8/16/32            | ✔️              | number                     |
| UInt64/128/256         | ✔️ ❗- ver abajo | string                     |
| Int8/16/32             | ✔️              | number                     |
| Int64/128/256          | ✔️ ❗- ver abajo | string                     |
| Float32/64             | ✔️              | number                     |
| Decimal                | ✔️ ❗- ver abajo | number                     |
| Boolean                | ✔️              | boolean                    |
| String                 | ✔️              | string                     |
| FixedString            | ✔️              | string                     |
| UUID                   | ✔️              | string                     |
| Date32/64              | ✔️              | string                     |
| DateTime32/64          | ✔️ ❗- ver abajo | string                     |
| Enum                   | ✔️              | string                     |
| LowCardinality         | ✔️              | string                     |
| Array(T)               | ✔️              | T\[]                       |
| (new) JSON             | ✔️              | object                     |
| Variant(T1, T2...)     | ✔️              | T (depende de la variante) |
| Dynamic                | ✔️              | T (depende de la variante) |
| Nested                 | ✔️              | T\[]                       |
| Tuple(T1, T2, ...)     | ✔️              | \[T1, T2, ...]             |
| Tuple(n1 T1, n2 T2...) | ✔️              | \{ n1: T1; n2: T2; ...}    |
| Nullable(T)            | ✔️              | tipo de JS para T o null   |
| IPv4                   | ✔️              | string                     |
| IPv6                   | ✔️              | string                     |
| Point                  | ✔️              | \[ number, number ]        |
| Ring                   | ✔️              | Array\<Point>              |
| Polygon                | ✔️              | Array\<Ring>               |
| MultiPolygon           | ✔️              | Array\<Polygon>            |
| Map(K, V)              | ✔️              | Record\<K, V>              |
| Time/Time64            | ✔️              | string                     |

La lista completa de formatos compatibles de ClickHouse está disponible
[aquí](/es/reference/data-types).

Véase también:

* [Ejemplos de uso de Dynamic/Variant/JSON](https://github.com/ClickHouse/clickhouse-js/blob/main/examples/node/coding/dynamic_variant_json.ts)
* [Ejemplos de uso de Time/Time64](https://github.com/ClickHouse/clickhouse-js/blob/main/examples/node/coding/time_time64.ts)

<div id="datedate32-types-caveats">
  ### Consideraciones sobre los tipos Date/Date32
</div>

Dado que el cliente inserta valores sin conversión de tipos adicional, las columnas de tipo `Date`/`Date32` solo pueden insertarse como
cadenas.

**Ejemplo:** Insertar un valor de tipo `Date`.
[Código fuente](https://github.com/ClickHouse/clickhouse-js/blob/ba387d7f4ce375a60982ac2d99cb47391cf76cec/__tests__/integration/date_time.test.ts)

```ts theme={null}
await client.insert({
  table: 'my_table',
  values: [ { date: '2022-09-05' } ],
  format: 'JSONEachRow',
})
```

Sin embargo, si usa columnas `DateTime` o `DateTime64`, puede usar tanto cadenas como objetos `Date` de JS. Los objetos `Date` de JS pueden pasarse a `insert` tal cual, con `date_time_input_format` configurado en `best_effort`. Consulte este [ejemplo](https://github.com/ClickHouse/clickhouse-js/blob/main/examples/node/coding/insert_js_dates.ts) para más detalles.

<div id="decimal-types-caveats">
  ### Consideraciones sobre los tipos Decimal\*
</div>

Es posible insertar valores Decimal mediante formatos de la familia `JSON*`. Supongamos que tenemos una tabla definida como:

```sql theme={null}
CREATE TABLE my_table
(
  id     UInt32,
  dec32  Decimal(9, 2),
  dec64  Decimal(18, 3),
  dec128 Decimal(38, 10),
  dec256 Decimal(76, 20)
)
ENGINE MergeTree()
ORDER BY (id)
```

Podemos insertar valores sin pérdida de precisión usando la representación textual:

```ts theme={null}
await client.insert({
  table: 'my_table',
  values: [{
    id: 1,
    dec32:  '1234567.89',
    dec64:  '123456789123456.789',
    dec128: '1234567891234567891234567891.1234567891',
    dec256: '12345678912345678912345678911234567891234567891234567891.12345678911234567891',
  }],
  format: 'JSONEachRow',
})
```

Sin embargo, al consultar los datos en formatos `JSON*`, ClickHouse devolverá los valores Decimal como *números* de forma predeterminada, lo que podría ocasionar pérdida de precisión. Para evitarlo, puede convertir los valores Decimal en cadenas en la consulta:

```ts theme={null}
await client.query({
  query: `
    SELECT toString(dec32)  AS decimal32,
           toString(dec64)  AS decimal64,
           toString(dec128) AS decimal128,
           toString(dec256) AS decimal256
    FROM my_table
  `,
  format: 'JSONEachRow',
})
```

Consulta [este ejemplo](https://github.com/ClickHouse/clickhouse-js/blob/main/examples/node/coding/insert_decimals.ts) para más detalles.

<div id="integral-types-int64-int128-int256-uint64-uint128-uint256">
  ### Tipos integrales: Int64, Int128, Int256, UInt64, UInt128, UInt256
</div>

Aunque el server puede aceptarlo como un número, se devuelve como una cadena en los formatos de salida de la familia `JSON*` para evitar
el desbordamiento de enteros, ya que los valores máximos de estos tipos son mayores que `Number.MAX_SAFE_INTEGER`.

Sin embargo, este comportamiento puede modificarse
con la [configuración `output_format_json_quote_64bit_integers`](/es/reference/settings/formats#output_format_json_quote_64bit_integers)
.

**Ejemplo:** Ajuste el formato de salida JSON para números de 64 bits.

```ts theme={null}
const resultSet = await client.query({
  query: 'SELECT * from system.numbers LIMIT 1',
  format: 'JSONEachRow',
})

expect(await resultSet.json()).toEqual([ { number: '0' } ])
```

```ts theme={null}
const resultSet = await client.query({
  query: 'SELECT * from system.numbers LIMIT 1',
  format: 'JSONEachRow',
  clickhouse_settings: { output_format_json_quote_64bit_integers: 0 },
})

expect(await resultSet.json()).toEqual([ { number: 0 } ])
```

<div id="clickhouse-settings">
  ## Ajustes de ClickHouse
</div>

El cliente puede ajustar el comportamiento de ClickHouse a través del mecanismo de [ajustes](/es/reference/settings/session-settings).
Los ajustes se pueden establecer a nivel de instancia del cliente para que se apliquen a cada solicitud enviada a
ClickHouse:

```ts theme={null}
const client = createClient({
  clickhouse_settings: {}
})
```

O bien, se puede configurar un ajuste a nivel de solicitud:

```ts theme={null}
client.query({
  clickhouse_settings: {}
})
```

Puede encontrar un archivo de declaración de tipos con todos los ajustes de ClickHouse admitidos
[aquí](https://github.com/ClickHouse/clickhouse-js/blob/main/packages/client-common/src/settings.ts).

<Warning>
  Asegúrese de que el usuario en cuyo nombre se realizan las consultas tenga permisos suficientes para cambiar los ajustes.
</Warning>

<div id="advanced-topics">
  ## Temas avanzados
</div>

<div id="queries-with-parameters">
  ### Consultas con parámetros
</div>

Puede crear una consulta con parámetros y pasarles valores desde la aplicación cliente. Esto permite evitar dar formato a la
consulta con valores dinámicos específicos en el lado del cliente.

Formatee una consulta como de costumbre y, a continuación, coloque entre llaves los valores que quiera pasar desde los parámetros de la aplicación a la consulta en
el siguiente formato:

```text theme={null}
{<name>: <data_type>}
```

donde:

* `name` — Identificador del marcador de posición.
* `data_type` - [tipo de dato](/es/reference/data-types) del valor del parámetro de la aplicación.

**Ejemplo:**: Consulta con parámetros.
[Código fuente](https://github.com/ClickHouse/clickhouse-js/blob/main/examples/node/coding/query_with_parameter_binding.ts)
.

```ts theme={null}
await client.query({
  query: 'SELECT plus({val1: Int32}, {val2: Int32})',
  format: 'CSV',
  query_params: {
    val1: 10,
    val2: 20,
  },
})
```

Consulte [https://clickhouse.com/docs/interfaces/cli#cli-queries-with-parameters-syntax](https://clickhouse.com/docs/interfaces/cli#cli-queries-with-parameters-syntax) para obtener más información.

<div id="compression">
  ### Compresión
</div>

Nota: la compresión de solicitudes no está disponible actualmente en la versión web. La compresión de respuestas funciona con normalidad. La versión de Node.js admite ambas.

Las aplicaciones de datos que trabajan con grandes conjuntos de datos transmitidos por la red pueden beneficiarse de habilitar la compresión. Actualmente, solo se admite `GZIP` mediante [zlib](https://nodejs.org/docs/latest-v14.x/api/zlib.html).

```typescript theme={null}
createClient({
  compression: {
    response: true,
    request: true
  }
})
```

Los parámetros de configuración son:

* `response: true` indica al servidor de ClickHouse que devuelva un cuerpo de respuesta comprimido. Valor predeterminado: `response: false`
* `request: true` habilita la compresión en el cuerpo de la solicitud del cliente. Valor predeterminado: `request: false`

<div id="logging-nodejs-only">
  ### Registro (solo Node.js)
</div>

<Warning>
  El registro es una función experimental y está sujeto a cambios en el futuro.
</Warning>

La implementación predeterminada del logger envía registros a `stdout` mediante los métodos `console.debug/info` y a `stderr` mediante los métodos `console.warn/error`.
Puede personalizar la lógica de registro proporcionando una `LoggerClass` y elegir el nivel de registro deseado mediante el parámetro `level` (el valor predeterminado es `WARN`):

```typescript theme={null}
import type { Logger } from '@clickhouse/client'

// Los tres tipos de LogParams son exportados por el cliente
interface LogParams {
  module: string
  message: string
  args?: Record<string, unknown>
}
type ErrorLogParams = LogParams & { err: Error }
type WarnLogParams = LogParams & { err?: Error }

class MyLogger implements Logger {
  trace({ module, message, args }: LogParams) {
    // ...
  }
  debug({ module, message, args }: LogParams) {
    // ...
  }
  info({ module, message, args }: LogParams) {
    // ...
  }
  warn({ module, message, args }: WarnLogParams) {
    // ...
  }
  error({ module, message, args, err }: ErrorLogParams) {
    // ...
  }
}

const client = createClient({
  log: {
    LoggerClass: MyLogger,
    level: ClickHouseLogLevel.DEBUG,
  }
})
```

Actualmente, el cliente registrará los siguientes eventos:

* `TRACE` - información de bajo nivel sobre el ciclo de vida de los sockets Keep-Alive
* `DEBUG` - información de la respuesta (sin headers de autorización ni información del host)
* `INFO` - apenas se usa; imprimirá el nivel de log actual cuando se inicialice el cliente
* `WARN` - errores no fatales; una solicitud `ping` fallida se registra como advertencia, ya que el error subyacente se incluye en el resultado devuelto
* `ERROR` - errores fatales de los métodos `query`/`insert`/`exec`/`command`, como una solicitud fallida

Puede encontrar aquí la implementación predeterminada de Logger [aquí](https://github.com/ClickHouse/clickhouse-js/blob/main/packages/client-common/src/logger.ts).

<div id="tls-certificates-nodejs-only">
  ### Certificados TLS (solo Node.js)
</div>

El cliente de Node.js admite de forma opcional tanto TLS básico (solo autoridad de certificación)
como TLS mutuo (autoridad de certificación y certificados de cliente).

Ejemplo de configuración de TLS básico, suponiendo que tiene los certificados en la carpeta `certs`
y que el nombre del archivo de la CA es `CA.pem`:

```ts theme={null}
const client = createClient({
  url: 'https://<hostname>:<port>',
  username: '<username>',
  password: '<password>', // si es necesario
  tls: {
    ca_cert: fs.readFileSync('certs/CA.pem'),
  },
})
```

Ejemplo de configuración de TLS mutuo mediante certificados de cliente:

```ts theme={null}
const client = createClient({
  url: 'https://<hostname>:<port>',
  username: '<username>',
  tls: {
    ca_cert: fs.readFileSync('certs/CA.pem'),
    cert: fs.readFileSync(`certs/client.crt`),
    key: fs.readFileSync(`certs/client.key`),
  },
})
```

Consulte en el repositorio ejemplos completos de TLS [básico](https://github.com/ClickHouse/clickhouse-js/blob/main/examples/node/security/basic_tls.ts) y [mutuo](https://github.com/ClickHouse/clickhouse-js/blob/main/examples/node/security/mutual_tls.ts).

<div id="keep-alive-configuration-nodejs-only">
  ### Configuración de Keep-Alive (solo para Node.js)
</div>

El cliente habilita Keep-Alive de forma predeterminada en el agente HTTP subyacente, lo que significa que los sockets conectados se reutilizarán en las solicitudes posteriores y que se enviará el encabezado `Connection: keep-alive`. Los sockets inactivos permanecerán en el pool de conexiones durante 2500 milisegundos de forma predeterminada (consulta las [notas sobre cómo ajustar esta opción](/es/integrations/language-clients/js#adjusting-idle_socket_ttl)).

El valor de `keep_alive.idle_socket_ttl` debe ser bastante menor que la configuración del servidor/LB. La razón principal es que, como HTTP/1.1 permite que el servidor cierre los sockets sin notificar al cliente, si el servidor o el balanceador de carga cierra la conexión *antes* que el cliente, este podría intentar reutilizar el socket cerrado, lo que provocaría un error `socket hang up`.

Si modificas `keep_alive.idle_socket_ttl`, ten en cuenta que siempre debe estar sincronizado con la configuración de Keep-Alive de tu servidor/LB y que **siempre debe ser inferior** a esta, para garantizar que el servidor nunca cierre primero la conexión abierta.

<div id="adjusting-idle_socket_ttl">
  #### Ajuste de `idle_socket_ttl`
</div>

El cliente establece `keep_alive.idle_socket_ttl` en 2500 milisegundos, ya que puede considerarse el valor predeterminado más seguro; en el servidor, `keep_alive_timeout` puede configurarse [hasta en tan solo 3 segundos en versiones de ClickHouse anteriores a la 23.11](https://github.com/ClickHouse/ClickHouse/commit/1685cdcb89fe110b45497c7ff27ce73cc03e82d1) sin modificar `config.xml`.

<Warning>
  Si el rendimiento es satisfactorio y no experimenta ningún problema, se recomienda **no** aumentar el valor del ajuste `keep_alive.idle_socket_ttl`, ya que esto podría provocar errores de "Socket hang-up"; además, si su aplicación envía muchas consultas y apenas hay tiempo de inactividad entre ellas, el valor predeterminado debería ser suficiente, ya que los sockets no permanecerán inactivos el tiempo necesario y el cliente los mantendrá en el pool.
</Warning>

Puede encontrar el valor correcto del tiempo de espera de Keep-Alive en los encabezados de respuesta del servidor ejecutando el siguiente comando:

```sh theme={null}
curl -is --data-binary "SELECT 1" <clickhouse_url>
```

Compruebe los valores de los encabezados `Connection` y `Keep-Alive` en la respuesta. Por ejemplo:

```text theme={null}
Connection: Keep-Alive
Keep-Alive: timeout=10
```

En este caso, `keep_alive_timeout` es de 10 segundos, y puedes intentar aumentar `keep_alive.idle_socket_ttl` a 9000 o incluso 9500 milisegundos para mantener los sockets inactivos abiertos un poco más de tiempo que el valor predeterminado. Vigila posibles errores "Socket hang-up", ya que indicarán que el server cierra las connections antes que el cliente, y reduce el valor hasta que los errores desaparezcan.

<div id="troubleshooting">
  #### Resolución de problemas
</div>

Si experimenta errores `socket hang up` incluso al usar la versión más reciente del cliente, tiene las siguientes opciones para resolver este problema:

* Habilite los logs con al menos el nivel de registro `WARN` (predeterminado). Esto permitirá comprobar si hay algún stream sin consumir o colgante en el código de la aplicación: la capa de transporte lo registrará en el nivel WARN, ya que esto podría provocar que el servidor cierre el socket. Puede habilitar el registro en la configuración del cliente de la siguiente manera:

  ```ts theme={null}
  const client = createClient({
    log: { level: ClickHouseLogLevel.WARN },
  })
  ```

* Asegúrese de que la configuración deseada se aplique a la instancia correcta del cliente. Si tiene varias instancias del cliente en su aplicación, vuelva a comprobar que la que usa para las consultas tenga el valor correcto de `keep_alive.idle_socket_ttl`.

* Reduzca el ajuste `keep_alive.idle_socket_ttl` en la configuración del cliente en 500 milisegundos. En algunas situaciones, por ejemplo, cuando hay alta latencia de red entre el cliente y el servidor, esto puede ser beneficioso, ya que descarta el caso en el que una solicitud saliente obtenga un socket que el servidor está a punto de cerrar.

* Si este error se produce durante consultas de larga ejecución sin entrada ni salida de datos (por ejemplo, un `INSERT FROM SELECT` de larga duración), podría deberse a un balanceador de carga u otros componentes de red que cierran conexiones de larga duración o solicitudes prolongadas. Puede intentar forzar la entrada de algunos datos durante las consultas de larga ejecución mediante una combinación de estos ajustes de ClickHouse:

  ```ts theme={null}
  const client = createClient({
    // Aquí asumimos que tendremos algunas queries con más de 5 minutos de tiempo de ejecución
    request_timeout: 400_000,
    /** Estos ajustes en combinación permiten evitar problemas de timeout del LB en caso de queries de larga ejecución sin entrada ni salida de datos,
     *  como `INSERT FROM SELECT` y otras similares, ya que el LB podría marcar la conexión como inactiva y cerrarla abruptamente.
     *  En este caso, asumimos que el LB tiene un timeout de conexión inactiva de 120 s, por lo que establecemos 110 s como un valor "seguro". */
    clickhouse_settings: {
      send_progress_in_http_headers: 1,
      http_headers_progress_interval_ms: '110000', // UInt64, debe pasarse como una cadena
    },
  })
  ```

  Tenga en cuenta, sin embargo, que el tamaño total de los encabezados recibidos tiene un límite de 16 KB en las versiones recientes de Node.js; después de recibir cierta cantidad de encabezados de progreso, que en nuestras pruebas fue de alrededor de 70-80, se generará una excepción.

  También es posible usar un enfoque completamente distinto, evitando por completo el tiempo de espera en la red; esto puede hacerse aprovechando la "funcionalidad" de la interfaz HTTP por la cual las mutations no se cancelan cuando se pierde la conexión. Consulte [este ejemplo (parte 2)](https://github.com/ClickHouse/clickhouse-js/blob/main/examples/long_running_queries_timeouts.ts) para más detalles.

* La funcionalidad Keep-Alive puede deshabilitarse por completo. En este caso, el cliente también añadirá el encabezado `Connection: close` a cada solicitud, y el agent HTTP subyacente no reutilizará las conexiones. El ajuste `keep_alive.idle_socket_ttl` se ignorará, ya que no habrá sockets inactivos. Esto generará una sobrecarga adicional, ya que se establecerá una nueva conexión para cada solicitud.

  ```ts theme={null}
  const client = createClient({
    keep_alive: {
      enabled: false,
    },
  })
  ```

* Descarte posibles problemas con el resto de la pila de red, incluido Node.js, ejecutando una prueba sencilla desde la línea de comandos con la misma instancia de ClickHouse y la misma ruta de red (es decir, desde la misma máquina o segmento de red, por ejemplo, un pod de Kubernetes), por ejemplo, usando `curl`:

  ```sh theme={null}
  curl -is --user '<user>:<password>' --data-binary "SELECT 1" <clickhouse_url>
  ```

  Quizá quiera ejecutarlo en un bucle durante varios minutos. Si ve errores similares en `curl`, es probable que el problema no esté relacionado con la configuración del cliente, sino con la pila de red o la configuración del servidor.

* Para probar la conexión con funcionalidad nativa de Node.js, puede intentar crear una solicitud HTTP sencilla al servidor de ClickHouse usando la API integrada `fetch`:

```ts theme={null}
  const response = await fetch('<clickhouse_url>?query=SELECT+1', {
    method: 'POST',
    headers: {
      'Authorization': 'Basic ' + Buffer.from('<user>:<password>').toString('base64'),
    }
  })
```

* En algunos casos, el código de la aplicación o los adaptadores del framework pueden añadir un `ping()` preventivo antes de la ejecución real de la consulta, lo que puede dar lugar a una situación en la que la solicitud `ping()` se complete correctamente, pero la solicitud de consulta posterior falle con un error "socket hang up" debido al mismo problema subyacente con las conexiones inactivas. Si observas ese patrón en los logs, comprueba si existe alguna opción para desactivar los pings preventivos en tu framework o en el código de la aplicación. Esto también debería ayudar a reducir la probabilidad de que algún componente de red intermedio te aplique limitación de tasa.

* Asegúrate de que la propia aplicación esté recibiendo suficiente tiempo de CPU y de que la red no esté limitada por el proveedor de hosting. Distintos mecanismos de monitorización, como las métricas de pausas del GC, las métricas de retraso del event loop y otras similares, también pueden ser útiles para descartar posibles problemas de falta de recursos.

* Prueba a revisar el código de la aplicación con la regla de ESLint [no-floating-promises](https://typescript-eslint.io/rules/no-floating-promises/) habilitada, lo que ayudará a identificar promesas no gestionadas que podrían dar lugar a streams y sockets colgantes.

<div id="read-only-users">
  ### Usuarios de solo lectura
</div>

Al usar el cliente con un [usuario con readonly=1](/es/concepts/features/configuration/settings/permissions-for-queries#readonly), no se puede habilitar la compresión de la respuesta, ya que requiere el ajuste `enable_http_compression`. La siguiente configuración producirá un error:

```ts theme={null}
const client = createClient({
  compression: {
    response: true, // no funcionará con un usuario readonly=1
  },
})
```

Consulta el [ejemplo](https://github.com/ClickHouse/clickhouse-js/blob/main/examples/node/security/read_only_user.ts) para ver más detalles sobre las limitaciones de un usuario con readonly=1.

<div id="proxy-with-a-pathname">
  ### Proxy con una ruta de acceso
</div>

Si tu instancia de ClickHouse está detrás de un proxy y la URL incluye una ruta de acceso, como por ejemplo [http://proxy:8123/clickhouse\&#95;server](http://proxy:8123/clickhouse\&#95;server), especifica `clickhouse_server` como opción de configuración `pathname` (con o sin barra inicial); de lo contrario, si se proporciona directamente en la `url`, se interpretará como la opción `database`. Se admiten varios segmentos, p. ej., `/my_proxy/db`.

```ts theme={null}
const client = createClient({
  url: 'http://proxy:8123',
  pathname: '/clickhouse_server',
})
```

<div id="reverse-proxy-with-authentication">
  ### Proxy inverso con autenticación
</div>

Si tiene un proxy inverso con autenticación delante de su despliegue de ClickHouse, puede usar la configuración `http_headers` para proporcionar allí los encabezados necesarios:

```ts theme={null}
const client = createClient({
  http_headers: {
    'My-Auth-Header': '...',
  },
})
```

<div id="custom-httphttps-agent-experimental-nodejs-only">
  ### Agente HTTP/HTTPS personalizado (experimental, solo para Node.js)
</div>

<Warning>
  Esta es una característica experimental que puede cambiar de maneras incompatibles con versiones anteriores en futuras versiones. La implementación predeterminada y la configuración que proporciona el cliente deberían ser suficientes para la mayoría de los casos de uso. Usa esta característica solo si estás seguro de que la necesitas.
</Warning>

De forma predeterminada, el cliente configurará el agente HTTP o HTTPS interno con la configuración proporcionada en la configuración del cliente (como `max_open_connections`, `keep_alive.enabled`, `tls`), que se encargará de gestionar las conexiones al servidor ClickHouse. Además, si se usan certificados TLS, el agente interno se configurará con los certificados necesarios y se exigirán los encabezados de autenticación TLS correctos.

A partir de la versión 1.2.0, es posible proporcionar al cliente un agente HTTP o HTTPS personalizado para reemplazar el predeterminado. Esto puede resultar útil en configuraciones de red complejas. Si se proporciona un agente personalizado, se aplican las siguientes condiciones:

* Las opciones `max_open_connections` y `tls` *no tendrán ningún efecto* y el cliente las ignorará, ya que forman parte de la configuración del agente interno.
* `keep_alive.enabled` solo controlará el valor predeterminado del encabezado `Connection` (`true` -> `Connection: keep-alive`, `false` -> `Connection: close`).
* Aunque la gestión de sockets keep-alive inactivos seguirá funcionando (ya que no está vinculada al agente, sino a un socket concreto), ahora es posible desactivarla por completo estableciendo el valor de `keep_alive.idle_socket_ttl` en `0`.

<div id="custom-agent-usage-examples">
  #### Ejemplos de uso de agentes personalizados
</div>

Uso de un agente HTTP o HTTPS personalizado sin certificados:

```ts theme={null}
const agent = new http.Agent({ // o https.Agent
  keepAlive: true,
  keepAliveMsecs: 2500,
  maxSockets: 10,
  maxFreeSockets: 10,
})
const client = createClient({
  http_agent: agent,
})
```

Uso de un agente HTTPS personalizado con TLS básico y un certificado de CA:

```ts theme={null}
const agent = new https.Agent({
  keepAlive: true,
  keepAliveMsecs: 2500,
  maxSockets: 10,
  maxFreeSockets: 10,
  ca: fs.readFileSync('./ca.crt'),
})
const client = createClient({
  url: 'https://myserver:8443',
  http_agent: agent,
  // Con un agente HTTPS personalizado, el cliente no utilizará la implementación de conexión HTTPS predeterminada; los encabezados deben proporcionarse manualmente
  http_headers: {
    'X-ClickHouse-User': 'username',
    'X-ClickHouse-Key': 'password',
  },
  // Importante: el encabezado de autorización entra en conflicto con los encabezados TLS; desactívelo.
  set_basic_auth_header: false,
})
```

Uso de un agente HTTPS personalizado con TLS mutuo:

```ts theme={null}
const agent = new https.Agent({
  keepAlive: true,
  keepAliveMsecs: 2500,
  maxSockets: 10,
  maxFreeSockets: 10,
  ca: fs.readFileSync('./ca.crt'),
  cert: fs.readFileSync('./client.crt'),
  key: fs.readFileSync('./client.key'),
})
const client = createClient({
  url: 'https://myserver:8443',
  http_agent: agent,
  // Con un agente HTTPS personalizado, el cliente no utilizará la implementación de conexión HTTPS predeterminada; los encabezados deben proporcionarse manualmente
  http_headers: {
    'X-ClickHouse-User': 'username',
    'X-ClickHouse-Key': 'password',
    'X-ClickHouse-SSL-Certificate-Auth': 'on',
  },
  // Importante: el encabezado de autorización entra en conflicto con los encabezados TLS; desactívelo.
  set_basic_auth_header: false,
})
```

Con certificados *y* un agente *HTTPS* personalizado, es probable que sea necesario desactivar el encabezado de autorización predeterminado mediante la configuración `set_basic_auth_header` (introducida en la versión 1.2.0), ya que entra en conflicto con los encabezados TLS. Todos los encabezados TLS deben proporcionarse manualmente.

<div id="known-limitations-nodejsweb">
  ## Limitaciones conocidas (Node.js/web)
</div>

* No hay mapeadores de datos para los conjuntos de resultados, por lo que solo se utilizan primitivas del lenguaje. Está previsto añadir determinados mapeadores de tipos de datos con [compatibilidad con RowBinary format](https://github.com/ClickHouse/clickhouse-js/issues/216).
* Hay algunas [consideraciones sobre los tipos de datos Decimal\* y Date\* / DateTime\*](/es/integrations/language-clients/js#datedate32-types-caveats).
* Al usar formatos de la familia JSON\*, los números mayores que Int32 se representan como cadenas, ya que los valores máximos de los tipos Int64+ son superiores a `Number.MAX_SAFE_INTEGER`. Consulta la sección [tipos integrales](/es/integrations/language-clients/js#integral-types-int64-int128-int256-uint64-uint128-uint256) para obtener más información.

<div id="known-limitations-web">
  ## Limitaciones conocidas (web)
</div>

* El streaming para las consultas SELECT funciona, pero está deshabilitado para las inserciones (también a nivel de tipo).
* La compresión de las solicitudes está deshabilitada y la configuración se ignora. La compresión de las respuestas funciona.
* Aún no hay soporte para registro.

<div id="tips-for-performance-optimizations">
  ## Consejos para optimizar el rendimiento
</div>

* Para reducir el consumo de memoria de la aplicación, considere usar streams para `insert` grandes (p. ej., desde archivos) y consultas, cuando corresponda. Para listeners de eventos y casos de uso similares, [async inserts](/es/concepts/features/operations/insert/asyncinserts) pueden ser otra buena opción, ya que permiten minimizar o incluso evitar por completo la agrupación en lotes del lado del cliente. Hay ejemplos de async insert disponibles en el [repositorio del cliente](https://github.com/ClickHouse/clickhouse-js/tree/main/examples/node), con `async_insert_` como prefijo del nombre de archivo.
* El cliente no habilita la compresión de solicitudes ni de respuestas de forma predeterminada. Sin embargo, al consultar o insertar conjuntos de datos grandes, podría considerar habilitarla mediante `ClickHouseClientConfigOptions.compression` (ya sea solo para `request` o `response`, o para ambos).
* La compresión tiene un impacto significativo en el rendimiento. Habilitarla para `request` o `response` afectará negativamente a la velocidad de las consultas o de los `insert`, respectivamente, pero reducirá la cantidad de tráfico de red transferido por la aplicación.

<div id="contact-us">
  ## Contáctanos
</div>

Si tienes alguna pregunta o necesitas ayuda, no dudes en ponerte en contacto con nosotros en el [Slack de la comunidad](https://clickhouse.com/slack) (canal `#clickhouse-js`) o a través de [issues de GitHub](https://github.com/ClickHouse/clickhouse-js/issues).
