diff --git a/CHANGELOG.md b/CHANGELOG.md index c57ada5f..ac759c5c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,16 +4,38 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/#semantic-versioning-200). -## [Unreleased] +## [3.0.0] - 2026-08-20 + +### :boom: Breaking Changes + +- `clusterId` is no longer derived automatically, and applications that connect to more than one database cluster must now set it explicitly. Previously the wrapper generated a cluster id from the connection URL and, for AWS RDS clusters, converged connections made through instance endpoints, IP addresses or custom domains onto the cluster endpoint's id. That derivation, along with the suggested and primary cluster id caches, has been removed: `clusterId` is now taken only from the configuration parameter and defaults to `1` for every connection. An application that connects to several clusters without setting a distinct `clusterId` per cluster will have all of them share the same topology cache and monitor entries, which leads to incorrect topology and failover to the wrong cluster. Give every cluster its own value, and use the same value for every connection to a given cluster. See [Cluster ID](https://github.com/aws/aws-advanced-nodejs-wrapper/blob/main/docs/using-the-nodejs-wrapper/ClusterId.md). +- Optional runtime dependencies are no longer installed for you. `@opentelemetry/api`, `http-cookie-agent` and `tough-cookie` moved from `dependencies` to optional `peerDependencies`, and the OpenTelemetry SDK packages (`@opentelemetry/context-async-hooks`, `@opentelemetry/resources`, `@opentelemetry/sdk-trace-base`, `@opentelemetry/semantic-conventions`) are no longer declared by the wrapper at all. Applications that use telemetry, or the [Federated Authentication](https://github.com/aws/aws-advanced-nodejs-wrapper/blob/main/docs/using-the-nodejs-wrapper/using-plugins/UsingTheFederatedAuthPlugin.md) and [Okta Authentication](https://github.com/aws/aws-advanced-nodejs-wrapper/blob/main/docs/using-the-nodejs-wrapper/using-plugins/UsingTheOktaAuthPlugin.md) plugins, must add the packages they need to their own dependencies. +- Client constructors are typed. `AwsPgClient`, `AwsPgPoolClient`, `AwsMySQLClient` and `AwsMySQLPoolClient` now accept `AwsPgClientConfig` / `AwsMySQLClientConfig` in place of `any`, so TypeScript rejects unknown or misspelled connection properties at compile time. This is a compile-time change only; runtime behaviour is unchanged. Configurations that relied on the untyped parameter may need corrections. +- `any` has been removed from the external API. Most visibly, `query()` on the MySQL clients now resolves to `[T, FieldPacket[]]` rather than `[T, any]`. Code that consumed those results loosely may need type updates. + +### :magic_wand: Added + +- Support for [Amazon Aurora Global Databases](https://github.com/aws/aws-advanced-nodejs-wrapper/blob/main/docs/using-the-nodejs-wrapper/GlobalDatabases.md), including in-region and cross-region failover, global writer endpoint recognition and stale DNS handling. +- [Global Database Failover Plugin](https://github.com/aws/aws-advanced-nodejs-wrapper/blob/main/docs/using-the-nodejs-wrapper/using-plugins/UsingTheGlobalDbFailoverPlugin.md), which adds the notion of a home region and lets failover behaviour be configured separately for the in-home and out-of-home cases. +- [Global Database Read/Write Splitting Plugin](https://github.com/aws/aws-advanced-nodejs-wrapper/blob/main/docs/using-the-nodejs-wrapper/using-plugins/UsingTheGlobalDbReadWriteSplittingPlugin.md), which can constrain new connections to a home region. +- [Restricting Aurora Global Database access by region](https://github.com/aws/aws-advanced-nodejs-wrapper/blob/main/docs/using-the-nodejs-wrapper/using-plugins/UsingGlobalAuroraAccessibleRegions.md) with the `gdbAccessibleRegions` parameter. +- [Monitoring connection priority](https://github.com/aws/aws-advanced-nodejs-wrapper/blob/main/docs/using-the-nodejs-wrapper/using-plugins/UsingMonitoringConnectionPriority.md), which directs the topology monitor's connection to a preferred host type or region. +- Exported configuration types `AwsClientConfig`, `AwsPgClientConfig` and `AwsMySQLClientConfig`. ### :crab: Changed - Renamed the PostgreSQL client to `AwsPgClient` and its pooled connection type to `AwsPgPooledConnection` for consistent `Pg` casing across the `pg` module. This is a non-breaking change. +- PostgreSQL dialect queries are now schema-qualified, so they resolve correctly regardless of the session `search_path`. ### :warning: Deprecated - `AwsPGClient` and `AwsPGPooledConnection` are now deprecated. They remain exported as backwards-compatible aliases of `AwsPgClient` and `AwsPgPooledConnection` and behave identically, so existing code continues to work without modification. Update imports to the new names; the deprecated aliases are scheduled for removal in the next major release. +### :bug: Fixed + +- IAM, Federated Authentication and Okta authentication now work against Aurora MySQL. Aurora asks a token-authenticated user for the `mysql_clear_password` authentication plugin, which the underlying driver refuses unless `enableCleartextPlugin` is set; the wrapper now enables it when a token-based authentication plugin is in use and the connection is encrypted. See [MySQL requires an encrypted connection](https://github.com/aws/aws-advanced-nodejs-wrapper/blob/main/docs/using-the-nodejs-wrapper/using-plugins/UsingTheIamAuthenticationPlugin.md#mysql-requires-an-encrypted-connection). +- Failover is now triggered by read-only connection errors when using `strict-writer` failover mode. + ## [2.1.1] - 2026-05-28 ### :magic_wand: Added @@ -119,6 +141,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), The Amazon Web Services (AWS) Advanced NodeJS Wrapper allows an application to take advantage of the features of clustered Aurora databases. +[3.0.0]: https://github.com/aws/aws-advanced-nodejs-wrapper/compare/2.1.1...3.0.0 [2.1.1]: https://github.com/aws/aws-advanced-nodejs-wrapper/compare/2.1.0...2.1.1 [2.1.0]: https://github.com/aws/aws-advanced-nodejs-wrapper/compare/2.0.1...2.1.0 [2.0.1]: https://github.com/aws/aws-advanced-nodejs-wrapper/compare/2.0.0...2.0.1 diff --git a/MAINTENANCE.md b/MAINTENANCE.md index efdd35c5..c719683d 100644 --- a/MAINTENANCE.md +++ b/MAINTENANCE.md @@ -10,6 +10,7 @@ | Oct 17 2025 | [Release 2.0.1](https://github.com/aws/aws-advanced-nodejs-wrapper/releases/tag/2.0.1) | | Jan 15 2026 | [Release 2.1.0](https://github.com/aws/aws-advanced-nodejs-wrapper/releases/tag/2.1.0) | | May 28 2026 | [Release 2.1.1](https://github.com/aws/aws-advanced-nodejs-wrapper/releases/tag/2.1.1) | +| Aug 20 2026 | [Release 3.0.0](https://github.com/aws/aws-advanced-nodejs-wrapper/releases/tag/3.0.0) | `aws-advanced-nodejs-wrapper` [follows semver](https://semver.org/#semantic-versioning-200) which means we will only release breaking changes in major versions. Generally speaking patches will be released to fix existing problems without @@ -62,4 +63,5 @@ from the updated source after the PRs are merged. | Major Version | Latest Minor Version | Status | Initial Release | Maintenance Window Start | Maintenance Window End | | ------------- | -------------------- | ----------- | --------------- | ------------------------ | ---------------------- | | 1 | 1.3.0 | Maintenance | Nov 19, 2024 | Sep 11, 2025 | Sep 11, 2026 | -| 2 | 2.1.1 | Current | Sep 11, 2025 | N/A | N/A | +| 2 | 2.1.1 | Maintenance | Sep 11, 2025 | Aug 20, 2026 | Aug 20, 2027 | +| 3 | 3.0.0 | Current | Aug 20, 2026 | N/A | N/A | diff --git a/common/lib/wrapper_property.ts b/common/lib/wrapper_property.ts index 7b999514..7effd64a 100644 --- a/common/lib/wrapper_property.ts +++ b/common/lib/wrapper_property.ts @@ -102,7 +102,7 @@ export interface AwsClientConfig { clusterTopologyRefreshRateMs?: number; /** Cluster topology high refresh rate in millis. */ clusterTopologyHighRefreshRateMs?: number; - /** A unique identifier for the cluster. Connections with the same cluster id share a cluster topology cache. If unspecified, a cluster id is automatically created for AWS RDS clusters. */ + /** A unique identifier for the cluster. Connections with the same cluster id share a cluster topology cache. If unspecified, the cluster id is '1'. Applications connecting to more than one cluster must set a distinct value for each cluster. */ clusterId?: string; /** The cluster instance DNS pattern that will be used to build a complete instance endpoint. A "?" character in this pattern should be used as a placeholder for cluster instance names. This pattern is required to be specified for IP address or custom domain connections to AWS RDS clusters. Otherwise, if unspecified, the pattern will be automatically created for AWS RDS clusters. */ clusterInstanceHostPattern?: string; diff --git a/docs/using-the-nodejs-wrapper/UsingTheNodejsWrapper.md b/docs/using-the-nodejs-wrapper/UsingTheNodejsWrapper.md index 0d18b09c..2d26a8e1 100644 --- a/docs/using-the-nodejs-wrapper/UsingTheNodejsWrapper.md +++ b/docs/using-the-nodejs-wrapper/UsingTheNodejsWrapper.md @@ -43,24 +43,25 @@ To enable logging when using the AWS Advanced NodeJS Wrapper, use the `LOG_LEVEL These parameters are applicable to any instance of the AWS Advanced NodeJS Wrapper. -| Parameter | Value | Required | Description | Default Value | Version Supported | -| ------------------------------------ | ------------------ | -------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------- | -| `host` | `string` | No | Database host. | `null` | `latest` | -| `database` | `string` | No | Database name. | `null` | `latest` | -| `user` | `string` | No | Database username. | `null` | `latest` | -| `password` | `string` | No | Database password. | `null` | `latest` | -| `transferSessionStateOnSwitch` | `boolean` | No | Enables transferring the session state to a new connection. | `true` | `latest` | -| `resetSessionStateOnClose` | `boolean` | No | Enables resetting the session state before closing connection. | `true` | `latest` | -| `enableGreenHostReplacement` | `boolean` | No | Enables replacing a green node host name with the original host name when the green host DNS doesn't exist anymore after a blue/green switchover. Refer to [Overview of Amazon RDS Blue/Green Deployments](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/blue-green-deployments-overview.html) for more details about green and blue nodes. | `false` | `latest` | -| `clusterInstanceHostPattern` | `string` | If connecting using an IP address or custom domain URL: Yes

