@m2k-5f/pgtx 2.2.0 → 2.3.1

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.
Files changed (40) hide show
  1. package/README.md +372 -307
  2. package/dist/clauses/abstract.clause.js +1 -5
  3. package/dist/clauses/array.clause.js +3 -7
  4. package/dist/clauses/empty.clause.js +3 -7
  5. package/dist/clauses/exclude.clause.js +2 -6
  6. package/dist/clauses/fragment.clause.js +4 -8
  7. package/dist/clauses/iden.caluse.js +2 -6
  8. package/dist/clauses/index.js +9 -25
  9. package/dist/clauses/insert.clause.js +2 -6
  10. package/dist/clauses/literal.clause.js +2 -6
  11. package/dist/clauses/update.clause.js +2 -6
  12. package/dist/clauses/where.clause.js +2 -6
  13. package/dist/connection.d.ts +11 -7
  14. package/dist/connection.d.ts.map +1 -1
  15. package/dist/connection.js +108 -111
  16. package/dist/error.d.ts +1 -1
  17. package/dist/error.d.ts.map +1 -1
  18. package/dist/error.js +2 -6
  19. package/dist/index.js +24 -37
  20. package/dist/pool.d.ts +9 -7
  21. package/dist/pool.d.ts.map +1 -1
  22. package/dist/pool.js +29 -42
  23. package/dist/protocol/connection-request-writer.js +13 -18
  24. package/dist/protocol/connection-response-reader.js +4 -9
  25. package/dist/protocol/constants.js +4 -7
  26. package/dist/protocol/socket-authorization.d.ts +5 -1
  27. package/dist/protocol/socket-authorization.d.ts.map +1 -1
  28. package/dist/protocol/socket-authorization.js +38 -34
  29. package/dist/protocol/socket-connector.js +3 -7
  30. package/dist/query.js +2 -6
  31. package/dist/queue.js +1 -5
  32. package/dist/security/md5.js +4 -8
  33. package/dist/security/sasl.js +7 -11
  34. package/dist/transaction.d.ts +7 -5
  35. package/dist/transaction.d.ts.map +1 -1
  36. package/dist/transaction.js +18 -26
  37. package/dist/types.js +0 -2
  38. package/dist/utils/template-compiler.js +3 -6
  39. package/dist/utils/value-parser.js +2 -7
  40. package/package.json +9 -2
package/dist/pool.d.ts CHANGED
@@ -1,5 +1,7 @@
1
1
  import { Connection, ConnectionParams } from "./connection";
2
2
  import { Transaction } from "./transaction";
3
+ import { Future } from "fluent-future";
4
+ import { PostgresError } from "./error";
3
5
  type PoolParams = ConnectionParams & {
4
6
  max?: number;
5
7
  };
@@ -35,7 +37,7 @@ type PoolParams = ConnectionParams & {
35
37
  * }
36
38
  *
37
39
  * // Clean up
38
- * await pool.close()
40
+ * pool.close()
39
41
  * ```
40
42
  */
41
43
  export declare class Pool {
@@ -65,7 +67,7 @@ export declare class Pool {
65
67
  * }
66
68
  * ```
67
69
  */
68
- acquire(): Promise<Connection>;
70
+ acquire(): Future<Connection, Error>;
69
71
  /**
70
72
  * Releases the connection back to the pool.
71
73
  *
@@ -103,7 +105,7 @@ export declare class Pool {
103
105
  * })
104
106
  * ```
105
107
  */
106
- begin<T>(txCallback: (transaction: Transaction) => Promise<T>): Promise<T>;
108
+ begin<T>(txCallback: (transaction: Transaction) => Promise<T>): Future<T, Error>;
107
109
  /**
108
110
  * Executes a one-off query using pipeline.
109
111
  *
@@ -127,7 +129,7 @@ export declare class Pool {
127
129
  * const users = await pool.query<User>`SELECT * FROM users`
128
130
  * ```
129
131
  */
130
- query<T extends Record<string, any>>(templates: TemplateStringsArray, ...args: any[]): Promise<T[]>;
132
+ query<T extends Record<string, any>>(templates: TemplateStringsArray, ...args: any[]): Future<T[], Error>;
131
133
  /**
132
134
  * Sends an asynchronous notification to a channel via `pg_notify`.
133
135
  *
@@ -139,7 +141,7 @@ export declare class Pool {
139
141
  * await pool.notify('events', 'hello')
140
142
  * ```
141
143
  */
