@aws/aurora-dsql-postgresjs-connector 0.1.0 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +20 -3
- package/dist/index.cjs +109 -0
- package/dist/index.d.cts +21 -0
- package/dist/index.d.cts.map +1 -0
- package/dist/index.d.mts +21 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +82 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +31 -15
- package/dist/client.d.ts +0 -21
- package/dist/client.d.ts.map +0 -1
- package/dist/client.js +0 -103
- package/dist/client.js.map +0 -1
- package/dist/index.d.ts +0 -3
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -6
- package/dist/index.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
# Aurora DSQL Connector for Postgres.js
|
|
2
2
|
|
|
3
|
+
[](https://github.com/awslabs/aurora-dsql-nodejs-connector/tree/main/packages/postgres-js)
|
|
4
|
+
[](https://github.com/awslabs/aurora-dsql-nodejs-connector/blob/main/LICENSE)
|
|
5
|
+
[](https://www.npmjs.com/package/@aws/aurora-dsql-postgresjs-connector)
|
|
6
|
+
[](https://discord.com/invite/nEF6ksFWru)
|
|
7
|
+
|
|
3
8
|
The Aurora DSQL Connector for Postgres.js is a Node.js connector built on [Postgres.js](https://github.com/porsager/postgres)
|
|
4
9
|
that integrates IAM Authentication for connecting JavaScript applications to Amazon Aurora DSQL clusters.
|
|
5
10
|
|
|
@@ -7,7 +12,7 @@ The Aurora DSQL Connector for Postgres.js is designed as an authentication plugi
|
|
|
7
12
|
Postgres.js client to enable applications to authenticate with Amazon Aurora DSQL using IAM credentials. The connector
|
|
8
13
|
does not connect directly to the database, but provides seamless IAM authentication on top of the underlying Postgres.js driver.
|
|
9
14
|
|
|
10
|
-
##
|
|
15
|
+
## About the Connector
|
|
11
16
|
|
|
12
17
|
Amazon Aurora DSQL is a distributed SQL database service that provides high availability and scalability for
|
|
13
18
|
PostgreSQL-compatible applications. Aurora DSQL requires IAM-based authentication with time-limited tokens that
|
|
@@ -19,21 +24,33 @@ client that handles IAM token generation, allowing users to connect to Aurora DS
|
|
|
19
24
|
The Aurora DSQL Connector for Postgres.js works with most versions of Postgres.js. Users provide their own version by installing
|
|
20
25
|
Postgres.js directly.
|
|
21
26
|
|
|
27
|
+
### What is Aurora DSQL Authentication?
|
|
28
|
+
|
|
29
|
+
In Aurora DSQL, authentication involves:
|
|
30
|
+
|
|
31
|
+
- **IAM Authentication:** All connections use IAM-based authentication with time-limited tokens
|
|
32
|
+
- **Token Generation:** Authentication tokens are generated using AWS credentials and have configurable lifetimes
|
|
33
|
+
|
|
34
|
+
The Aurora DSQL Connector for Postgres.js is designed to understand these requirements and automatically generate IAM authentication tokens when establishing connections.
|
|
35
|
+
|
|
22
36
|
### Features
|
|
23
37
|
|
|
24
38
|
- **Automatic IAM Authentication** - Handles DSQL token generation and refresh
|
|
25
39
|
- **Built on Postgres.js** - Leverages the fast PostgreSQL client for Node.js
|
|
40
|
+
- **Seamless Integration** - Works with existing Postgres.js connection patterns
|
|
26
41
|
- **Region Auto-Discovery** - Extracts AWS region from DSQL cluster hostname
|
|
27
42
|
- **Full TypeScript Support** - Provides full type safety
|
|
28
|
-
- **
|
|
43
|
+
- **AWS Credentials Support** - Supports various AWS credential providers (default, profile-based, custom)
|
|
44
|
+
- **Connection Pooling Compatibility** - Works seamlessly with Postgres.js' built-in connection pooling
|
|
29
45
|
|
|
30
46
|
## Quick start guide
|
|
31
47
|
|
|
32
48
|
### Requirements
|
|
33
49
|
|
|
34
50
|
- Node.js 20+
|
|
51
|
+
- [Access to an Aurora DSQL cluster](https://docs.aws.amazon.com/aurora-dsql/latest/userguide/getting-started.html)
|
|
52
|
+
- Set up appropriate IAM permissions to allow your application to connect to Aurora DSQL.
|
|
35
53
|
- AWS credentials configured (via AWS CLI, environment variables, or IAM roles)
|
|
36
|
-
- Access to an Aurora DSQL cluster
|
|
37
54
|
|
|
38
55
|
### Installation
|
|
39
56
|
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
//#region rolldown:runtime
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __copyProps = (to, from, except, desc) => {
|
|
9
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
10
|
+
for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
11
|
+
key = keys[i];
|
|
12
|
+
if (!__hasOwnProp.call(to, key) && key !== except) {
|
|
13
|
+
__defProp(to, key, {
|
|
14
|
+
get: ((k) => from[k]).bind(null, key),
|
|
15
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
return to;
|
|
21
|
+
};
|
|
22
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
|
|
23
|
+
value: mod,
|
|
24
|
+
enumerable: true
|
|
25
|
+
}) : target, mod));
|
|
26
|
+
|
|
27
|
+
//#endregion
|
|
28
|
+
let postgres = require("postgres");
|
|
29
|
+
postgres = __toESM(postgres);
|
|
30
|
+
let __aws_sdk_dsql_signer = require("@aws-sdk/dsql-signer");
|
|
31
|
+
|
|
32
|
+
//#region src/client.ts
|
|
33
|
+
const ADMIN = "admin";
|
|
34
|
+
const DEFAULT_DATABASE = "postgres";
|
|
35
|
+
const DEFAULT_EXPIRY = 30;
|
|
36
|
+
const PRE_REGION_HOST_PATTERN = ".dsql.";
|
|
37
|
+
const POST_REGION_HOST_PATTERN = ".on.aws";
|
|
38
|
+
function auroraDSQLPostgres(urlOrOptions, options) {
|
|
39
|
+
let opts;
|
|
40
|
+
let host;
|
|
41
|
+
let username;
|
|
42
|
+
let database;
|
|
43
|
+
let ssl;
|
|
44
|
+
if (typeof urlOrOptions === "string") {
|
|
45
|
+
let parsedOptions = parseConnectionString(urlOrOptions);
|
|
46
|
+
host = options?.hostname || options?.host || parsedOptions.host || process.env.PGHOST;
|
|
47
|
+
username = options?.username || options?.user || parsedOptions.username || process.env.PGUSERNAME || process.env.USER || ADMIN;
|
|
48
|
+
database = options?.database || options?.db || parsedOptions.database || process.env.PGDATABASE;
|
|
49
|
+
ssl = options?.ssl || parsedOptions.ssl;
|
|
50
|
+
opts = { ...options };
|
|
51
|
+
} else {
|
|
52
|
+
host = urlOrOptions?.hostname || urlOrOptions?.host || process.env.PGHOST;
|
|
53
|
+
username = urlOrOptions?.username || urlOrOptions?.user || process.env.PGUSERNAME || process.env.USER || ADMIN;
|
|
54
|
+
database = urlOrOptions?.database || urlOrOptions?.db || process.env.PGDATABASE;
|
|
55
|
+
ssl = urlOrOptions?.ssl;
|
|
56
|
+
opts = { ...urlOrOptions };
|
|
57
|
+
}
|
|
58
|
+
if (Array.isArray(host)) throw new Error("Multi-host configurations are not supported for Aurora DSQL");
|
|
59
|
+
let region = opts.region || parseRegionFromHost(host);
|
|
60
|
+
if (isClusterID(host)) {
|
|
61
|
+
host = buildHostnameFromIdAndRegion(host, region);
|
|
62
|
+
opts.host = host;
|
|
63
|
+
}
|
|
64
|
+
let signerConfig = {
|
|
65
|
+
hostname: host,
|
|
66
|
+
region: opts.region || parseRegionFromHost(host),
|
|
67
|
+
expiresIn: opts.tokenDurationSecs ?? opts.connect_timeout ?? (process.env.PGCONNECT_TIMEOUT ? parseInt(process.env.PGCONNECT_TIMEOUT) : void 0) ?? DEFAULT_EXPIRY,
|
|
68
|
+
profile: opts.profile || process.env.AWS_PROFILE || "default"
|
|
69
|
+
};
|
|
70
|
+
if (opts.customCredentialsProvider) signerConfig.credentials = opts.customCredentialsProvider;
|
|
71
|
+
let signer = new __aws_sdk_dsql_signer.DsqlSigner(signerConfig);
|
|
72
|
+
if (!database) opts.database = DEFAULT_DATABASE;
|
|
73
|
+
if (!ssl) opts.ssl = true;
|
|
74
|
+
const postgresOpts = {
|
|
75
|
+
...opts,
|
|
76
|
+
pass: () => getToken(signer, username)
|
|
77
|
+
};
|
|
78
|
+
return typeof urlOrOptions === "string" ? (0, postgres.default)(urlOrOptions, postgresOpts) : (0, postgres.default)(postgresOpts);
|
|
79
|
+
}
|
|
80
|
+
function parseConnectionString(url) {
|
|
81
|
+
let decodedUrl = decodeURI(url);
|
|
82
|
+
const parsed = new URL(decodedUrl);
|
|
83
|
+
if (parsed.hostname?.includes(",")) throw new Error("Multi-host connection strings are not supported for Aurora DSQL");
|
|
84
|
+
return {
|
|
85
|
+
username: parsed.username,
|
|
86
|
+
host: parsed.hostname,
|
|
87
|
+
database: parsed.pathname?.slice(1),
|
|
88
|
+
ssl: parsed.searchParams.get("ssl") || parsed.searchParams.get("sslmode") || void 0
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
function parseRegionFromHost(host) {
|
|
92
|
+
if (!host) throw new Error("Hostname is required to parse region");
|
|
93
|
+
const match = host.match(/^(?<instance>[^.]+)\.(?<dns>dsql(?:-[^.]+)?)\.(?<domain>(?<region>[a-zA-Z0-9-]+)\.on\.aws\.?)$/i);
|
|
94
|
+
if (match?.groups) return match.groups.region;
|
|
95
|
+
throw new Error(`Unable to parse region from hostname: ${host}`);
|
|
96
|
+
}
|
|
97
|
+
function isClusterID(host) {
|
|
98
|
+
return !host.includes(".");
|
|
99
|
+
}
|
|
100
|
+
function buildHostnameFromIdAndRegion(host, region) {
|
|
101
|
+
return host + PRE_REGION_HOST_PATTERN + region + POST_REGION_HOST_PATTERN;
|
|
102
|
+
}
|
|
103
|
+
async function getToken(signer, username) {
|
|
104
|
+
if (username === ADMIN) return await signer.getDbConnectAdminAuthToken();
|
|
105
|
+
else return await signer.getDbConnectAuthToken();
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
//#endregion
|
|
109
|
+
exports.auroraDSQLPostgres = auroraDSQLPostgres;
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import postgres, { PostgresType } from "postgres";
|
|
2
|
+
import { AwsCredentialIdentity, AwsCredentialIdentityProvider } from "@aws-sdk/types";
|
|
3
|
+
|
|
4
|
+
//#region src/client.d.ts
|
|
5
|
+
declare function auroraDSQLPostgres<T extends Record<string, postgres.PostgresType> = {}>(url: string, options?: AuroraDSQLConfig<T>): postgres.Sql<Record<string, postgres.PostgresType> extends T ? {} : { [type in keyof T]: T[type] extends {
|
|
6
|
+
serialize: (value: infer R) => any;
|
|
7
|
+
parse: (raw: any) => infer R;
|
|
8
|
+
} ? R : never }>;
|
|
9
|
+
declare function auroraDSQLPostgres<T extends Record<string, postgres.PostgresType> = {}>(options: AuroraDSQLConfig<T>): postgres.Sql<Record<string, postgres.PostgresType> extends T ? {} : { [type in keyof T]: T[type] extends {
|
|
10
|
+
serialize: (value: infer R) => any;
|
|
11
|
+
parse: (raw: any) => infer R;
|
|
12
|
+
} ? R : never }>;
|
|
13
|
+
interface AuroraDSQLConfig<T extends Record<string, PostgresType<T>>> extends Omit<postgres.Options<T>, 'password' | 'pass'> {
|
|
14
|
+
region?: string;
|
|
15
|
+
profile?: string;
|
|
16
|
+
tokenDurationSecs?: number;
|
|
17
|
+
customCredentialsProvider?: AwsCredentialIdentity | AwsCredentialIdentityProvider;
|
|
18
|
+
}
|
|
19
|
+
//#endregion
|
|
20
|
+
export { type AuroraDSQLConfig, auroraDSQLPostgres };
|
|
21
|
+
//# sourceMappingURL=index.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.cts","names":[],"sources":["../src/client.ts"],"sourcesContent":[],"mappings":";;;;iBAgBgB,6BAA6B,eAAe,QAAA,CAAS,2CAEvD,iBAAiB,KAC5B,QAAA,CAAS,IAAI,eAAe,QAAA,CAAS,sBAAsB,0BAC3C,IAAI,EAAE;EAJT,SAAA,EAAA,CAAA,KAAkB,EAAA,KAAA,EAAA,EAAA,GAAA,GAAA;EAA0B,KAAS,EAAA,CAAA,GAAA,EAAA,GAAA,EAAA,GAAA,KAAA,EAAA;AAAxB,CAAA,GAAA,CAAA,GAAA,KAAA,EAEd,CAAA;AAAjB,iBAQE,kBARF,CAAA,UAQ+B,MAR/B,CAAA,MAAA,EAQ8C,QAAA,CAAS,YARvD,CAAA,GAAA,CAAA,CAAA,CAAA,CAAA,OAAA,EASD,gBATC,CASgB,CAThB,CAAA,CAAA,EAUX,QAAA,CAAS,GAVE,CAUE,MAVF,CAAA,MAAA,EAUiB,QAAA,CAAS,YAV1B,CAAA,SAUgD,CAVhD,GAAA,CAAA,CAAA,GAAA,WAC0B,MAUrB,CAVqB,GAUjB,CAViB,CAUf,IAVe,CAAA,SAAA;EAAxB,SAAA,EAAA,CAAA,KAAA,EAAA,KAAA,EAAA,EAAA,GAAA,GAAA;EAA8C,KAAA,EAAA,CAAA,GAAA,EAAA,GAAA,EAAA,GAAA,KAAA,EAAA;AAC3C,CAAA,GAAA,CAAA,GAAA,KAAA,EAAI,CAAA;AAAE,UA2HR,gBA3HQ,CAAA,UA2HmB,MA3HnB,CAAA,MAAA,EA2HkC,YA3HlC,CA2H+C,CA3H/C,CAAA,CAAA,CAAA,SA2H4D,IA3H5D,CA2HiE,QAAA,CAAS,OA3H1E,CA2HkF,CA3HlF,CAAA,EAAA,UAAA,GAAA,MAAA,CAAA,CAAA;EADtB,MAAS,CAAA,EAAA,MAAA;EAAG,OAAA,CAAA,EAAA,MAAA;EAOC,iBAAA,CAAA,EAAA,MAAkB;EAA0B,yBAAS,CAAA,EA6HrC,qBA7HqC,GA6Hb,6BA7Ha"}
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import postgres, { PostgresType } from "postgres";
|
|
2
|
+
import { AwsCredentialIdentity, AwsCredentialIdentityProvider } from "@aws-sdk/types";
|
|
3
|
+
|
|
4
|
+
//#region src/client.d.ts
|
|
5
|
+
declare function auroraDSQLPostgres<T extends Record<string, postgres.PostgresType> = {}>(url: string, options?: AuroraDSQLConfig<T>): postgres.Sql<Record<string, postgres.PostgresType> extends T ? {} : { [type in keyof T]: T[type] extends {
|
|
6
|
+
serialize: (value: infer R) => any;
|
|
7
|
+
parse: (raw: any) => infer R;
|
|
8
|
+
} ? R : never }>;
|
|
9
|
+
declare function auroraDSQLPostgres<T extends Record<string, postgres.PostgresType> = {}>(options: AuroraDSQLConfig<T>): postgres.Sql<Record<string, postgres.PostgresType> extends T ? {} : { [type in keyof T]: T[type] extends {
|
|
10
|
+
serialize: (value: infer R) => any;
|
|
11
|
+
parse: (raw: any) => infer R;
|
|
12
|
+
} ? R : never }>;
|
|
13
|
+
interface AuroraDSQLConfig<T extends Record<string, PostgresType<T>>> extends Omit<postgres.Options<T>, 'password' | 'pass'> {
|
|
14
|
+
region?: string;
|
|
15
|
+
profile?: string;
|
|
16
|
+
tokenDurationSecs?: number;
|
|
17
|
+
customCredentialsProvider?: AwsCredentialIdentity | AwsCredentialIdentityProvider;
|
|
18
|
+
}
|
|
19
|
+
//#endregion
|
|
20
|
+
export { type AuroraDSQLConfig, auroraDSQLPostgres };
|
|
21
|
+
//# sourceMappingURL=index.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/client.ts"],"sourcesContent":[],"mappings":";;;;iBAgBgB,6BAA6B,eAAe,QAAA,CAAS,2CAEvD,iBAAiB,KAC5B,QAAA,CAAS,IAAI,eAAe,QAAA,CAAS,sBAAsB,0BAC3C,IAAI,EAAE;EAJT,SAAA,EAAA,CAAA,KAAkB,EAAA,KAAA,EAAA,EAAA,GAAA,GAAA;EAA0B,KAAS,EAAA,CAAA,GAAA,EAAA,GAAA,EAAA,GAAA,KAAA,EAAA;AAAxB,CAAA,GAAA,CAAA,GAAA,KAAA,EAEd,CAAA;AAAjB,iBAQE,kBARF,CAAA,UAQ+B,MAR/B,CAAA,MAAA,EAQ8C,QAAA,CAAS,YARvD,CAAA,GAAA,CAAA,CAAA,CAAA,CAAA,OAAA,EASD,gBATC,CASgB,CAThB,CAAA,CAAA,EAUX,QAAA,CAAS,GAVE,CAUE,MAVF,CAAA,MAAA,EAUiB,QAAA,CAAS,YAV1B,CAAA,SAUgD,CAVhD,GAAA,CAAA,CAAA,GAAA,WAC0B,MAUrB,CAVqB,GAUjB,CAViB,CAUf,IAVe,CAAA,SAAA;EAAxB,SAAA,EAAA,CAAA,KAAA,EAAA,KAAA,EAAA,EAAA,GAAA,GAAA;EAA8C,KAAA,EAAA,CAAA,GAAA,EAAA,GAAA,EAAA,GAAA,KAAA,EAAA;AAC3C,CAAA,GAAA,CAAA,GAAA,KAAA,EAAI,CAAA;AAAE,UA2HR,gBA3HQ,CAAA,UA2HmB,MA3HnB,CAAA,MAAA,EA2HkC,YA3HlC,CA2H+C,CA3H/C,CAAA,CAAA,CAAA,SA2H4D,IA3H5D,CA2HiE,QAAA,CAAS,OA3H1E,CA2HkF,CA3HlF,CAAA,EAAA,UAAA,GAAA,MAAA,CAAA,CAAA;EADtB,MAAS,CAAA,EAAA,MAAA;EAAG,OAAA,CAAA,EAAA,MAAA;EAOC,iBAAA,CAAA,EAAA,MAAkB;EAA0B,yBAAS,CAAA,EA6HrC,qBA7HqC,GA6Hb,6BA7Ha"}
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import postgres from "postgres";
|
|
2
|
+
import { DsqlSigner } from "@aws-sdk/dsql-signer";
|
|
3
|
+
|
|
4
|
+
//#region src/client.ts
|
|
5
|
+
const ADMIN = "admin";
|
|
6
|
+
const DEFAULT_DATABASE = "postgres";
|
|
7
|
+
const DEFAULT_EXPIRY = 30;
|
|
8
|
+
const PRE_REGION_HOST_PATTERN = ".dsql.";
|
|
9
|
+
const POST_REGION_HOST_PATTERN = ".on.aws";
|
|
10
|
+
function auroraDSQLPostgres(urlOrOptions, options) {
|
|
11
|
+
let opts;
|
|
12
|
+
let host;
|
|
13
|
+
let username;
|
|
14
|
+
let database;
|
|
15
|
+
let ssl;
|
|
16
|
+
if (typeof urlOrOptions === "string") {
|
|
17
|
+
let parsedOptions = parseConnectionString(urlOrOptions);
|
|
18
|
+
host = options?.hostname || options?.host || parsedOptions.host || process.env.PGHOST;
|
|
19
|
+
username = options?.username || options?.user || parsedOptions.username || process.env.PGUSERNAME || process.env.USER || ADMIN;
|
|
20
|
+
database = options?.database || options?.db || parsedOptions.database || process.env.PGDATABASE;
|
|
21
|
+
ssl = options?.ssl || parsedOptions.ssl;
|
|
22
|
+
opts = { ...options };
|
|
23
|
+
} else {
|
|
24
|
+
host = urlOrOptions?.hostname || urlOrOptions?.host || process.env.PGHOST;
|
|
25
|
+
username = urlOrOptions?.username || urlOrOptions?.user || process.env.PGUSERNAME || process.env.USER || ADMIN;
|
|
26
|
+
database = urlOrOptions?.database || urlOrOptions?.db || process.env.PGDATABASE;
|
|
27
|
+
ssl = urlOrOptions?.ssl;
|
|
28
|
+
opts = { ...urlOrOptions };
|
|
29
|
+
}
|
|
30
|
+
if (Array.isArray(host)) throw new Error("Multi-host configurations are not supported for Aurora DSQL");
|
|
31
|
+
let region = opts.region || parseRegionFromHost(host);
|
|
32
|
+
if (isClusterID(host)) {
|
|
33
|
+
host = buildHostnameFromIdAndRegion(host, region);
|
|
34
|
+
opts.host = host;
|
|
35
|
+
}
|
|
36
|
+
let signerConfig = {
|
|
37
|
+
hostname: host,
|
|
38
|
+
region: opts.region || parseRegionFromHost(host),
|
|
39
|
+
expiresIn: opts.tokenDurationSecs ?? opts.connect_timeout ?? (process.env.PGCONNECT_TIMEOUT ? parseInt(process.env.PGCONNECT_TIMEOUT) : void 0) ?? DEFAULT_EXPIRY,
|
|
40
|
+
profile: opts.profile || process.env.AWS_PROFILE || "default"
|
|
41
|
+
};
|
|
42
|
+
if (opts.customCredentialsProvider) signerConfig.credentials = opts.customCredentialsProvider;
|
|
43
|
+
let signer = new DsqlSigner(signerConfig);
|
|
44
|
+
if (!database) opts.database = DEFAULT_DATABASE;
|
|
45
|
+
if (!ssl) opts.ssl = true;
|
|
46
|
+
const postgresOpts = {
|
|
47
|
+
...opts,
|
|
48
|
+
pass: () => getToken(signer, username)
|
|
49
|
+
};
|
|
50
|
+
return typeof urlOrOptions === "string" ? postgres(urlOrOptions, postgresOpts) : postgres(postgresOpts);
|
|
51
|
+
}
|
|
52
|
+
function parseConnectionString(url) {
|
|
53
|
+
let decodedUrl = decodeURI(url);
|
|
54
|
+
const parsed = new URL(decodedUrl);
|
|
55
|
+
if (parsed.hostname?.includes(",")) throw new Error("Multi-host connection strings are not supported for Aurora DSQL");
|
|
56
|
+
return {
|
|
57
|
+
username: parsed.username,
|
|
58
|
+
host: parsed.hostname,
|
|
59
|
+
database: parsed.pathname?.slice(1),
|
|
60
|
+
ssl: parsed.searchParams.get("ssl") || parsed.searchParams.get("sslmode") || void 0
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
function parseRegionFromHost(host) {
|
|
64
|
+
if (!host) throw new Error("Hostname is required to parse region");
|
|
65
|
+
const match = host.match(/^(?<instance>[^.]+)\.(?<dns>dsql(?:-[^.]+)?)\.(?<domain>(?<region>[a-zA-Z0-9-]+)\.on\.aws\.?)$/i);
|
|
66
|
+
if (match?.groups) return match.groups.region;
|
|
67
|
+
throw new Error(`Unable to parse region from hostname: ${host}`);
|
|
68
|
+
}
|
|
69
|
+
function isClusterID(host) {
|
|
70
|
+
return !host.includes(".");
|
|
71
|
+
}
|
|
72
|
+
function buildHostnameFromIdAndRegion(host, region) {
|
|
73
|
+
return host + PRE_REGION_HOST_PATTERN + region + POST_REGION_HOST_PATTERN;
|
|
74
|
+
}
|
|
75
|
+
async function getToken(signer, username) {
|
|
76
|
+
if (username === ADMIN) return await signer.getDbConnectAdminAuthToken();
|
|
77
|
+
else return await signer.getDbConnectAuthToken();
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
//#endregion
|
|
81
|
+
export { auroraDSQLPostgres };
|
|
82
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.mjs","names":["opts: AuroraDSQLConfig<T>","host: string","username: string","database: string | undefined","ssl: object | boolean | string | undefined","signerConfig: DsqlSignerConfig","postgresOpts: postgres.Options<T>"],"sources":["../src/client.ts"],"sourcesContent":["/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport postgres, {PostgresType} from \"postgres\";\nimport {AwsCredentialIdentity, AwsCredentialIdentityProvider} from \"@aws-sdk/types\";\nimport {DsqlSigner, DsqlSignerConfig} from \"@aws-sdk/dsql-signer\";\n\nconst ADMIN = \"admin\";\nconst DEFAULT_DATABASE = \"postgres\";\nconst DEFAULT_EXPIRY = 30; // Based on default Postgres.js connect_timeout\n// String components of a DSQL hostname, <Cluster ID>.dsql.<region>.on.aws\nconst PRE_REGION_HOST_PATTERN = \".dsql.\";\nconst POST_REGION_HOST_PATTERN = \".on.aws\";\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\nexport function auroraDSQLPostgres<T extends Record<string, postgres.PostgresType> = {}>(\n url: string,\n options?: AuroraDSQLConfig<T>\n): postgres.Sql<Record<string, postgres.PostgresType> extends T ? {} : {\n [type in keyof T]: T[type] extends {\n serialize: (value: infer R) => any,\n parse: (raw: any) => infer R\n } ? R : never\n}>;\n\nexport function auroraDSQLPostgres<T extends Record<string, postgres.PostgresType> = {}>(\n options: AuroraDSQLConfig<T>\n): postgres.Sql<Record<string, postgres.PostgresType> extends T ? {} : {\n [type in keyof T]: T[type] extends {\n serialize: (value: infer R) => any,\n parse: (raw: any) => infer R\n } ? R : never\n}>;\n\nexport function auroraDSQLPostgres<T extends Record<string, postgres.PostgresType> = {}>(\n urlOrOptions: string | AuroraDSQLConfig<T>,\n options?: AuroraDSQLConfig<T>\n): postgres.Sql<Record<string, postgres.PostgresType> extends T ? {} : {\n [type in keyof T]: T[type] extends {\n serialize: (value: infer R) => any,\n parse: (raw: any) => infer R\n } ? R : never\n}> {\n/* eslint-enable @typescript-eslint/no-explicit-any */\n let opts: AuroraDSQLConfig<T>;\n let host: string;\n let username: string;\n let database: string | undefined;\n let ssl: object | boolean | string | undefined;\n if (typeof urlOrOptions === 'string') {\n // Called with (url, options)\n let parsedOptions = parseConnectionString(urlOrOptions);\n host = options?.hostname || options?.host || parsedOptions.host || process.env.PGHOST!;\n username = options?.username || options?.user || parsedOptions.username! || process.env.PGUSERNAME || process.env.USER || ADMIN;\n database = options?.database || options?.db || parsedOptions.database || process.env.PGDATABASE;\n ssl = options?.ssl || parsedOptions.ssl;\n opts = {...options!};\n } else {\n // Called with (options) only\n host = urlOrOptions?.hostname || urlOrOptions?.host || process.env.PGHOST!;\n username = urlOrOptions?.username || urlOrOptions?.user || process.env.PGUSERNAME || process.env.USER || ADMIN;\n database = urlOrOptions?.database || urlOrOptions?.db || process.env.PGDATABASE;\n ssl = urlOrOptions?.ssl;\n opts = {...urlOrOptions!};\n }\n if (Array.isArray(host)) {\n throw new Error('Multi-host configurations are not supported for Aurora DSQL');\n }\n let region = opts.region || parseRegionFromHost(host);\n if (isClusterID(host)) {\n host = buildHostnameFromIdAndRegion(host, region);\n opts.host = host;\n }\n let signerConfig: DsqlSignerConfig = {\n hostname: host,\n region: opts.region || parseRegionFromHost(host),\n expiresIn: opts.tokenDurationSecs ?? opts.connect_timeout ?? (process.env.PGCONNECT_TIMEOUT ? parseInt(process.env.PGCONNECT_TIMEOUT) : undefined) ?? DEFAULT_EXPIRY,\n profile: opts.profile || process.env.AWS_PROFILE || \"default\",\n };\n if (opts.customCredentialsProvider) {\n signerConfig.credentials = opts.customCredentialsProvider;\n }\n let signer = new DsqlSigner(signerConfig);\n if (!database) opts.database = DEFAULT_DATABASE;\n if (!ssl) opts.ssl = true;\n const postgresOpts: postgres.Options<T> = {\n ...opts,\n pass: () => getToken(signer, username),\n };\n return typeof urlOrOptions === 'string' ? postgres(urlOrOptions, postgresOpts) : postgres(postgresOpts);\n}\n\nfunction parseConnectionString(url: string): {\n database?: string;\n host?: string;\n username?: string;\n ssl?: string;\n} {\n let decodedUrl = decodeURI(url);\n const parsed = new URL(decodedUrl);\n\n // Check for multi-host\n if (parsed.hostname?.includes(',')) {\n throw new Error('Multi-host connection strings are not supported for Aurora DSQL');\n }\n\n return {\n username: parsed.username,\n host: parsed.hostname,\n database: parsed.pathname?.slice(1),\n ssl: parsed.searchParams.get(\"ssl\") || parsed.searchParams.get(\"sslmode\") || undefined,\n };\n}\n\nfunction parseRegionFromHost(host: string): string | undefined {\n if (!host) {\n throw new Error(\"Hostname is required to parse region\");\n }\n\n const match = host.match(/^(?<instance>[^.]+)\\.(?<dns>dsql(?:-[^.]+)?)\\.(?<domain>(?<region>[a-zA-Z0-9-]+)\\.on\\.aws\\.?)$/i);\n if (match?.groups) {\n return match.groups.region;\n }\n throw new Error(`Unable to parse region from hostname: ${host}`);\n}\n\nfunction isClusterID(host: string) {\n return !host.includes(\".\");\n}\n\nfunction buildHostnameFromIdAndRegion(host: string, region: string | undefined) {\n return host + PRE_REGION_HOST_PATTERN + region + POST_REGION_HOST_PATTERN;\n}\n\nasync function getToken(signer: DsqlSigner, username: string): Promise<string> {\n if (username === ADMIN) {\n return await signer.getDbConnectAdminAuthToken();\n } else {\n return await signer.getDbConnectAuthToken();\n }\n}\n\nexport interface AuroraDSQLConfig<T extends Record<string, PostgresType<T>>> extends Omit<postgres.Options<T>, 'password' | 'pass'> {\n\n region?: string;\n\n profile?: string;\n\n tokenDurationSecs?: number;\n\n customCredentialsProvider?: AwsCredentialIdentity | AwsCredentialIdentityProvider;\n\n}"],"mappings":";;;;AAQA,MAAM,QAAQ;AACd,MAAM,mBAAmB;AACzB,MAAM,iBAAiB;AAEvB,MAAM,0BAA0B;AAChC,MAAM,2BAA2B;AAsBjC,SAAgB,mBACZ,cACA,SAMD;CAEC,IAAIA;CACJ,IAAIC;CACJ,IAAIC;CACJ,IAAIC;CACJ,IAAIC;AACJ,KAAI,OAAO,iBAAiB,UAAU;EAElC,IAAI,gBAAgB,sBAAsB,aAAa;AACvD,SAAO,SAAS,YAAY,SAAS,QAAQ,cAAc,QAAQ,QAAQ,IAAI;AAC/E,aAAW,SAAS,YAAY,SAAS,QAAQ,cAAc,YAAa,QAAQ,IAAI,cAAc,QAAQ,IAAI,QAAQ;AAC1H,aAAW,SAAS,YAAY,SAAS,MAAM,cAAc,YAAY,QAAQ,IAAI;AACrF,QAAM,SAAS,OAAO,cAAc;AACpC,SAAO,EAAC,GAAG,SAAS;QACjB;AAEH,SAAO,cAAc,YAAY,cAAc,QAAQ,QAAQ,IAAI;AACnE,aAAW,cAAc,YAAY,cAAc,QAAQ,QAAQ,IAAI,cAAc,QAAQ,IAAI,QAAQ;AACzG,aAAW,cAAc,YAAY,cAAc,MAAM,QAAQ,IAAI;AACrE,QAAM,cAAc;AACpB,SAAO,EAAC,GAAG,cAAc;;AAE7B,KAAI,MAAM,QAAQ,KAAK,CACnB,OAAM,IAAI,MAAM,8DAA8D;CAElF,IAAI,SAAS,KAAK,UAAU,oBAAoB,KAAK;AACrD,KAAI,YAAY,KAAK,EAAE;AACnB,SAAO,6BAA6B,MAAM,OAAO;AACjD,OAAK,OAAO;;CAEhB,IAAIC,eAAiC;EACjC,UAAU;EACV,QAAQ,KAAK,UAAU,oBAAoB,KAAK;EAChD,WAAW,KAAK,qBAAqB,KAAK,oBAAoB,QAAQ,IAAI,oBAAoB,SAAS,QAAQ,IAAI,kBAAkB,GAAG,WAAc;EACtJ,SAAS,KAAK,WAAW,QAAQ,IAAI,eAAe;EACvD;AACD,KAAI,KAAK,0BACL,cAAa,cAAc,KAAK;CAEpC,IAAI,SAAS,IAAI,WAAW,aAAa;AACzC,KAAI,CAAC,SAAU,MAAK,WAAW;AAC/B,KAAI,CAAC,IAAK,MAAK,MAAM;CACrB,MAAMC,eAAoC;EACtC,GAAG;EACH,YAAY,SAAS,QAAQ,SAAS;EACzC;AACD,QAAO,OAAO,iBAAiB,WAAW,SAAS,cAAc,aAAa,GAAG,SAAS,aAAa;;AAG3G,SAAS,sBAAsB,KAK7B;CACE,IAAI,aAAa,UAAU,IAAI;CAC/B,MAAM,SAAS,IAAI,IAAI,WAAW;AAGlC,KAAI,OAAO,UAAU,SAAS,IAAI,CAC9B,OAAM,IAAI,MAAM,kEAAkE;AAGtF,QAAO;EACH,UAAU,OAAO;EACjB,MAAM,OAAO;EACb,UAAU,OAAO,UAAU,MAAM,EAAE;EACnC,KAAK,OAAO,aAAa,IAAI,MAAM,IAAI,OAAO,aAAa,IAAI,UAAU,IAAI;EAChF;;AAGL,SAAS,oBAAoB,MAAkC;AAC3D,KAAI,CAAC,KACD,OAAM,IAAI,MAAM,uCAAuC;CAG3D,MAAM,QAAQ,KAAK,MAAM,kGAAkG;AAC3H,KAAI,OAAO,OACP,QAAO,MAAM,OAAO;AAExB,OAAM,IAAI,MAAM,yCAAyC,OAAO;;AAGpE,SAAS,YAAY,MAAc;AAC/B,QAAO,CAAC,KAAK,SAAS,IAAI;;AAG9B,SAAS,6BAA6B,MAAc,QAA4B;AAC5E,QAAO,OAAO,0BAA0B,SAAS;;AAGrD,eAAe,SAAS,QAAoB,UAAmC;AAC3E,KAAI,aAAa,MACb,QAAO,MAAM,OAAO,4BAA4B;KAEhD,QAAO,MAAM,OAAO,uBAAuB"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aws/aurora-dsql-postgresjs-connector",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "An AWS Aurora DSQL connector with IAM authentication for Postgres.js",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|
|
@@ -13,16 +13,31 @@
|
|
|
13
13
|
"access": "public"
|
|
14
14
|
},
|
|
15
15
|
"type": "module",
|
|
16
|
-
"main": "./dist/index.
|
|
17
|
-
"
|
|
16
|
+
"main": "./dist/index.cjs",
|
|
17
|
+
"module": "./dist/index.mjs",
|
|
18
|
+
"types": "./dist/index.d.mts",
|
|
19
|
+
"exports": {
|
|
20
|
+
".": {
|
|
21
|
+
"import": {
|
|
22
|
+
"types": "./dist/index.d.mts",
|
|
23
|
+
"default": "./dist/index.mjs"
|
|
24
|
+
},
|
|
25
|
+
"require": {
|
|
26
|
+
"types": "./dist/index.d.cts",
|
|
27
|
+
"default": "./dist/index.cjs"
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
},
|
|
18
31
|
"scripts": {
|
|
19
|
-
"
|
|
20
|
-
"
|
|
21
|
-
"
|
|
22
|
-
"
|
|
23
|
-
"
|
|
32
|
+
"clean": "rm -rf dist/ node_modules/",
|
|
33
|
+
"build": "npm run build:dev",
|
|
34
|
+
"build:dev": "npm run typecheck && tsdown \"src/**/*.ts\" --format cjs,esm --dts --sourcemap",
|
|
35
|
+
"build:prod": "npm run typecheck && tsdown src/index.ts --format cjs,esm --dts",
|
|
36
|
+
"typecheck": "tsc --noEmit",
|
|
37
|
+
"test": "npm run test:unit && npm run test:integration",
|
|
38
|
+
"test:unit": "jest --testPathIgnorePatterns=integration",
|
|
39
|
+
"test:integration": "NODE_OPTIONS='--experimental-vm-modules' jest --testPathPatterns=integration",
|
|
24
40
|
"test:watch": "jest --watch",
|
|
25
|
-
"dev": "tsc --watch",
|
|
26
41
|
"lint": "eslint src/**/*.ts test/**/*.ts",
|
|
27
42
|
"lint:fix": "eslint src/**/*.ts test/**/*.ts --fix"
|
|
28
43
|
},
|
|
@@ -32,7 +47,7 @@
|
|
|
32
47
|
],
|
|
33
48
|
"dependencies": {
|
|
34
49
|
"@aws-sdk/credential-providers": "^3.901.0",
|
|
35
|
-
"@aws-sdk/dsql-signer": "^3.
|
|
50
|
+
"@aws-sdk/dsql-signer": "^3.940.0"
|
|
36
51
|
},
|
|
37
52
|
"peerDependencies": {
|
|
38
53
|
"postgres": "^3.4.7"
|
|
@@ -40,14 +55,15 @@
|
|
|
40
55
|
"devDependencies": {
|
|
41
56
|
"@eslint/js": "^9.37.0",
|
|
42
57
|
"@types/jest": "^29.5.14",
|
|
43
|
-
"@types/node": "^
|
|
44
|
-
"@typescript-eslint/eslint-plugin": "^8.
|
|
45
|
-
"@typescript-eslint/parser": "^8.
|
|
46
|
-
"eslint": "^9.
|
|
58
|
+
"@types/node": "^25.0.0",
|
|
59
|
+
"@typescript-eslint/eslint-plugin": "^8.48.0",
|
|
60
|
+
"@typescript-eslint/parser": "^8.48.0",
|
|
61
|
+
"eslint": "^9.39.1",
|
|
47
62
|
"eslint-plugin-header": "^3.1.1",
|
|
48
|
-
"jest": "^
|
|
63
|
+
"jest": "^30.2.0",
|
|
49
64
|
"postgres": "^3.4.7",
|
|
50
65
|
"ts-jest": "^29.4.5",
|
|
66
|
+
"tsdown": "^0.17.2",
|
|
51
67
|
"typescript": "^5.9.3"
|
|
52
68
|
}
|
|
53
69
|
}
|
package/dist/client.d.ts
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import postgres, { PostgresType } from "postgres";
|
|
2
|
-
import { AwsCredentialIdentity, AwsCredentialIdentityProvider } from "@aws-sdk/types";
|
|
3
|
-
export declare function auroraDSQLPostgres<T extends Record<string, postgres.PostgresType> = {}>(url: string, options?: AuroraDSQLConfig<T>): postgres.Sql<Record<string, postgres.PostgresType> extends T ? {} : {
|
|
4
|
-
[type in keyof T]: T[type] extends {
|
|
5
|
-
serialize: (value: infer R) => any;
|
|
6
|
-
parse: (raw: any) => infer R;
|
|
7
|
-
} ? R : never;
|
|
8
|
-
}>;
|
|
9
|
-
export declare function auroraDSQLPostgres<T extends Record<string, postgres.PostgresType> = {}>(options: AuroraDSQLConfig<T>): postgres.Sql<Record<string, postgres.PostgresType> extends T ? {} : {
|
|
10
|
-
[type in keyof T]: T[type] extends {
|
|
11
|
-
serialize: (value: infer R) => any;
|
|
12
|
-
parse: (raw: any) => infer R;
|
|
13
|
-
} ? R : never;
|
|
14
|
-
}>;
|
|
15
|
-
export interface AuroraDSQLConfig<T extends Record<string, PostgresType<T>>> extends Omit<postgres.Options<T>, 'password' | 'pass'> {
|
|
16
|
-
region?: string;
|
|
17
|
-
profile?: string;
|
|
18
|
-
tokenDurationSecs?: number;
|
|
19
|
-
customCredentialsProvider?: AwsCredentialIdentity | AwsCredentialIdentityProvider;
|
|
20
|
-
}
|
|
21
|
-
//# sourceMappingURL=client.d.ts.map
|
package/dist/client.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAIA,OAAO,QAAQ,EAAE,EAAC,YAAY,EAAC,MAAM,UAAU,CAAC;AAChD,OAAO,EAAC,qBAAqB,EAAE,6BAA6B,EAAC,MAAM,gBAAgB,CAAC;AAWpF,wBAAgB,kBAAkB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,YAAY,CAAC,GAAG,EAAE,EACnF,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,gBAAgB,CAAC,CAAC,CAAC,GAC9B,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,YAAY,CAAC,SAAS,CAAC,GAAG,EAAE,GAAG;KAClE,IAAI,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,SAAS;QAC/B,SAAS,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,KAAK,GAAG,CAAC;QACnC,KAAK,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,MAAM,CAAC,CAAA;KAC/B,GAAG,CAAC,GAAG,KAAK;CAChB,CAAC,CAAC;AAEH,wBAAgB,kBAAkB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,YAAY,CAAC,GAAG,EAAE,EACnF,OAAO,EAAE,gBAAgB,CAAC,CAAC,CAAC,GAC7B,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,YAAY,CAAC,SAAS,CAAC,GAAG,EAAE,GAAG;KAClE,IAAI,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,SAAS;QAC/B,SAAS,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,KAAK,GAAG,CAAC;QACnC,KAAK,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,MAAM,CAAC,CAAA;KAC/B,GAAG,CAAC,GAAG,KAAK;CAChB,CAAC,CAAC;AA8GH,MAAM,WAAW,gBAAgB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC,CAAE,SAAQ,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,UAAU,GAAG,MAAM,CAAC;IAE/H,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAE3B,yBAAyB,CAAC,EAAE,qBAAqB,GAAG,6BAA6B,CAAC;CAErF"}
|
package/dist/client.js
DELETED
|
@@ -1,103 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
3
|
-
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
-
*/
|
|
5
|
-
import postgres from "postgres";
|
|
6
|
-
import { DsqlSigner } from "@aws-sdk/dsql-signer";
|
|
7
|
-
const ADMIN = "admin";
|
|
8
|
-
const DEFAULT_DATABASE = "postgres";
|
|
9
|
-
const DEFAULT_EXPIRY = 30; // Based on default Postgres.js connect_timeout
|
|
10
|
-
// String components of a DSQL hostname, <Cluster ID>.dsql.<region>.on.aws
|
|
11
|
-
const PRE_REGION_HOST_PATTERN = ".dsql.";
|
|
12
|
-
const POST_REGION_HOST_PATTERN = ".on.aws";
|
|
13
|
-
export function auroraDSQLPostgres(urlOrOptions, options) {
|
|
14
|
-
/* eslint-enable @typescript-eslint/no-explicit-any */
|
|
15
|
-
let opts;
|
|
16
|
-
let host;
|
|
17
|
-
let username;
|
|
18
|
-
let database;
|
|
19
|
-
let ssl;
|
|
20
|
-
if (typeof urlOrOptions === 'string') {
|
|
21
|
-
// Called with (url, options)
|
|
22
|
-
let parsedOptions = parseConnectionString(urlOrOptions);
|
|
23
|
-
host = options?.hostname || options?.host || parsedOptions.host || process.env.PGHOST;
|
|
24
|
-
username = options?.username || options?.user || parsedOptions.username || process.env.PGUSERNAME || process.env.USER || ADMIN;
|
|
25
|
-
database = options?.database || options?.db || parsedOptions.database || process.env.PGDATABASE;
|
|
26
|
-
ssl = options?.ssl || parsedOptions.ssl;
|
|
27
|
-
opts = { ...options };
|
|
28
|
-
}
|
|
29
|
-
else {
|
|
30
|
-
// Called with (options) only
|
|
31
|
-
host = urlOrOptions?.hostname || urlOrOptions?.host || process.env.PGHOST;
|
|
32
|
-
username = urlOrOptions?.username || urlOrOptions?.user || process.env.PGUSERNAME || process.env.USER || ADMIN;
|
|
33
|
-
database = urlOrOptions?.database || urlOrOptions?.db || process.env.PGDATABASE;
|
|
34
|
-
ssl = urlOrOptions?.ssl;
|
|
35
|
-
opts = { ...urlOrOptions };
|
|
36
|
-
}
|
|
37
|
-
if (Array.isArray(host)) {
|
|
38
|
-
throw new Error('Multi-host configurations are not supported for Aurora DSQL');
|
|
39
|
-
}
|
|
40
|
-
let region = opts.region || parseRegionFromHost(host);
|
|
41
|
-
if (isClusterID(host)) {
|
|
42
|
-
host = buildHostnameFromIdAndRegion(host, region);
|
|
43
|
-
opts.host = host;
|
|
44
|
-
}
|
|
45
|
-
let signerConfig = {
|
|
46
|
-
hostname: host,
|
|
47
|
-
region: opts.region || parseRegionFromHost(host),
|
|
48
|
-
expiresIn: opts.tokenDurationSecs ?? opts.connect_timeout ?? (process.env.PGCONNECT_TIMEOUT ? parseInt(process.env.PGCONNECT_TIMEOUT) : undefined) ?? DEFAULT_EXPIRY,
|
|
49
|
-
profile: opts.profile || process.env.AWS_PROFILE || "default",
|
|
50
|
-
};
|
|
51
|
-
if (opts.customCredentialsProvider) {
|
|
52
|
-
signerConfig.credentials = opts.customCredentialsProvider;
|
|
53
|
-
}
|
|
54
|
-
let signer = new DsqlSigner(signerConfig);
|
|
55
|
-
if (!database)
|
|
56
|
-
opts.database = DEFAULT_DATABASE;
|
|
57
|
-
if (!ssl)
|
|
58
|
-
opts.ssl = true;
|
|
59
|
-
const postgresOpts = {
|
|
60
|
-
...opts,
|
|
61
|
-
pass: () => getToken(signer, username),
|
|
62
|
-
};
|
|
63
|
-
return typeof urlOrOptions === 'string' ? postgres(urlOrOptions, postgresOpts) : postgres(postgresOpts);
|
|
64
|
-
}
|
|
65
|
-
function parseConnectionString(url) {
|
|
66
|
-
let decodedUrl = decodeURI(url);
|
|
67
|
-
const parsed = new URL(decodedUrl);
|
|
68
|
-
// Check for multi-host
|
|
69
|
-
if (parsed.hostname?.includes(',')) {
|
|
70
|
-
throw new Error('Multi-host connection strings are not supported for Aurora DSQL');
|
|
71
|
-
}
|
|
72
|
-
return {
|
|
73
|
-
username: parsed.username,
|
|
74
|
-
host: parsed.hostname,
|
|
75
|
-
database: parsed.pathname?.slice(1),
|
|
76
|
-
ssl: parsed.searchParams.get("ssl") || parsed.searchParams.get("sslmode") || undefined,
|
|
77
|
-
};
|
|
78
|
-
}
|
|
79
|
-
function parseRegionFromHost(host) {
|
|
80
|
-
if (!host) {
|
|
81
|
-
throw new Error("Hostname is required to parse region");
|
|
82
|
-
}
|
|
83
|
-
const match = host.match(/^(?<instance>[^.]+)\.(?<dns>dsql(?:-[^.]+)?)\.(?<domain>(?<region>[a-zA-Z0-9-]+)\.on\.aws\.?)$/i);
|
|
84
|
-
if (match?.groups) {
|
|
85
|
-
return match.groups.region;
|
|
86
|
-
}
|
|
87
|
-
throw new Error(`Unable to parse region from hostname: ${host}`);
|
|
88
|
-
}
|
|
89
|
-
function isClusterID(host) {
|
|
90
|
-
return !host.includes(".");
|
|
91
|
-
}
|
|
92
|
-
function buildHostnameFromIdAndRegion(host, region) {
|
|
93
|
-
return host + PRE_REGION_HOST_PATTERN + region + POST_REGION_HOST_PATTERN;
|
|
94
|
-
}
|
|
95
|
-
async function getToken(signer, username) {
|
|
96
|
-
if (username === ADMIN) {
|
|
97
|
-
return await signer.getDbConnectAdminAuthToken();
|
|
98
|
-
}
|
|
99
|
-
else {
|
|
100
|
-
return await signer.getDbConnectAuthToken();
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
//# sourceMappingURL=client.js.map
|
package/dist/client.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
DELETED
package/dist/index.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAAC,kBAAkB,EAAC,MAAM,UAAU,CAAC;AAC5C,YAAY,EAAC,gBAAgB,EAAC,MAAM,UAAU,CAAC"}
|
package/dist/index.js
DELETED
package/dist/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAC,kBAAkB,EAAC,MAAM,UAAU,CAAC"}
|