Otherwise: No | This parameter is not required unless connecting to an AWS RDS cluster via an IP address or custom domain URL. In those cases, this parameter specifies the cluster instance DNS pattern that will be used to build a complete instance endpoint. A "?" character in this pattern should be used as a placeholder for the DB instance identifiers of the instances in the cluster. See [here](#host-pattern) for more information.

Example: `?.my-domain.com`, `any-subdomain.?.my-domain.com`

Use case Example: If your cluster instance endpoints follow this pattern:`instanceIdentifier1.customHost`, `instanceIdentifier2.customHost`, etc. and you want your initial connection to be to `customHost:1234`, then your client configuration should look like this: `{ host: "customHost", port: 1234, database: "test", clusterInstanceHostPattern: "?.customHost" }` | If the provided host is not an IP address or custom domain, the NodeJS Wrapper will automatically acquire the cluster instance host pattern from the customer-provided host. | `latest` | -| ~~`mysqlQueryTimeout`~~ | `number` | No | This parameter has been deprecated since version 1.1.0, applications should use the `wrapperQueryTimeout` parameter instead.

Query timeout in milliseconds. This is only applicable when using the AwsMySQLClient. To set query timeout for the AwsPgClient, please use the built-in `query_timeout` parameter. See the `node-postgres` [documentation](https://node-postgres.com/apis/client) for more details. | 20000 | `1.0.0` | -| `wrapperConnectTimeout` | `number` | No | Connect timeout in milliseconds. This parameter will apply the provided timeout value to the underlying driver's built-in connect timeout parameter, if there is one available. | 20000 | `latest` | -| `wrapperQueryTimeout` | `number` | No | Query timeout in milliseconds. This parameter will apply the provided timeout value to the underlying driver's built-in query timeout parameter, if there is one available. The wrapper will also use this value for its own query timeout implementation. | 20000 | `latest` | -| `wrapperKeepAliveProperties` | `Map` | No | If the underlying target driver has keepAlive properties available, properties within this map will be applied to the underlying target driver's client configuration. For example, the node-postgres driver's `keepAlive` and `keepAliveInitialDelayMillis` properties can be configured by setting this property in the client configuration: `{ wrapperKeepAliveProperties: new Map([["keepAlive", true], ["keepAliveInitialDelayMillis", 1234]]) }`.

Currently supported drivers: node-postgres | `null` | -| `awsProfile` | `string` | No | Allows users to specify a profile name for AWS credentials. This parameter is used by plugins that require AWS credentials, like the [AWS IAM Authentication Plugin](./using-plugins/UsingTheIamAuthenticationPlugin.md) and the [AWS Secrets Manager Plugin](./using-plugins/UsingTheAwsSecretsManagerPlugin.md). | `null` | -| `connectionProvider` | `object` | No | Allows users to specify a connection provider used to create connections. Provided value should be an object that implements `ConnectionProvider` interface. | `null` | -| `customDatabaseDialect` | `object` | No | Allows users to specify a custom database dialect. Provided value should be an object that implements `DatabaseDialect` interface. | `null` | -| `customAwsCredentialProviderHandler` | `object` | No | Allows users to specify a custom AWS credentials provider. This parameter is used by plugins that require AWS credentials, like the [AWS IAM Authentication Plugin](./using-plugins/UsingTheIamAuthenticationPlugin.md) and the [AWS Secrets Manager Plugin](./using-plugins/UsingTheAwsSecretsManagerPlugin.md). For more information see [AWS Credentials Provider Configuration](./custom-configuration/AwsCredentialsConfiguration.md). | `null` | +| Parameter | Value | Required | Description | Default Value | Version Supported | +| ------------------------------------ | ------------------ | ------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------- | +| `host` | `string` | No | Database host. | `null` | `latest` | +| `database` | `string` | No | Database name. | `null` | `latest` | +| `user` | `string` | No | Database username. | `null` | `latest` | +| `password` | `string` | No | Database password. | `null` | `latest` | +| `transferSessionStateOnSwitch` | `boolean` | No | Enables transferring the session state to a new connection. | `true` | `latest` | +| `resetSessionStateOnClose` | `boolean` | No | Enables resetting the session state before closing connection. | `true` | `latest` | +| `enableGreenHostReplacement` | `boolean` | No | Enables replacing a green node host name with the original host name when the green host DNS doesn't exist anymore after a blue/green switchover. Refer to [Overview of Amazon RDS Blue/Green Deployments](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/blue-green-deployments-overview.html) for more details about green and blue nodes. | `false` | `latest` | +| `clusterId` | `string` | If connecting to multiple database clusters within a single application: Yes

Otherwise: No | A unique identifier for the cluster. The wrapper uses this value as the key for its topology cache and monitoring services, so all connections sharing a `clusterId` share the cached topology and the monitors for that cluster. This parameter is optional when the application connects to a single cluster. When the application connects to more than one cluster it becomes mandatory: each cluster must be given a distinct value, and every connection to a given cluster must use the same value, otherwise the clusters collide in the cache and failover can target the wrong cluster. The value can be any string or number.

Examples: `1`, `2`, `1234`, `abc-1`, `abc-2`

See [Cluster ID](./ClusterId.md) for details. | `1` | `latest` | +| `clusterInstanceHostPattern` | `string` | If connecting using an IP address or custom domain URL: Yes

Otherwise: No | This parameter is not required unless connecting to an AWS RDS cluster via an IP address or custom domain URL. In those cases, this parameter specifies the cluster instance DNS pattern that will be used to build a complete instance endpoint. A "?" character in this pattern should be used as a placeholder for the DB instance identifiers of the instances in the cluster. See [here](#host-pattern) for more information.

Example: `?.my-domain.com`, `any-subdomain.?.my-domain.com`

Use case Example: If your cluster instance endpoints follow this pattern:`instanceIdentifier1.customHost`, `instanceIdentifier2.customHost`, etc. and you want your initial connection to be to `customHost:1234`, then your client configuration should look like this: `{ host: "customHost", port: 1234, database: "test", clusterInstanceHostPattern: "?.customHost" }` | If the provided host is not an IP address or custom domain, the NodeJS Wrapper will automatically acquire the cluster instance host pattern from the customer-provided host. | `latest` | +| ~~`mysqlQueryTimeout`~~ | `number` | No | This parameter has been deprecated since version 1.1.0, applications should use the `wrapperQueryTimeout` parameter instead.

Query timeout in milliseconds. This is only applicable when using the AwsMySQLClient. To set query timeout for the AwsPgClient, please use the built-in `query_timeout` parameter. See the `node-postgres` [documentation](https://node-postgres.com/apis/client) for more details. | 20000 | `1.0.0` | +| `wrapperConnectTimeout` | `number` | No | Connect timeout in milliseconds. This parameter will apply the provided timeout value to the underlying driver's built-in connect timeout parameter, if there is one available. | 20000 | `latest` | +| `wrapperQueryTimeout` | `number` | No | Query timeout in milliseconds. This parameter will apply the provided timeout value to the underlying driver's built-in query timeout parameter, if there is one available. The wrapper will also use this value for its own query timeout implementation. | 20000 | `latest` | +| `wrapperKeepAliveProperties` | `Map` | No | If the underlying target driver has keepAlive properties available, properties within this map will be applied to the underlying target driver's client configuration. For example, the node-postgres driver's `keepAlive` and `keepAliveInitialDelayMillis` properties can be configured by setting this property in the client configuration: `{ wrapperKeepAliveProperties: new Map([["keepAlive", true], ["keepAliveInitialDelayMillis", 1234]]) }`.

Currently supported drivers: node-postgres | `null` | +| `awsProfile` | `string` | No | Allows users to specify a profile name for AWS credentials. This parameter is used by plugins that require AWS credentials, like the [AWS IAM Authentication Plugin](./using-plugins/UsingTheIamAuthenticationPlugin.md) and the [AWS Secrets Manager Plugin](./using-plugins/UsingTheAwsSecretsManagerPlugin.md). | `null` | +| `connectionProvider` | `object` | No | Allows users to specify a connection provider used to create connections. Provided value should be an object that implements `ConnectionProvider` interface. | `null` | +| `customDatabaseDialect` | `object` | No | Allows users to specify a custom database dialect. Provided value should be an object that implements `DatabaseDialect` interface. | `null` | +| `customAwsCredentialProviderHandler` | `object` | No | Allows users to specify a custom AWS credentials provider. This parameter is used by plugins that require AWS credentials, like the [AWS IAM Authentication Plugin](./using-plugins/UsingTheIamAuthenticationPlugin.md) and the [AWS Secrets Manager Plugin](./using-plugins/UsingTheAwsSecretsManagerPlugin.md). For more information see [AWS Credentials Provider Configuration](./custom-configuration/AwsCredentialsConfiguration.md). | `null` | ## Host Pattern diff --git a/examples/javascript_example/package.json b/examples/javascript_example/package.json index fffd48eb..80808c11 100644 --- a/examples/javascript_example/package.json +++ b/examples/javascript_example/package.json @@ -8,7 +8,7 @@ "start": "node index.js" }, "dependencies": { - "aws-advanced-nodejs-wrapper": "^2.1.1", + "aws-advanced-nodejs-wrapper": "^3.0.0", "pg": "^8.11.0" } } diff --git a/examples/prisma_example/package.json b/examples/prisma_example/package.json index cf517067..ae7bbfdb 100644 --- a/examples/prisma_example/package.json +++ b/examples/prisma_example/package.json @@ -18,7 +18,7 @@ "dependencies": { "@prisma/client": "6.0.0", "@prisma/driver-adapter-utils": "^6.0.0", - "aws-advanced-nodejs-wrapper": "^2.1.1", + "aws-advanced-nodejs-wrapper": "^3.0.0", "pg": "^8.13.1", "util": "^0.12.5" } diff --git a/examples/typescript_example/package.json b/examples/typescript_example/package.json index f25533fc..975dca20 100644 --- a/examples/typescript_example/package.json +++ b/examples/typescript_example/package.json @@ -10,7 +10,7 @@ "dev": "ts-node src/index.ts" }, "dependencies": { - "aws-advanced-nodejs-wrapper": "^2.1.1", + "aws-advanced-nodejs-wrapper": "^3.0.0", "mysql2": "^3.6.0" }, "devDependencies": { diff --git a/package-lock.json b/package-lock.json index 76f14fe0..296523c0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "aws-advanced-nodejs-wrapper", - "version": "2.1.1", + "version": "3.0.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "aws-advanced-nodejs-wrapper", - "version": "2.1.1", + "version": "3.0.0", "workspaces": [ "common", "pg", diff --git a/package.json b/package.json index 8e7db353..23adce2f 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,11 @@ { "name": "aws-advanced-nodejs-wrapper", - "version": "2.1.1", + "version": "3.0.0", "type": "module", + "repository": { + "type": "git", + "url": "git+https://github.com/aws/aws-advanced-nodejs-wrapper.git" + }, "engines": { "node": ">=22.9.0", "npm": ">=10.0.0"