Files
Gemini-Search/node_modules/@neondatabase/serverless/CONFIG.md
Ammaar Reshi d6025af146 Initial commit
2025-01-04 14:06:53 +00:00

312 lines
13 KiB
Markdown

# Options and configuration
## `neon(...)` function
The `neon(...)` function returns a query function that can be used both as a tagged-template function and as an ordinary function:
```typescript
import { neon } from '@neondatabase/serverless';
const sql = neon(process.env.DATABASE_URL);
// as a tagged-template function
const rowsA = await sql`SELECT * FROM posts WHERE id = ${postId}`;
// as an ordinary function (exactly equivalent)
const rowsB = await sql('SELECT * FROM posts WHERE id = $1', [postId]);
```
By default, the query function returned by `neon(...)` returns only the rows resulting from the provided SQL query, and it returns them as an array of objects where the keys are column names. For example:
```typescript
import { neon } from '@neondatabase/serverless';
const sql = neon(process.env.DATABASE_URL);
const rows = await sql`SELECT * FROM posts WHERE id = ${postId}`;
// -> [{ id: 12, title: "My post", ... }]
```
However, you can customise the return format of the query function using the configuration options `fullResults` and `arrayMode`. These options are available both on the `neon(...)` function and on the query function it returns (but only when the query function is called as an ordinary function, not as a tagged-template function).
### `arrayMode: boolean`
When `arrayMode` is true, rows are returned as an array of arrays instead of an array of objects:
```typescript
import { neon } from '@neondatabase/serverless';
const sql = neon(process.env.DATABASE_URL, { arrayMode: true });
const rows = await sql`SELECT * FROM posts WHERE id = ${postId}`;
// -> [[12, "My post", ...]]
```
Or, with the same effect:
```typescript
import { neon } from '@neondatabase/serverless';
const sql = neon(process.env.DATABASE_URL);
const rows = await sql('SELECT * FROM posts WHERE id = $1', [postId], {
arrayMode: true,
});
// -> [[12, "My post", ...]]
```
### `fullResults: boolean`
When `fullResults` is true, additional metadata is returned alongside the result rows, which are then found in the `rows` property of the return value. The metadata matches what would be returned by node-postgres:
```typescript
import { neon } from '@neondatabase/serverless';
const sql = neon(process.env.DATABASE_URL, { fullResults: true });
const results = await sql`SELECT * FROM posts WHERE id = ${postId}`;
/* -> {
rows: [{ id: 12, title: "My post", ... }],
fields: [
{ name: "id", dataTypeID: 23, ... },
{ name: "title", dataTypeID: 25, ... },
...
],
rowCount: 1,
rowAsArray: false,
command: "SELECT"
}
*/
```
Or, with the same effect:
```typescript
import { neon } from '@neondatabase/serverless';
const sql = neon(process.env.DATABASE_URL);
const results = await sql('SELECT * FROM posts WHERE id = $1', [postId], {
fullResults: true,
});
// -> { ... same as above ... }
```
### `fetchOptions: Record<string, any>`
The `fetchOptions` option can be passed to `neon(...)`, the `transaction` function, or the query function (if not within a `transaction` function). This option takes an object that is merged with the options to the `fetch` call.
For example, to increase the priority of every database `fetch` request:
```typescript
import { neon } from '@neondatabase/serverless';
const sql = neon(process.env.DATABASE_URL, {
fetchOptions: { priority: 'high' },
});
const rows = await sql`SELECT * FROM posts WHERE id = ${postId}`;
```
Or to implement a `fetch` timeout:
```typescript
import { neon } from '@neondatabase/serverless';
const sql = neon(process.env.DATABASE_URL);
const abortController = new AbortController();
const timeout = setTimeout(() => abortController.abort('timed out'), 10000);
const rows = await sql('SELECT * FROM posts WHERE id = $1', [postId], {
fetchOptions: { signal: abortController.signal },
}); // throws an error if no result received within 10s
clearTimeout(timeout);
```
### `authToken: string | (() => Promise<string> | string)`
The `authToken` option can be passed to `neon(...)` to set the `Authorization` header for the `fetch` request. This allows you to authenticate database requests against third-party authentication providers. So, this mechanism can be used to ensure that access control and authorization are managed effectively across different systems.
Example of usage:
```typescript
import { neon } from '@neondatabase/serverless';
// Retrieve the JWT token (implementation depends on your auth system)
const authToken = getAuthToken();
// Initialize the Neon client with a connection string and auth token
const sql = neon(process.env.DATABASE_URL, { authToken });
// Run a query
const posts = await sql('SELECT * FROM posts');
```
## `transaction(...)` function
The `transaction(queriesOrFn, options)` function is exposed as a property on the query function. It allows multiple queries to be executed within a single, non-interactive transaction.
The first argument to `transaction()`, `queriesOrFn`, is either (1) an array of queries or (2) a non-`async` function that receives a query function as its argument and returns an array of queries.
The array-of-queries case looks like this:
```javascript
import { neon } from '@neondatabase/serverless';
const sql = neon(process.env.DATABASE_URL);
const showLatestN = 10;
const [posts, tags] = await sql.transaction(
[
sql`SELECT * FROM posts ORDER BY posted_at DESC LIMIT ${showLatestN}`,
sql`SELECT * FROM tags`,
],
{
isolationLevel: 'RepeatableRead',
readOnly: true,
},
);
```
Or as an example of the function case:
```javascript
const [authors, tags] = await neon(process.env.DATABASE_URL).transaction(
(txn) => [txn`SELECT * FROM authors`, txn`SELECT * FROM tags`],
);
```
The optional second argument to `transaction()`, `options`, has the same keys as the options to the ordinary query function -- `arrayMode`, `fullResults` and `fetchOptions` -- plus three additional keys that concern the transaction configuration. These transaction-related keys are: `isolationMode`, `readOnly` and `deferrable`. They are described below. Defaults for the transaction-related keys can also be set as options to the `neon` function.
The `fetchOptions` option cannot be supplied for individual queries inside `transaction()`, since only a single `fetch` is performed for the transaction as a whole. The TypeScript types also currently do not allow `arrayMode` or `fullResults` options to be supplied for individual queries within `transaction()` (although this does have the expected effect if the type errors are ignored).
### `isolationMode`
This option selects a Postgres [transaction isolation mode](https://www.postgresql.org/docs/current/transaction-iso.html). If present, it must be one of: `'ReadUncommitted'`, `'ReadCommitted'`, `'RepeatableRead'` or `'Serializable'`.
### `readOnly`
If `true`, this option ensures that a `READ ONLY` transaction is used to execute the queries passed.
### `deferrable`
If `true` (and if `readOnly` is also `true`, and `isolationMode` is `'Serializable'`), this option ensures that a `DEFERRABLE` transaction is used to execute the queries passed.
## `neonConfig` configuration
In most cases, there are two ways to set configuration options:
1. Import `neonConfig` from the package and set global default options on that.
2. Set options on individual `Client` instances using their `neonConfig` property.
For example:
```javascript
import { Client, neonConfig } from '@neondatabase/serverless';
import ws from 'ws';
// set default option for all clients
neonConfig.webSocketConstructor = ws;
// override the default option on an individual client
const client = new Client(process.env.DATABASE_URL);
client.neonConfig.webSocketConstructor = ws;
```
A few configuration options can only be set globally, and these are noted as such below.
#### `webSocketConstructor: typeof WebSocket | undefined`
Set this parameter if you're using the driver in an environment where the `WebSocket` global is not defined, such as Node.js, and you need transaction or session support.
For example:
```javascript
import { neonConfig } from '@neondatabase/serverless';
import ws from 'ws';
neonConfig.webSocketConstructor = ws;
```
### Advanced configuration
If you're using `@neondatabase/serverless` to connect to a Neon database, you usually **won't** need to touch the following configuration options. These options are intended for testing, troubleshooting, and supporting access to non-Neon Postgres instances via self-hosted WebSocket proxies.
#### `poolQueryViaFetch: boolean`
**Experimentally**, when `poolQueryViaFetch` is `true` and no listeners for the `"connect"`, `"acquire"`, `"release"` or `"remove"` events are set on the `Pool`, queries via `Pool.query()` will be sent by low-latency HTTP `fetch` request.
Default: currently `false` (but may be `true` in future).
Note: this option can only be set globally, **not** on an individual `Client` instance.
#### `fetchEndpoint: string | ((host: string, port: number | string) => string)`
Set `fetchEndpoint` to set the server endpoint to be sent queries via http fetch.
This may be useful for local development (e.g. to set a port that's not the default 443).
Provide either the full endpoint URL, or a function that takes the database host address and port and returns the full endpoint URL (including protocol).
Default: `host => 'https://' + host + '/sql'`
Note: this option can only be set globally, **not** on an individual `Client` instance.
#### `fetchFunction: any`
The `fetchFunction` option allows you to supply an alternative function for making http requests. The function must accept the same arguments as native `fetch`.
Default: `undefined`.
Note: this option can only be set globally, **not** on an individual `Client` instance.
#### `wsProxy: string | (host: string, port: number | string) => string`
If connecting to a non-Neon database, the `wsProxy` option should point to [your WebSocket proxy](DEPLOY.md). It can either be a string, which will have `?address=host:port` appended to it, or a function with the signature `(host: string, port: number | string) => string`. Either way, the protocol must _not_ be included, because this depends on other options. For example, when using the `wsproxy` proxy, the `wsProxy` option should look something like this:
```javascript
// either:
neonConfig.wsProxy = (host, port) =>
`my-wsproxy.example.com/v1?address=${host}:${port}`;
// or (with identical effect):
neonConfig.wsProxy = 'my-wsproxy.example.com/v1';
```
Default: `host => host + '/v2'`.
#### `pipelineConnect: "password" | false`
To speed up connection times, the driver will pipeline the first three messages to the database (startup, authentication and first query) if `pipelineConnect` is set to `"password"`. Note that this will only work if you've configured cleartext password authentication for the relevant user and database.
If your connection doesn't support password authentication, set `pipelineConnect` to `false` instead.
Default: `"password"`.
#### `coalesceWrites: boolean`
When this option is `true`, multiple network writes generated in a single iteration of the JavaScript run-loop are coalesced into a single WebSocket message. Since node-postgres sends a lot of very short messages, this may reduce TCP/IP overhead.
Default: `true`.
#### `forceDisablePgSSL: boolean`
This option disables TLS encryption in the Postgres protocol (as set via e.g. `?sslmode=require` in the connection string). Security is not compromised if used in conjunction with `useSecureWebSocket = true`.
Default: `true`.
#### `useSecureWebSocket: boolean`
This option switches between secure (the default) and insecure WebSockets.
To use experimental pure-JS encryption, set `useSecureWebSocket = false` and `forceDisablePgSSL = false`, and append `?sslmode=verify-full` to your database connection string.
**Remember that pure-JS encryption is currently experimental and not suitable for use in production.**
Default: `true`.
#### `subtls: any`
**Only when using experimental pure-JS TLS encryption**, you must supply the [subtls](https://github.com/jawj/subtls) TLS library to the `subtls` option like so:
```typescript
import { neonConfig } from '@neondatabase/serverless';
import * as subtls from 'subtls';
neonConfig.subtls = subtls;
```
Default: `undefined`.
#### `rootCerts: string /* PEM format */`
**Only when using experimental pure-JS TLS encryption**, the `rootCerts` option determines what root (certificate authority) certificates are trusted.
Its value is a string containing zero or more certificates in PEM format.
Default: `""` (the empty string).
#### `pipelineTLS: boolean`
**Only when using experimental pure-JS encryption**, the driver will pipeline the SSL request message and TLS Client Hello if `pipelineTLS` is set to `true`. Currently, this is only supported by Neon database hosts, and will fail when communicating with an ordinary Postgres or pgbouncer back-end.
Default: `false`.