142
- notify(channelName: string, payload?: string): Promise<[]>;
144
+ notify(channelName: string, payload?: string): Future<[], PostgresError>;
143
145
  /**
144
146
  * Number of available (idle) connections in the pool.
145
147
  */
@@ -157,10 +159,10 @@ export declare class Pool {
157
159
  *
158
160
  * @example
159
161
  * ```ts
160
- * await pool.close()
162
+ * pool.close()
161
163
  * ```
162
164
  */
163
- close(): Promise<void>;
165
+ close(): void;
164
166
  }
165
167
  export {};
166
168
  //# sourceMappingURL=pool.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"pool.d.ts","sourceRoot":"","sources":["../src/pool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAA;AAC3D,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAK3C,KAAK,UAAU,GAAG,gBAAgB,GAAG;IACjC,GAAG,CAAC,EAAE,MAAM,CAAA;CACf,CAAA;AAQD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,qBAAa,IAAI;IACb,OAAO,CAAC,UAAU,CAA0B;IAC5C,OAAO,CAAC,OAAO,CAAkB;IACjC,OAAO,CAAC,IAAI,CAAQ;IACpB,OAAO,CAAC,MAAM,CAAI;IAClB,OAAO,CAAC,QAAQ,CAAsB;IACtC,OAAO,CAAC,SAAS,CAAQ;IAEzB,OAAO,CAAC,YAAY;gBAIR,MAAM,EAAE,UAAU;IAM9B;;;;;;;;;;;;;;;;;OAiBG;IACG,OAAO,IAAI,OAAO,CAAC,UAAU,CAAC;IA6BpC;;;;;;;;;;;;;;;;;OAiBG;IACH,OAAO,CAAC,IAAI,EAAE,UAAU;IAoBxB;;;;;;;;;;;;;;;;;OAiBG;IACG,KAAK,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,WAAW,EAAE,WAAW,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAYhF;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACH,KAAK,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,SAAS,EAAE,oBAAoB,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC,CAAC,EAAE,CAAC;IAmCnG;;;;;;;;;;OAUG;IACH,MAAM,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,GAAE,MAAW,GACuB,OAAO,CAAC,EAAE,CAAC;IAIlF;;OAEG;IACH,IAAI,IAAI,WAEP;IAGD;;;OAGG;IACH,IAAI,KAAK,WAER;IAGD;;;;;;;;;;OAUG;IACG,KAAK;CAed"}
