Skip to content

Commit 1f20c9a

Browse files
committed
Add getConnectionParameters() method to WebSocket client
Add a new getConnectionParameters() method to NeonClient that exposes PostgreSQL connection parameters sent by the server during the connection lifecycle. Added test coverage in tests/cli/ws.test.ts
1 parent 2c51902 commit 1f20c9a

File tree

6 files changed

+78
-14
lines changed

6 files changed

+78
-14
lines changed

index.d.mts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,13 @@ export declare class Client extends Client_2 {
226226
config?: (string | ClientConfig) | undefined;
227227
get neonConfig(): neonConfig;
228228
constructor(config?: (string | ClientConfig) | undefined);
229+
/**
230+
* Get connection parameters sent by PostgreSQL server.
231+
* Returns a read-only Map containing parameters like 'client_encoding', 'TimeZone', 'server_version', etc.
232+
* This is only available for WebSocket connections (Client/Pool), not for HTTP queries.
233+
* The Map is populated after connect() completes.
234+
*/
235+
getConnectionParameters(): ReadonlyMap<string, string>;
229236
connect(): Promise<void>;
230237
connect(callback: (err?: Error) => void): void;
231238
_handleAuthSASLContinue(msg: any): Promise<void>;

index.d.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,13 @@ export declare class Client extends Client_2 {
226226
config?: (string | ClientConfig) | undefined;
227227
get neonConfig(): neonConfig;
228228
constructor(config?: (string | ClientConfig) | undefined);
229+
/**
230+
* Get connection parameters sent by PostgreSQL server.
231+
* Returns a read-only Map containing parameters like 'client_encoding', 'TimeZone', 'server_version', etc.
232+
* This is only available for WebSocket connections (Client/Pool), not for HTTP queries.
233+
* The Map is populated after connect() completes.
234+
*/
235+
getConnectionParameters(): ReadonlyMap<string, string>;
229236
connect(): Promise<void>;
230237
connect(callback: (err?: Error) => void): void;
231238
_handleAuthSASLContinue(msg: any): Promise<void>;

index.js

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1307,13 +1307,15 @@ c.dataTypeID)),u=e===!0?r.rows.map(c=>c.map((l,f)=>l===null?null:o[f](l))):r.row
13071307
c.map((l,f)=>[s[f],l===null?null:o[f](l)])));return t?(r.viaNeonFetch=!0,r.rowAsArray=e,r.rows=u,r._parsers=
13081308
o,r._types=i,r):u}a(as,"processQueryResult");async function Fu(r){if(typeof r=="string")return r;if(typeof r==
13091309
"function")try{return await Promise.resolve(r())}catch(e){let t=new de("Error getting auth token.");
1310-
throw e instanceof Error&&(t=new de(`Error getting auth token: ${e.message}`)),t}}a(Fu,"getAuthToken");p();var go=Ae(ct());p();var wo=Ae(ct());var Un=class Un extends wo.Client{constructor(t){super(t);this.config=t}get neonConfig(){return this.
1311-
connection.stream}connect(t){let{neonConfig:n}=this;n.forceDisablePgSSL&&(this.ssl=this.connection.ssl=
1312-
!1),this.ssl&&n.useSecureWebSocket&&console.warn("SSL is enabled for both Postgres (e.g. ?sslmode=re\
1313-
quire in the connection string + forceDisablePgSSL = false) and the WebSocket tunnel (useSecureWebSo\
1314-
cket = true). Double encryption will increase latency and CPU usage. It may be appropriate to disabl\
1315-
e SSL in the Postgres connection parameters or set forceDisablePgSSL = true.");let i=typeof this.config!=
1316-
"string"&&this.config?.host!==void 0||typeof this.config!="string"&&this.config?.connectionString!==
1310+
throw e instanceof Error&&(t=new de(`Error getting auth token: ${e.message}`)),t}}a(Fu,"getAuthToken");p();var go=Ae(ct());p();var wo=Ae(ct());var Un=class Un extends wo.Client{constructor(t){super(t);this.config=t;E(this,"_connectionParameter\
1311+
s",new Map);this.connection.on("parameterStatus",n=>{this._connectionParameters.set(n.parameterName,
1312+
n.parameterValue)})}get neonConfig(){return this.connection.stream}getConnectionParameters(){return this.
1313+
_connectionParameters}connect(t){let{neonConfig:n}=this;n.forceDisablePgSSL&&(this.ssl=this.connection.
1314+
ssl=!1),this.ssl&&n.useSecureWebSocket&&console.warn("SSL is enabled for both Postgres (e.g. ?sslmod\
1315+
e=require in the connection string + forceDisablePgSSL = false) and the WebSocket tunnel (useSecureW\
1316+
ebSocket = true). Double encryption will increase latency and CPU usage. It may be appropriate to di\
1317+
sable SSL in the Postgres connection parameters or set forceDisablePgSSL = true.");let i=typeof this.
1318+
config!="string"&&this.config?.host!==void 0||typeof this.config!="string"&&this.config?.connectionString!==
13171319
void 0||m.env.PGHOST!==void 0,s=m.env.USER??m.env.USERNAME;if(!i&&this.host==="localhost"&&this.user===
13181320
s&&this.database===s&&this.password===null)throw new Error(`No database host or connection string wa\
13191321
s set, and key parameters have default values (host: localhost, user: ${s}, db: ${s}, password: null\

index.mjs

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1305,13 +1305,15 @@ c.dataTypeID)),u=e===!0?r.rows.map(c=>c.map((l,f)=>l===null?null:o[f](l))):r.row
13051305
c.map((l,f)=>[s[f],l===null?null:o[f](l)])));return t?(r.viaNeonFetch=!0,r.rowAsArray=e,r.rows=u,r._parsers=
13061306
o,r._types=i,r):u}a(os,"processQueryResult");async function Fu(r){if(typeof r=="string")return r;if(typeof r==
13071307
"function")try{return await Promise.resolve(r())}catch(e){let t=new be("Error getting auth token.");
1308-
throw e instanceof Error&&(t=new be(`Error getting auth token: ${e.message}`)),t}}a(Fu,"getAuthToken");p();var go=Se(ot());p();var wo=Se(ot());var kn=class kn extends wo.Client{constructor(t){super(t);this.config=t}get neonConfig(){return this.
1309-
connection.stream}connect(t){let{neonConfig:n}=this;n.forceDisablePgSSL&&(this.ssl=this.connection.ssl=
1310-
!1),this.ssl&&n.useSecureWebSocket&&console.warn("SSL is enabled for both Postgres (e.g. ?sslmode=re\
1311-
quire in the connection string + forceDisablePgSSL = false) and the WebSocket tunnel (useSecureWebSo\
1312-
cket = true). Double encryption will increase latency and CPU usage. It may be appropriate to disabl\
1313-
e SSL in the Postgres connection parameters or set forceDisablePgSSL = true.");let i=typeof this.config!=
1314-
"string"&&this.config?.host!==void 0||typeof this.config!="string"&&this.config?.connectionString!==
1308+
throw e instanceof Error&&(t=new be(`Error getting auth token: ${e.message}`)),t}}a(Fu,"getAuthToken");p();var go=Se(ot());p();var wo=Se(ot());var kn=class kn extends wo.Client{constructor(t){super(t);this.config=t;E(this,"_connectionParameter\
1309+
s",new Map);this.connection.on("parameterStatus",n=>{this._connectionParameters.set(n.parameterName,
1310+
n.parameterValue)})}get neonConfig(){return this.connection.stream}getConnectionParameters(){return this.
1311+
_connectionParameters}connect(t){let{neonConfig:n}=this;n.forceDisablePgSSL&&(this.ssl=this.connection.
1312+
ssl=!1),this.ssl&&n.useSecureWebSocket&&console.warn("SSL is enabled for both Postgres (e.g. ?sslmod\
1313+
e=require in the connection string + forceDisablePgSSL = false) and the WebSocket tunnel (useSecureW\
1314+
ebSocket = true). Double encryption will increase latency and CPU usage. It may be appropriate to di\
1315+
sable SSL in the Postgres connection parameters or set forceDisablePgSSL = true.");let i=typeof this.
1316+
config!="string"&&this.config?.host!==void 0||typeof this.config!="string"&&this.config?.connectionString!==
13151317
void 0||m.env.PGHOST!==void 0,s=m.env.USER??m.env.USERNAME;if(!i&&this.host==="localhost"&&this.user===
13161318
s&&this.database===s&&this.password===null)throw new Error(`No database host or connection string wa\
13171319
s set, and key parameters have default values (host: localhost, user: ${s}, db: ${s}, password: null\

src/client.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,29 @@ export declare interface NeonClient {
2020
* https://node-postgres.com/apis/client
2121
*/
2222
export class NeonClient extends Client {
23+
private _connectionParameters: Map<string, string> = new Map();
24+
2325
get neonConfig() {
2426
return this.connection.stream as Socket;
2527
}
2628

2729
constructor(public config?: string | ClientConfig) {
2830
super(config);
31+
32+
// Set up parameterStatus listener to capture connection parameters from PostgreSQL
33+
this.connection.on('parameterStatus', (msg: any) => {
34+
this._connectionParameters.set(msg.parameterName, msg.parameterValue);
35+
});
36+
}
37+
38+
/**
39+
* Get connection parameters sent by PostgreSQL server.
40+
* Returns a read-only Map containing parameters like 'client_encoding', 'TimeZone', 'server_version', etc.
41+
* This is only available for WebSocket connections (Client/Pool), not for HTTP queries.
42+
* The Map is populated after connect() completes.
43+
*/
44+
getConnectionParameters(): ReadonlyMap<string, string> {
45+
return this._connectionParameters;
2946
}
3047

3148
override connect(): Promise<void>;

tests/cli/ws.test.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,4 +174,33 @@ describe.each([
174174
expect((wsResult as any).viaNeonFetch).toBeUndefined();
175175
});
176176
}
177+
178+
test('Client.getConnectionParameters() returns connection parameters', async () => {
179+
const client = new WsClient({ connectionString: DB_URL });
180+
181+
// Before connect, parameters should be empty
182+
const paramsBefore = client.getConnectionParameters();
183+
expect(paramsBefore.size).toBe(0);
184+
185+
await client.connect();
186+
187+
// After connect, parameters should be populated
188+
const params = client.getConnectionParameters();
189+
expect(params.size).toBeGreaterThan(0);
190+
191+
// Check for common PostgreSQL parameters
192+
expect(params.get('client_encoding')).toBeDefined();
193+
expect(params.get('server_version')).toBeDefined();
194+
expect(params.get('TimeZone')).toBeDefined();
195+
expect(params.get('DateStyle')).toBeDefined();
196+
expect(params.get('integer_datetimes')).toBeDefined();
197+
198+
// Verify it's read-only (returns ReadonlyMap)
199+
expect(() => {
200+
// @ts-expect-error - should not be able to set on ReadonlyMap
201+
params.set('test', 'value');
202+
}).toThrow();
203+
204+
await client.end();
205+
});
177206
});

0 commit comments

Comments
 (0)