1
+ {"version":3,"file":"pool.d.ts","sourceRoot":"","sources":["../src/pool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAA;AAC3D,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAG3C,OAAO,EAAE,MAAM,EAAW,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAGxC,KAAK,UAAU,GAAG,gBAAgB,GAAG;IACjC,GAAG,CAAC,EAAE,MAAM,CAAA;CACf,CAAA;AAQD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,qBAAa,IAAI;IACb,OAAO,CAAC,UAAU,CAA0B;IAC5C,OAAO,CAAC,OAAO,CAAkB;IACjC,OAAO,CAAC,IAAI,CAAQ;IACpB,OAAO,CAAC,MAAM,CAAI;IAClB,OAAO,CAAC,QAAQ,CAAsB;IACtC,OAAO,CAAC,SAAS,CAAQ;IAEzB,OAAO,CAAC,YAAY;gBAIR,MAAM,EAAE,UAAU;IAM9B;;;;;;;;;;;;;;;;;OAiBG;IACH,OAAO;IA0BP;;;;;;;;;;;;;;;;;OAiBG;IACH,OAAO,CAAC,IAAI,EAAE,UAAU;IAoBxB;;;;;;;;;;;;;;;;;OAiBG;IACH,KAAK,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,WAAW,EAAE,WAAW,KAAK,OAAO,CAAC,CAAC,CAAC;IAW7D;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACH,KAAK,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,SAAS,EAAE,oBAAoB,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE;IAiCpF;;;;;;;;;;OAUG;IACH,MAAM,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,GAAE,MAAW,GACuB,MAAM,CAAC,EAAE,EAAE,aAAa,CAAC;IAIhG;;OAEG;IACH,IAAI,IAAI,WAEP;IAGD;;;OAGG;IACH,IAAI,KAAK,WAER;IAGD;;;;;;;;;;OAUG;IACH,KAAK;CAeR"}
package/dist/pool.js CHANGED
@@ -1,8 +1,6 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.Pool = void 0;
4
- const connection_1 = require("./connection");
5
- const queue_1 = require("./queue");
1
+ import { Connection } from "./connection";
2
+ import { Queue } from "./queue";
3
+ import { Future, Resolve } from "fluent-future";
6
4
  /**
7
5
  * The main entry point for Pgtx.
8
6
  * Manages a connection pool and provides high-level API for queries and transactions.
@@ -35,18 +33,18 @@ const queue_1 = require("./queue");
35
33
  * }
36
34
  *
37
35
  * // Clean up
38
- * await pool.close()
36
+ * pool.close()
39
37
  * ```
40
38
  */
41
- class Pool {
39
+ export class Pool {
42
40
  _checkClosed() {
43
41
  if (this._isClosed)
44
42
  throw new Error('Pool closed');
45
43
  }
46
44
  constructor(params) {
47
- this._available = new queue_1.Queue();
45
+ this._available = new Queue();
48
46
  this._total = 0;
49
- this._waiting = new queue_1.Queue();
47
+ this._waiting = new Queue();
50
48
  this._isClosed = false;
51
49
  this._config = params;
52
50
  this._max = params.max || 20;
@@ -69,29 +67,24 @@ class Pool {
69
67
  * }
70
68
  * ```
71
69
  */
72
- async acquire() {
70
+ acquire() {
73
71
  this._checkClosed();
74
72
  while (this._available.hasMore) {
75
73
  const conn = this._available.get();
76
74
  this._available.next();
77
75
  if (conn.isOpened) {
78
- return conn;
76
+ return Resolve(conn);
79
77
  }
80
78
  this._total--;
81
79
  }
82
80
  if (this._total < this._max) {
83
81
  this._total++;
84
- try {
85
- return await connection_1.Connection.new(this._config);
86
- }
87
- catch (err) {
88
- this._total--;
89
- throw err;
90
- }
82
+ return Future.of(Connection.new(this._config))
83
+ .tapErr(() => this._total--);
91
84
  }
92
- return new Promise((resolve, reject) => {
85
+ return Future.of(new Promise((resolve, reject) => {
93
86
  this._waiting.push({ resolve, reject });
94
- });
87
+ }));
95
88
  }
96
89
  /**
97
90
  * Releases the connection back to the pool.
@@ -143,15 +136,11 @@ class Pool {
143
136
  * })
144
137
  * ```
145
138
  */
146
- async begin(txCallback) {
139
+ begin(txCallback) {
147
140
  this._checkClosed();
148
- const conn = await this.acquire();
149
- try {
150
- return conn.begin(txCallback);
151
- }
152
- finally {
153
- this.release(conn);
154
- }
141
+ return this.acquire()
142
+ .andThen(conn => conn.begin(txCallback)
143
+ .finally(() => this.release(conn)));
155
144
  }
156
145
  /**
157
146
  * Executes a one-off query using pipeline.
@@ -180,26 +169,25 @@ class Pool {
180
169
  this._checkClosed();
181
170
  while (this._available.hasMore) {
182
171
  const conn = this._available.get();
183
- if (conn.isOpened) {
184
- return conn.query(templates, ...args);
185
- }
186
172
  this._available.next();
187
- this._total--;
173
+ if (!conn.isOpened) {
174
+ this._total--;
175
+ continue;
176
+ }
177
+ this._available.push(conn);
178
+ return conn.query(templates, ...args);
188
179
  }
189
180
  if (this._total < this._max) {
190
181
  this._total++;
191
- return connection_1.Connection.new(this._config)
192
- .catch(err => {
193
- this._total--;
194
- throw err;
195
- })
196
- .then(conn => {
182
+ return Future.of(Connection.new(this._config))
183
+ .tapErr(() => this._total--)
184
+ .andThen(conn => {
197
185
  this.release(conn);
198
186
  return conn.query(templates, ...args);
199
187
  });
200
188
  }
201
189
  return this.acquire()
202
- .then(conn => {
190
+ .andThen(conn => {
203
191
  this.release(conn);
204
192
  return conn.query(templates, ...args);
205
193
  });
@@ -239,10 +227,10 @@ class Pool {
239
227
  *
240
228
  * @example
241
229
  * ```ts
242
- * await pool.close()
230
+ * pool.close()
243
231
  * ```
244
232
  */
245
- async close() {
233
+ close() {
246
234
  while (this._available.hasMore) {
247
235
  const conn = this._available.get();
248
236
  this._available.next();
@@ -256,4 +244,3 @@ class Pool {
256
244
  this._total = 0;
257
245
  }
258
246
  }
259
- exports.Pool = Pool;
@@ -1,8 +1,5 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ConnectionRequestWriter = exports.ConnectionRequestBuffer = void 0;
4
- const constants_1 = require("./constants");
5
- class ConnectionRequestBuffer {
1
+ import { RequestTypes } from "./constants";
2
+ export class ConnectionRequestBuffer {
6
3
  constructor(buffer, offset = 0, lastRequestLenByteOffset = 0) {
7
4
  this.buffer = buffer;
8
5
  this.offset = offset;
@@ -75,8 +72,7 @@ class ConnectionRequestBuffer {
75
72
  this.lastRequestLenByteOffset = 0;
76
73
  }
77
74
  }
78
- exports.ConnectionRequestBuffer = ConnectionRequestBuffer;
79
- class ConnectionRequestWriter {
75
+ export class ConnectionRequestWriter {
80
76
  constructor(buffer) {
81
77
  this.buffer = buffer;
82
78
  }
@@ -84,13 +80,13 @@ class ConnectionRequestWriter {
84
80
  return new ConnectionRequestWriter(ConnectionRequestBuffer.new(65536));
85
81
  }
86
82
  writeQuery(text) {
87
- this.buffer.startRequest(constants_1.RequestTypes.SimpleQuery)
83
+ this.buffer.startRequest(RequestTypes.SimpleQuery)
88
84
  .writeCString(text)
89
85
  .endRequest();
90
86
  return this;
91
87
  }
92
88
  writeParse(name, text) {
93
- this.buffer.startRequest(constants_1.RequestTypes.Parse)
89
+ this.buffer.startRequest(RequestTypes.Parse)
94
90
  .writeCString(name)
95
91
  .writeCString(text)
96
92
  .writeInt16(0)
@@ -98,14 +94,14 @@ class ConnectionRequestWriter {
98
94
  return this;
99
95
  }
100
96
  writeDescribe(statementName) {
101
- this.buffer.startRequest(constants_1.RequestTypes.Describe)
97
+ this.buffer.startRequest(RequestTypes.Describe)
102
98
  .writeChar('S')
103
99
  .writeCString(statementName)
104
100
  .endRequest();
105
101
  return this;
106
102
  }
107
103
  writeBind(portName, statementName, params) {
108
- const request = this.buffer.startRequest(constants_1.RequestTypes.Bind)
104
+ const request = this.buffer.startRequest(RequestTypes.Bind)
109
105
  .writeCString(portName)
110
106
  .writeCString(statementName)
111
107
  .writeInt16(0)
@@ -118,7 +114,7 @@ class ConnectionRequestWriter {
118
114
  return this;
119
115
  }
120
116
  writeClose(name) {
121
- this.buffer.startRequest(constants_1.RequestTypes.Close)
117
+ this.buffer.startRequest(RequestTypes.Close)
122
118
  .writeChar("P")
123
119
  .writeCString(name)
124
120
  .endRequest();
@@ -134,24 +130,24 @@ class ConnectionRequestWriter {
134
130
  return this;
135
131
  }
136
132
  writeExecute(portName) {
137
- this.buffer.startRequest(constants_1.RequestTypes.Execute)
133
+ this.buffer.startRequest(RequestTypes.Execute)
138
134
  .writeCString(portName)
139
135
  .writeInt32(0)
140
136
  .endRequest();
141
137
  return this;
142
138
  }
143
139
  writeSync() {
144
- this.buffer.startRequest(constants_1.RequestTypes.Sync).endRequest();
140
+ this.buffer.startRequest(RequestTypes.Sync).endRequest();
145
141
  return this;
146
142
  }
147
143
  writePassword(password) {
148
- this.buffer.startRequest(constants_1.RequestTypes.Password)
144
+ this.buffer.startRequest(RequestTypes.Password)
149
145
  .writeCString(password)
150
146
  .endRequest();
151
147
  return this;
152
148
  }
153
149
  writeSaslInitial(mechanism, clientFirstMessage) {
154
- this.buffer.startRequest(constants_1.RequestTypes.Password)
150
+ this.buffer.startRequest(RequestTypes.Password)
155
151
  .writeCString(mechanism)
156
152
  .writeInt32(Buffer.byteLength(clientFirstMessage, 'utf-8'))
157
153
  .writeString(clientFirstMessage)
@@ -159,7 +155,7 @@ class ConnectionRequestWriter {
159
155
  return this;
160
156
  }
161
157
  writeSaslResponse(clientFinalMessage) {
162
- this.buffer.startRequest(constants_1.RequestTypes.Password)
158
+ this.buffer.startRequest(RequestTypes.Password)
163
159
  .writeString(clientFinalMessage)
164
160
  .endRequest();
165
161
  return this;
@@ -172,4 +168,3 @@ class ConnectionRequestWriter {
172
168
  return this;
173
169
  }
174
170
  }
175
- exports.ConnectionRequestWriter = ConnectionRequestWriter;
@@ -1,8 +1,5 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ConnectionResponseReader = exports.ConnectionResponseBuffer = void 0;
4
- const error_1 = require("../error");
5
- class ConnectionResponseBuffer {
1
+ import { PostgresError } from "../error";
2
+ export class ConnectionResponseBuffer {
6
3
  constructor(buffer) {
7
4
  this.buffer = buffer;
8
5
  this.caret = 0;
@@ -57,8 +54,7 @@ class ConnectionResponseBuffer {
57
54
  return this.buffer.subarray(this.caret);
58
55
  }
59
56
  }
60
- exports.ConnectionResponseBuffer = ConnectionResponseBuffer;
61
- class ConnectionResponseReader {
57
+ export class ConnectionResponseReader {
62
58
  constructor(buffer) {
63
59
  this.buffer = buffer;
64
60
  this.currentPacketLength = 0;
@@ -136,7 +132,7 @@ class ConnectionResponseReader {
136
132
  break;
137
133
  }
138
134
  }
139
- return new error_1.PostgresError(message, code, detail, severity, where, hint, position, dataType, constraint);
135
+ return new PostgresError(message, code, detail, severity, where, hint, position, dataType, constraint);
140
136
  }
141
137
  readReadyForQuery() {
142
138
  this.buffer.readInt32();
@@ -225,4 +221,3 @@ class ConnectionResponseReader {
225
221
  this.buffer.readInt32();
226
222
  }
227
223
  }
228
- exports.ConnectionResponseReader = ConnectionResponseReader;
@@ -1,7 +1,4 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.TransactionStatuses = exports.AuthenticationCodes = exports.ResponseTypes = exports.RequestTypes = void 0;
4
- exports.RequestTypes = {
1
+ export const RequestTypes = {
5
2
  SimpleQuery: "Q",
6
3
  Parse: "P",
7
4
  Bind: "B",
@@ -11,7 +8,7 @@ exports.RequestTypes = {
11
8
  Describe: 'D',
12
9
  Close: "C"
13
10
  };
14
- exports.ResponseTypes = {
11
+ export const ResponseTypes = {
15
12
  RowDescription: "T",
16
13
  DataRow: "D",
17
14
  ComandComplete: "C",
@@ -29,7 +26,7 @@ exports.ResponseTypes = {
29
26
  Notice: "N",
30
27
  NotificationResponse: "A"
31
28
  };
32
- exports.AuthenticationCodes = {
29
+ export const AuthenticationCodes = {
33
30
  Ok: 0,
34
31
  CleartextPassword: 3,
35
32
  MD5Password: 5,
@@ -37,7 +34,7 @@ exports.AuthenticationCodes = {
37
34
  SASLContinue: 11,
38
35
  SASLFinal: 12,
39
36
  };
40
- exports.TransactionStatuses = {
37
+ export const TransactionStatuses = {
41
38
  Idle: "I",
42
39
  InTransactionBlock: "T",
43
40
  FailedTransactionBlock: "E",
@@ -1,5 +1,7 @@
1
1
  import { Socket } from "node:net";
2
2
  import { ConnectionRequestWriter } from "./connection-request-writer";
3
+ import { PostgresError } from "../error";
4
+ import { Future } from "fluent-future";
3
5
  export type AuthorizationParams = {
4
6
  host: string;
5
7
  port: number;
@@ -7,5 +9,7 @@ export type AuthorizationParams = {
7
9
  database: string;
8
10
  password?: string;
9
11
  };
10
- export declare const createAuthorizedSocket: (writer: ConnectionRequestWriter, params: AuthorizationParams) => Promise<Socket>;
12
+ export declare const ErrNonceMismatch: PostgresError;
13
+ export declare const ErrPasswordRequired: PostgresError;
14
+ export declare const createAuthorizedSocket: (writer: ConnectionRequestWriter, params: AuthorizationParams) => Future<Socket, PostgresError>;
11
15
  //# sourceMappingURL=socket-authorization.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"socket-authorization.d.ts","sourceRoot":"","sources":["../../src/protocol/socket-authorization.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoB,MAAM,EAAE,MAAM,UAAU,CAAA;AACnD,OAAO,EAAE,uBAAuB,EAAE,MAAM,6BAA6B,CAAA;AAOrE,MAAM,MAAM,mBAAmB,GAAG;IAC9B,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAA;CACpB,CAAA;AAGD,eAAO,MAAM,sBAAsB,GAAI,QAAQ,uBAAuB,EAAE,QAAQ,mBAAmB,oBAiHlG,CAAA"}
1
+ {"version":3,"file":"socket-authorization.d.ts","sourceRoot":"","sources":["../../src/protocol/socket-authorization.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoB,MAAM,EAAE,MAAM,UAAU,CAAA;AACnD,OAAO,EAAE,uBAAuB,EAAE,MAAM,6BAA6B,CAAA;AAKrE,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AACxC,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAA;AAGtC,MAAM,MAAM,mBAAmB,GAAG;IAC9B,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAA;CACpB,CAAA;AAGD,eAAO,MAAM,gBAAgB,eAAmF,CAAA;AAChH,eAAO,MAAM,mBAAmB,eAAqE,CAAA;AAIrG,eAAO,MAAM,sBAAsB,GAAI,QAAQ,uBAAuB,EAAE,QAAQ,mBAAmB,kCAwHlG,CAAA"}
@@ -1,85 +1,86 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.createAuthorizedSocket = void 0;
4
- const node_net_1 = require("node:net");
5
- const sasl_1 = require("../security/sasl");
6
- const socket_connector_1 = require("./socket-connector");
7
- const constants_1 = require("./constants");
8
- const md5_1 = require("../security/md5");
9
- const createAuthorizedSocket = (writer, params) => {
10
- return new Promise((resolve, reject) => {
11
- const nonce = (0, sasl_1.generateNonce)();
1
+ import { createConnection } from "node:net";
2
+ import { calculateScramAuth, generateNonce } from "../security/sasl";
3
+ import { SocketConnector } from "./socket-connector";
4
+ import { AuthenticationCodes, ResponseTypes } from "./constants";
5
+ import { encryptMd5 } from "../security/md5";
6
+ import { PostgresError } from "../error";
7
+ import { Future } from "fluent-future";
8
+ export const ErrNonceMismatch = new PostgresError("Protocol violation: server nonce doesn't match client nonce");
9
+ export const ErrPasswordRequired = new PostgresError('The authorization method requires a password.');
10
+ export const createAuthorizedSocket = (writer, params) => {
11
+ return Future.of(new Promise((resolve, reject) => {
12
+ const nonce = generateNonce();
12
13
  let clientMessage = '';
13
14
  let serverMessage = '';
14
- const socket = (0, node_net_1.createConnection)({ host: params.host, port: params.port });
15
- const connector = new socket_connector_1.SocketConnector(socket, (type, reader) => {
15
+ const socket = createConnection({ host: params.host, port: params.port });
16
+ const connector = new SocketConnector(socket, (type, reader) => {
16
17
  writer.clear();
17
18
  switch (type) {
18
- case constants_1.ResponseTypes.Authentication: {
19
+ case ResponseTypes.Authentication: {
19
20
  switch (reader.readAuthentication()) {
20
- case constants_1.AuthenticationCodes.Ok: break;
21
- case constants_1.AuthenticationCodes.CleartextPassword: {
21
+ case AuthenticationCodes.Ok: break;
22
+ case AuthenticationCodes.CleartextPassword: {
22
23
  if (!params.password)
23
- throw new Error('The authorization method requires a password.');
24
+ throw ErrPasswordRequired;
24
25
  connector.write(writer.writePassword(params.password));
25
26
  break;
26
27
  }
27
- case constants_1.AuthenticationCodes.MD5Password: {
28
+ case AuthenticationCodes.MD5Password: {
28
29
  const salt = reader.readMD5Salt();
29
30
  if (!params.password)
30
- throw new Error('The authorization method requires a password.');
31
- const password = (0, md5_1.encryptMd5)(params.password, params.user, salt);
31
+ throw ErrPasswordRequired;
32
+ const password = encryptMd5(params.password, params.user, salt);
32
33
  connector.write(writer.writePassword(password));
33
34
  break;
34
35
  }
35
- case constants_1.AuthenticationCodes.SASL: {
36
+ case AuthenticationCodes.SASL: {
36
37
  reader.readSaslMechanisms();
37
38
  if (!params.password)
38
- throw new Error('The authorization method requires a password.');
39
+ throw ErrPasswordRequired;
39
40
  clientMessage = `n=${params.user},r=${nonce}`;
40
41
  connector.write(writer.writeSaslInitial('SCRAM-SHA-256', `n,,${clientMessage}`));
41
42
  break;
42
43
  }
43
- case constants_1.AuthenticationCodes.SASLContinue: {
44
+ case AuthenticationCodes.SASLContinue: {
44
45
  serverMessage = reader.readSaslMessage();
45
46
  if (!params.password)
46
- throw new Error('The authorization method requires a password.');
47
+ throw ErrPasswordRequired;
47
48
  const parts = Object.fromEntries(serverMessage.split(',').map(x => x.split('=')));
48
49
  const serverNonce = parts.r;
49
50
  const saltBase64 = parts.s;
50
51
  const iterations = parseInt(parts.i, 10);
51
52
  if (!serverNonce.startsWith(nonce)) {
52
53
  connector.destroy();
53
- return reject("Protocol violation: server nonce doesn't match client nonce");
54
+ return reject(ErrNonceMismatch);
54
55
  }
55
56
  const clientFinalMessageWithoutProof = `c=biws,r=${serverNonce}`;
56
57
  const authMessage = `${clientMessage},${serverMessage},${clientFinalMessageWithoutProof}`;
57
- const { clientProof } = (0, sasl_1.calculateScramAuth)(params.password, saltBase64, iterations, authMessage);
58
+ const { clientProof } = calculateScramAuth(params.password, saltBase64, iterations, authMessage);
58
59
  const clientFinalMessage = `${clientFinalMessageWithoutProof},p=${clientProof}`;
59
60
  connector.write(writer.writeSaslResponse(clientFinalMessage));
60
61
  break;
61
62
  }
62
- case constants_1.AuthenticationCodes.SASLFinal: {
63
+ case AuthenticationCodes.SASLFinal: {
63
64
  reader.readSaslMessage();
64
65
  break;
65
66
  }
66
67
  }
67
68
  break;
68
69
  }
69
- case constants_1.ResponseTypes.ParamaterStatus: {
70
+ case ResponseTypes.ParamaterStatus: {
70
71
  reader.readParameterStatus();
71
72
  break;
72
73
  }
73
- case constants_1.ResponseTypes.ErrorResponse: {
74
- const message = reader.readErrorResponse();
74
+ case ResponseTypes.ErrorResponse: {
75
+ const error = reader.readErrorResponse();
75
76
  connector.destroy();
76
- reject(message);
77
+ reject(error);
77
78
  return;
78
79
  }
79
- case constants_1.ResponseTypes.BackendKeyData: {
80
+ case ResponseTypes.BackendKeyData: {
80
81
  reader.readBackendKeyData();
81
82
  }
82
- case constants_1.ResponseTypes.ReadyForQuery: {
83
+ case ResponseTypes.ReadyForQuery: {
83
84
  reader.readReadyForQuery();
84
85
  resolve(connector.unwrapSocket());
85
86
  return;
@@ -90,6 +91,9 @@ const createAuthorizedSocket = (writer, params) => {
90
91
  });
91
92
  connector.write(writer.writeStartup(params.user, params.database));
92
93
  writer.clear();
94
+ }), error => {
95
+ if (error instanceof PostgresError)
96
+ return error;
97
+ return new PostgresError(error.message);
93
98
  });
94
99
  };
95
- exports.createAuthorizedSocket = createAuthorizedSocket;
@@ -1,8 +1,5 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.SocketConnector = void 0;
4
- const connection_response_reader_1 = require("../protocol/connection-response-reader");
5
- class SocketConnector {
1
+ import { ConnectionResponseReader } from '../protocol/connection-response-reader';
2
+ export class SocketConnector {
6
3
  constructor(_socket, _onData, _onError) {
7
4
  this._socket = _socket;
8
5
  this._onData = _onData;
@@ -15,7 +12,7 @@ class SocketConnector {
15
12
  ? Buffer.concat([this.residualBuffer, buffer])
16
13
  : buffer;
17
14
  this.residualBuffer = null;
18
- const reader = connection_response_reader_1.ConnectionResponseReader.from(currentBuffer);
15
+ const reader = ConnectionResponseReader.from(currentBuffer);
19
16
  while (reader.hasMore()) {
20
17
  if (!reader.hasFullPacket()) {
21
18
  this.residualBuffer = reader.getResidualBuffer();
@@ -46,4 +43,3 @@ class SocketConnector {
46
43
  }
47
44
  get isDestroyed() { return this._isDestroyed; }
48
45
  }
49
- exports.SocketConnector = SocketConnector;
package/dist/query.js CHANGED
@@ -1,14 +1,11 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.Query = exports.QueryState = void 0;
4
- exports.QueryState = {
1
+ export const QueryState = {
5
2
  Parsing: 0,
6
3
  Describing: 1,
7
4
  Executing: 2,
8
5
  Completed: 3,
9
6
  Failed: 4
10
7
  };
11
- class Query {
8
+ export class Query {
12
9
  constructor(text, args, state, statementName, columns) {
13
10
  this.text = text;
14
11
  this.args = args;
@@ -25,4 +22,3 @@ class Query {
25
22
  this.state = state;
26
23
  }
27
24
  }
28
- exports.Query = Query;
package/dist/queue.js CHANGED
@@ -1,7 +1,4 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.Queue = void 0;
4
- class Queue {
1
+ export class Queue {
5
2
  constructor() {
6
3
  this._queue = new Array();
7
4
  this._pointer = 0;
@@ -36,4 +33,3 @@ class Queue {
36
33
  }
37
34
  get isFree() { return this._pointer >= this._queue.length; }
38
35
  }
39
- exports.Queue = Queue;
@@ -1,12 +1,8 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.encryptMd5 = void 0;
4
- const crypto_1 = require("crypto");
5
- const encryptMd5 = (password, user, salt) => {
6
- const stage1 = (0, crypto_1.createHash)('md5').update(password + user).digest('hex');
7
- const stage2 = (0, crypto_1.createHash)('md5')
1
+ import { createHash } from "crypto";
2
+ export const encryptMd5 = (password, user, salt) => {
3
+ const stage1 = createHash('md5').update(password + user).digest('hex');
4
+ const stage2 = createHash('md5')
8
5
  .update(Buffer.concat([Buffer.from(stage1), salt]))
9
6
  .digest('hex');
10
7
  return 'md5' + stage2;
11
8
  };
12
- exports.encryptMd5 = encryptMd5;
@@ -1,22 +1,18 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.generateNonce = generateNonce;
4
- exports.calculateScramAuth = calculateScramAuth;
5
- const crypto_1 = require("crypto");
6
- function generateNonce() {
7
- return (0, crypto_1.randomBytes)(18).toString('base64').replace(/[^a-zA-Z0-9]/g, '').substring(0, 24);
1
+ import { randomBytes, createHmac, pbkdf2Sync, createHash } from 'crypto';
2
+ export function generateNonce() {
3
+ return randomBytes(18).toString('base64').replace(/[^a-zA-Z0-9]/g, '').substring(0, 24);
8
4
  }
9
5
  function hmac(key, data) {
10
- return (0, crypto_1.createHmac)('sha256', key).update(data).digest();
6
+ return createHmac('sha256', key).update(data).digest();
11
7
  }
12
8
  function hi(password, salt, iterations) {
13
- return (0, crypto_1.pbkdf2Sync)(password, salt, iterations, 32, 'sha256');
9
+ return pbkdf2Sync(password, salt, iterations, 32, 'sha256');
14
10
  }
15
- function calculateScramAuth(password, saltBase64, iterations, authMessage) {
11
+ export function calculateScramAuth(password, saltBase64, iterations, authMessage) {
16
12
  const salt = Buffer.from(saltBase64, 'base64');
17
13
  const saltedPassword = hi(password, salt, iterations);
18
14
  const clientKey = hmac(saltedPassword, 'Client Key');
19
- const storedKey = (0, crypto_1.createHash)('sha256').update(clientKey).digest();
15
+ const storedKey = createHash('sha256').update(clientKey).digest();
20
16
  const clientSignature = hmac(storedKey, authMessage);
21
17
  const clientProofBuf = Buffer.alloc(32);
22
18
  for (let i = 0; i < 32; i++) {