@nestjs-kitchen/connextion-postgres 2.0.6 → 2.1.0
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 +41 -0
- package/dist/define-postgres.d.ts +2 -3
- package/dist/postgres.instance.d.ts +8 -6
- package/dist/postgres.instance.js +70 -40
- package/dist/transaction.js +1 -1
- package/dist/types.d.ts +14 -1
- package/dist/utils.d.ts +6 -1
- package/dist/utils.js +50 -6
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -9,6 +9,13 @@ A flexible module to provide [node-postgres](https://node-postgres.com/) interfa
|
|
|
9
9
|
|
|
10
10
|
---
|
|
11
11
|
|
|
12
|
+
## Feature
|
|
13
|
+
|
|
14
|
+
- ✅ Transaction support
|
|
15
|
+
- ✅ High availability (HA) support
|
|
16
|
+
- ✅ Type intelligent
|
|
17
|
+
|
|
18
|
+
|
|
12
19
|
## Install
|
|
13
20
|
|
|
14
21
|
```bash
|
|
@@ -174,6 +181,40 @@ class SampleService {
|
|
|
174
181
|
}
|
|
175
182
|
```
|
|
176
183
|
|
|
184
|
+
### High availability (HA)
|
|
185
|
+
|
|
186
|
+
Register postgres connection instance with multiple host.
|
|
187
|
+
|
|
188
|
+
When enabled, `instance1` will attempt to connect db with each hosts/ports in sequence until a connection is successfully established.
|
|
189
|
+
|
|
190
|
+
**Note: This is a temporary workaround and will change once `node-postgres` internally supports multiple hosts.**
|
|
191
|
+
|
|
192
|
+
```typescript
|
|
193
|
+
@Module({
|
|
194
|
+
imports: [
|
|
195
|
+
PostgresModule.register({
|
|
196
|
+
connections: [
|
|
197
|
+
{
|
|
198
|
+
name: 'instance1',
|
|
199
|
+
hosts: [
|
|
200
|
+
{
|
|
201
|
+
host: 'instance_1_host_1',
|
|
202
|
+
port: 1
|
|
203
|
+
},
|
|
204
|
+
{
|
|
205
|
+
host: 'instance_1_host_2',
|
|
206
|
+
port: 2
|
|
207
|
+
}
|
|
208
|
+
]
|
|
209
|
+
}
|
|
210
|
+
]
|
|
211
|
+
})
|
|
212
|
+
],
|
|
213
|
+
providers: [SampleService]
|
|
214
|
+
})
|
|
215
|
+
export class SampleModule {}
|
|
216
|
+
```
|
|
217
|
+
|
|
177
218
|
## License
|
|
178
219
|
|
|
179
220
|
MIT License
|
|
@@ -2,7 +2,6 @@ import { type AsyncModuleOptions, type ConnectionOptionName, type ConnextionInst
|
|
|
2
2
|
import type { DynamicModule, Type } from '@nestjs/common';
|
|
3
3
|
import { DEFAULT_INSTANCE_NAME } from './constants';
|
|
4
4
|
import { PostgresInstance } from './postgres.instance';
|
|
5
|
-
import type { PostgresInstanceOptions } from './types';
|
|
6
5
|
/**
|
|
7
6
|
* Creates a set of Postgres services, modules, and their associated Transaction decorator.
|
|
8
7
|
*/
|
|
@@ -22,8 +21,8 @@ export declare const definePostgres: <T extends string = typeof DEFAULT_INSTANCE
|
|
|
22
21
|
*/
|
|
23
22
|
PostgresModule: {
|
|
24
23
|
new (): {};
|
|
25
|
-
register(options: ModuleOptions<T,
|
|
26
|
-
registerAsync(options: AsyncModuleOptions<T,
|
|
24
|
+
register(options: ModuleOptions<T, import("./types").Options>): DynamicModule;
|
|
25
|
+
registerAsync(options: AsyncModuleOptions<T, import("./types").Options>): DynamicModule;
|
|
27
26
|
};
|
|
28
27
|
/**
|
|
29
28
|
* A decorator that automatically enables transactions for the specific Postgres
|
|
@@ -1,19 +1,21 @@
|
|
|
1
1
|
import { AsyncLocalStorage } from 'node:async_hooks';
|
|
2
2
|
import { ConnextionInstance } from '@nestjs-kitchen/connextion';
|
|
3
|
-
import { type PoolClient, type QueryArrayConfig, type QueryArrayResult, type QueryConfig, type QueryConfigValues, type QueryResult, type QueryResultRow, type Submittable } from 'pg';
|
|
3
|
+
import { Pool, type PoolClient, type QueryArrayConfig, type QueryArrayResult, type QueryConfig, type QueryConfigValues, type QueryResult, type QueryResultRow, type Submittable } from 'pg';
|
|
4
4
|
import { ALS, GET_CLIENT } from './constants';
|
|
5
|
-
import type { ALSType, PostgresInstanceOptions } from './types';
|
|
5
|
+
import type { ALSType, Options, PostgresInstanceOptions } from './types';
|
|
6
6
|
export declare class PostgresInstance extends ConnextionInstance<PostgresInstanceOptions> {
|
|
7
|
-
private
|
|
7
|
+
private pools;
|
|
8
8
|
private logger;
|
|
9
|
-
private
|
|
9
|
+
private optionsArray;
|
|
10
10
|
[ALS]: AsyncLocalStorage<ALSType>;
|
|
11
11
|
private listener1;
|
|
12
12
|
private listener2;
|
|
13
13
|
constructor(name: string, options?: PostgresInstanceOptions);
|
|
14
14
|
private end;
|
|
15
|
-
dispose(): Promise<void
|
|
16
|
-
|
|
15
|
+
dispose(): Promise<void>;
|
|
16
|
+
createPool(options: Options): Pool | undefined;
|
|
17
|
+
create(options: PostgresInstanceOptions): Promise<void>;
|
|
18
|
+
private getAndTestClient;
|
|
17
19
|
[GET_CLIENT](): Promise<PoolClient>;
|
|
18
20
|
query<T extends Submittable>(queryStream: T): Promise<T>;
|
|
19
21
|
query<R extends any[] = any[], I = any[]>(queryConfig: QueryArrayConfig<I>, values?: QueryConfigValues<I>): Promise<QueryArrayResult<R>>;
|
|
@@ -13,7 +13,8 @@ const utils_1 = require("./utils");
|
|
|
13
13
|
class PostgresInstance extends connextion_1.ConnextionInstance {
|
|
14
14
|
constructor(name, options) {
|
|
15
15
|
super(name, options);
|
|
16
|
-
this.
|
|
16
|
+
this.pools = [];
|
|
17
|
+
this.optionsArray = [];
|
|
17
18
|
// Every instance should have its own als to avoid accessing wrong context.
|
|
18
19
|
this[_a] = new node_async_hooks_1.AsyncLocalStorage();
|
|
19
20
|
this.listener1 = (_cli) => {
|
|
@@ -23,10 +24,9 @@ class PostgresInstance extends connextion_1.ConnextionInstance {
|
|
|
23
24
|
this.logger.error(err);
|
|
24
25
|
};
|
|
25
26
|
this.logger = new common_1.Logger(`Postgres][${name}`);
|
|
26
|
-
this.debug = Boolean(process.env[constants_1.CONNEXTION_POSTGRES_DEBUG]) || options?.debug;
|
|
27
27
|
}
|
|
28
28
|
async end(pool) {
|
|
29
|
-
if (!pool) {
|
|
29
|
+
if (!pool || pool.ending) {
|
|
30
30
|
return;
|
|
31
31
|
}
|
|
32
32
|
try {
|
|
@@ -38,60 +38,90 @@ class PostgresInstance extends connextion_1.ConnextionInstance {
|
|
|
38
38
|
this.logger.error(error);
|
|
39
39
|
}
|
|
40
40
|
}
|
|
41
|
-
dispose() {
|
|
42
|
-
if (!this.
|
|
41
|
+
async dispose() {
|
|
42
|
+
if (!this.pools) {
|
|
43
43
|
return;
|
|
44
44
|
}
|
|
45
|
-
const
|
|
46
|
-
this.
|
|
47
|
-
|
|
45
|
+
const pools = this.pools;
|
|
46
|
+
this.pools = [];
|
|
47
|
+
for (const pool of pools) {
|
|
48
|
+
await this.end(pool);
|
|
49
|
+
}
|
|
50
|
+
return;
|
|
48
51
|
}
|
|
49
|
-
|
|
50
|
-
this.dispose();
|
|
52
|
+
createPool(options) {
|
|
51
53
|
try {
|
|
52
54
|
const pool = new pg_1.Pool(options);
|
|
53
55
|
//https://github.com/brianc/node-postgres/issues/2439#issuecomment-757691278
|
|
54
56
|
pool.on('connect', this.listener1);
|
|
55
57
|
pool.on('error', this.listener2);
|
|
56
|
-
|
|
58
|
+
return pool;
|
|
57
59
|
}
|
|
58
60
|
catch (error) {
|
|
59
61
|
this.logger.error(error.message);
|
|
60
62
|
}
|
|
61
63
|
}
|
|
62
|
-
async
|
|
63
|
-
|
|
64
|
-
|
|
64
|
+
async create(options) {
|
|
65
|
+
await this.dispose();
|
|
66
|
+
this.optionsArray = (0, utils_1.normalizeOptions)(options);
|
|
67
|
+
if (!this.optionsArray.length) {
|
|
68
|
+
throw new Error('cannot find available options');
|
|
65
69
|
}
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
if (!client) {
|
|
72
|
-
throw new errors_1.PostgresError('client not found');
|
|
73
|
-
}
|
|
70
|
+
this.pools = this.optionsArray.map((options) => this.createPool(options)).filter(Boolean);
|
|
71
|
+
}
|
|
72
|
+
async getAndTestClient(promise) {
|
|
73
|
+
const client = await promise;
|
|
74
|
+
if (!client) {
|
|
74
75
|
return client;
|
|
75
76
|
}
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
if (err) {
|
|
81
|
-
throw new errors_1.PostgresError(err, err);
|
|
77
|
+
try {
|
|
78
|
+
// test if current client is still alive.
|
|
79
|
+
await client.query('SELECT 1;');
|
|
80
|
+
return client;
|
|
82
81
|
}
|
|
83
|
-
|
|
84
|
-
|
|
82
|
+
catch (error) {
|
|
83
|
+
client.release(error);
|
|
84
|
+
throw error;
|
|
85
85
|
}
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
86
|
+
}
|
|
87
|
+
async [(_a = constants_1.ALS, constants_1.GET_CLIENT)]() {
|
|
88
|
+
let error = 'failed to get client';
|
|
89
|
+
for (let i = 0; i < this.optionsArray.length; i++) {
|
|
90
|
+
const pool = this.pools[i];
|
|
91
|
+
const debugMode = this.optionsArray[i].debug || !!process.env[constants_1.CONNEXTION_POSTGRES_DEBUG];
|
|
92
|
+
if (!debugMode) {
|
|
93
|
+
const [client, err] = await (0, utils_1.plainPromise)(this.getAndTestClient(pool.connect()));
|
|
94
|
+
if (client) {
|
|
95
|
+
return client;
|
|
96
|
+
}
|
|
97
|
+
error = err || 'client not found';
|
|
98
|
+
if (!(0, utils_1.isFailoverRequired)(error)) {
|
|
99
|
+
break;
|
|
91
100
|
}
|
|
92
|
-
return value;
|
|
93
101
|
}
|
|
94
|
-
|
|
102
|
+
else {
|
|
103
|
+
// Debug mode
|
|
104
|
+
const logger = (0, utils_1.createDebugLogger)(this.logger.debug.bind(this.logger), debugMode);
|
|
105
|
+
const debug = (0, utils_1.debugFactroy)(this.name, (0, uid_1.uid)(21), `${this.optionsArray[i].host}:${this.optionsArray[i].port}`, logger);
|
|
106
|
+
const [client, err] = await (0, utils_1.plainPromise)(this.getAndTestClient(debug.pool.connect(pool.connect.bind(pool))()));
|
|
107
|
+
if (client) {
|
|
108
|
+
return new Proxy(client, {
|
|
109
|
+
get(target, prop, receiver) {
|
|
110
|
+
const value = Reflect.get(target, prop, receiver);
|
|
111
|
+
if (debug.client[prop]) {
|
|
112
|
+
return debug.client[prop](value.bind(target));
|
|
113
|
+
}
|
|
114
|
+
return value;
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
error = err || 'client not found';
|
|
119
|
+
if (!(0, utils_1.isFailoverRequired)(error)) {
|
|
120
|
+
break;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
throw new errors_1.PostgresError(error, typeof error === 'string' ? undefined : error);
|
|
95
125
|
}
|
|
96
126
|
async query(...rest) {
|
|
97
127
|
if (!rest.length) {
|
|
@@ -116,7 +146,7 @@ class PostgresInstance extends connextion_1.ConnextionInstance {
|
|
|
116
146
|
throw err;
|
|
117
147
|
}
|
|
118
148
|
finally {
|
|
119
|
-
client.release(err
|
|
149
|
+
client.release(err);
|
|
120
150
|
}
|
|
121
151
|
}
|
|
122
152
|
async transactionQueryWithConfig(...rest) {
|
|
@@ -156,13 +186,13 @@ class PostgresInstance extends connextion_1.ConnextionInstance {
|
|
|
156
186
|
};
|
|
157
187
|
const onEnd = () => {
|
|
158
188
|
res.off('error', onError);
|
|
159
|
-
client.release(
|
|
189
|
+
client.release();
|
|
160
190
|
};
|
|
161
191
|
res.once('end', onEnd);
|
|
162
192
|
res.once('error', onError);
|
|
163
193
|
}
|
|
164
194
|
else {
|
|
165
|
-
client.release(err
|
|
195
|
+
client.release(err);
|
|
166
196
|
}
|
|
167
197
|
}
|
|
168
198
|
}
|
package/dist/transaction.js
CHANGED
|
@@ -62,7 +62,7 @@ const createTransaction = (Postgres) => {
|
|
|
62
62
|
}
|
|
63
63
|
}
|
|
64
64
|
};
|
|
65
|
-
const releaseClients = async (err) => runWithClients((client) => client.release(err
|
|
65
|
+
const releaseClients = async (err) => runWithClients((client) => client.release(err));
|
|
66
66
|
// Ensure all clients are available.
|
|
67
67
|
const [_, initErr] = await (0, utils_1.plainPromise)(initClients());
|
|
68
68
|
if (initErr) {
|
package/dist/types.d.ts
CHANGED
|
@@ -4,6 +4,19 @@ export interface ALSType {
|
|
|
4
4
|
client: Promise<PoolClient>;
|
|
5
5
|
queries: Promise<ALSQueryType>[];
|
|
6
6
|
}
|
|
7
|
-
export type
|
|
7
|
+
export type Options = PoolConfig & {
|
|
8
8
|
debug?: boolean | ((data: Record<any, any>) => void);
|
|
9
|
+
} & {
|
|
10
|
+
/**
|
|
11
|
+
* Enable multi host connections for `High Availability` (HA).
|
|
12
|
+
*
|
|
13
|
+
* This will find and switch to connect the availabe host.
|
|
14
|
+
*
|
|
15
|
+
* If provided, will ignore `Options.host` and `Options.port`
|
|
16
|
+
*/
|
|
17
|
+
hosts?: {
|
|
18
|
+
host: PoolConfig['host'];
|
|
19
|
+
port: PoolConfig['port'];
|
|
20
|
+
}[];
|
|
9
21
|
};
|
|
22
|
+
export type PostgresInstanceOptions = Options;
|
package/dist/utils.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { type PoolClient, type Submittable } from 'pg';
|
|
2
|
+
import type { Options } from './types';
|
|
2
3
|
export declare const isSubmittable: (val: any) => val is Submittable;
|
|
3
4
|
export declare const isObject: (val: any) => val is object;
|
|
4
5
|
export declare const normalizeStrings: (strs?: string[]) => string[];
|
|
@@ -9,7 +10,7 @@ export declare const getCurrentDateStr: () => string;
|
|
|
9
10
|
export declare const formatArray: (arr?: any) => string;
|
|
10
11
|
export declare const extraceQueryTextAndValues: (...rest: any[]) => [text: string, values: any[]];
|
|
11
12
|
export declare const createDebugLogger: (defaultLogger: (...rest: any) => void, customFormater?: Boolean | ((data: Record<any, any>) => void)) => (data: Record<any, any>) => void;
|
|
12
|
-
export declare const debugFactroy: (name: string, queryId: string, logger: (data: Record<any, any>) => void) => {
|
|
13
|
+
export declare const debugFactroy: (name: string, queryId: string, host: string, logger: (data: Record<any, any>) => void) => {
|
|
13
14
|
pool: {
|
|
14
15
|
connect: <T extends () => Promise<PoolClient>>(callback: T) => () => Promise<PoolClient>;
|
|
15
16
|
};
|
|
@@ -26,3 +27,7 @@ export declare const withResolvers: <T>() => {
|
|
|
26
27
|
resolve: (value: T | PromiseLike<T>) => void;
|
|
27
28
|
reject: (reason?: any) => void;
|
|
28
29
|
};
|
|
30
|
+
export declare const normalizeOptions: (options: Options) => Omit<Options, "hosts">[];
|
|
31
|
+
export declare const isFailoverRequired: (err?: {
|
|
32
|
+
code?: string;
|
|
33
|
+
}) => boolean;
|
package/dist/utils.js
CHANGED
|
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.withResolvers = exports.setTransactionMetdata = exports.getTransactionMetdata = exports.copyMethodMetadata = exports.debugFactroy = exports.createDebugLogger = exports.extraceQueryTextAndValues = exports.formatArray = exports.getCurrentDateStr = exports.printTable = exports.truncateString = exports.plainPromise = exports.normalizeStrings = exports.isObject = exports.isSubmittable = void 0;
|
|
6
|
+
exports.isFailoverRequired = exports.normalizeOptions = exports.withResolvers = exports.setTransactionMetdata = exports.getTransactionMetdata = exports.copyMethodMetadata = exports.debugFactroy = exports.createDebugLogger = exports.extraceQueryTextAndValues = exports.formatArray = exports.getCurrentDateStr = exports.printTable = exports.truncateString = exports.plainPromise = exports.normalizeStrings = exports.isObject = exports.isSubmittable = void 0;
|
|
7
7
|
const dayjs_1 = __importDefault(require("dayjs"));
|
|
8
8
|
const constants_1 = require("./constants");
|
|
9
9
|
const isSubmittable = (val) => {
|
|
@@ -87,7 +87,7 @@ const createDebugLogger = (defaultLogger, customFormater) => {
|
|
|
87
87
|
};
|
|
88
88
|
};
|
|
89
89
|
exports.createDebugLogger = createDebugLogger;
|
|
90
|
-
const debugFactroy = (name, queryId, logger) => {
|
|
90
|
+
const debugFactroy = (name, queryId, host, logger) => {
|
|
91
91
|
return {
|
|
92
92
|
pool: {
|
|
93
93
|
connect: (callback) => {
|
|
@@ -104,12 +104,13 @@ const debugFactroy = (name, queryId, logger) => {
|
|
|
104
104
|
finally {
|
|
105
105
|
logger({
|
|
106
106
|
Instance: name,
|
|
107
|
+
Host: host,
|
|
107
108
|
Client: queryId,
|
|
108
109
|
Type: 'Request new client',
|
|
109
110
|
'Started On': startOn,
|
|
110
111
|
'Ended On': (0, exports.getCurrentDateStr)(),
|
|
111
112
|
Status: err ? 'Failed' : 'Successful',
|
|
112
|
-
Error: err
|
|
113
|
+
Error: err?.code ? `[${err.code}]${err}` : err
|
|
113
114
|
});
|
|
114
115
|
}
|
|
115
116
|
};
|
|
@@ -126,6 +127,7 @@ const debugFactroy = (name, queryId, logger) => {
|
|
|
126
127
|
rest[0].on('end', () => {
|
|
127
128
|
logger({
|
|
128
129
|
Instance: name,
|
|
130
|
+
Host: host,
|
|
129
131
|
Client: queryId,
|
|
130
132
|
Type: 'Submittable',
|
|
131
133
|
Text: text,
|
|
@@ -138,6 +140,7 @@ const debugFactroy = (name, queryId, logger) => {
|
|
|
138
140
|
rest[0].on('error', (err) => {
|
|
139
141
|
logger({
|
|
140
142
|
Instance: name,
|
|
143
|
+
Host: host,
|
|
141
144
|
Client: queryId,
|
|
142
145
|
Type: 'Submittable',
|
|
143
146
|
Text: text,
|
|
@@ -145,7 +148,7 @@ const debugFactroy = (name, queryId, logger) => {
|
|
|
145
148
|
'Started On': startOn,
|
|
146
149
|
'Ended On': (0, exports.getCurrentDateStr)(),
|
|
147
150
|
Status: 'Failed',
|
|
148
|
-
Error: err
|
|
151
|
+
Error: err?.code ? `[${err.code}]${err}` : err
|
|
149
152
|
});
|
|
150
153
|
});
|
|
151
154
|
}
|
|
@@ -160,6 +163,7 @@ const debugFactroy = (name, queryId, logger) => {
|
|
|
160
163
|
if (!submittable) {
|
|
161
164
|
logger({
|
|
162
165
|
Instance: name,
|
|
166
|
+
Host: host,
|
|
163
167
|
Client: queryId,
|
|
164
168
|
Type: 'Query',
|
|
165
169
|
Text: text,
|
|
@@ -167,7 +171,7 @@ const debugFactroy = (name, queryId, logger) => {
|
|
|
167
171
|
'Started On': startOn,
|
|
168
172
|
'Ended On': (0, exports.getCurrentDateStr)(),
|
|
169
173
|
Status: err ? 'Failed' : 'Successful',
|
|
170
|
-
Error: err
|
|
174
|
+
Error: err?.code ? `[${err.code}]${err}` : err
|
|
171
175
|
});
|
|
172
176
|
}
|
|
173
177
|
}
|
|
@@ -187,12 +191,13 @@ const debugFactroy = (name, queryId, logger) => {
|
|
|
187
191
|
finally {
|
|
188
192
|
logger({
|
|
189
193
|
Instance: name,
|
|
194
|
+
Host: host,
|
|
190
195
|
Client: queryId,
|
|
191
196
|
Type: 'Release client',
|
|
192
197
|
'Started On': startOn,
|
|
193
198
|
'Ended On': (0, exports.getCurrentDateStr)(),
|
|
194
199
|
Status: err ? 'Failed' : 'Successful',
|
|
195
|
-
Error: err
|
|
200
|
+
Error: err?.code ? `[${err.code}]${err}` : err
|
|
196
201
|
});
|
|
197
202
|
}
|
|
198
203
|
};
|
|
@@ -228,3 +233,42 @@ const withResolvers = () => {
|
|
|
228
233
|
return { promise, resolve: resolve, reject: reject };
|
|
229
234
|
};
|
|
230
235
|
exports.withResolvers = withResolvers;
|
|
236
|
+
const normalizeOptions = (options) => {
|
|
237
|
+
const { host, hosts, port, ...rest } = options;
|
|
238
|
+
if (hosts) {
|
|
239
|
+
return hosts.map((ele) => ({
|
|
240
|
+
...rest,
|
|
241
|
+
...ele
|
|
242
|
+
}));
|
|
243
|
+
}
|
|
244
|
+
return [
|
|
245
|
+
{
|
|
246
|
+
...rest,
|
|
247
|
+
host,
|
|
248
|
+
port
|
|
249
|
+
}
|
|
250
|
+
];
|
|
251
|
+
};
|
|
252
|
+
exports.normalizeOptions = normalizeOptions;
|
|
253
|
+
const failoverErrorCodes = new Set([
|
|
254
|
+
'ECONNREFUSED',
|
|
255
|
+
'ETIMEDOUT',
|
|
256
|
+
'EHOSTUNREACH',
|
|
257
|
+
'ENOTFOUND',
|
|
258
|
+
'EAI_AGAIN',
|
|
259
|
+
'ECONNRESET',
|
|
260
|
+
'EPIPE',
|
|
261
|
+
'57P01',
|
|
262
|
+
'57P02',
|
|
263
|
+
'57P03',
|
|
264
|
+
'55P03',
|
|
265
|
+
'55000',
|
|
266
|
+
'54000',
|
|
267
|
+
'53300',
|
|
268
|
+
'08006',
|
|
269
|
+
'XX000'
|
|
270
|
+
]);
|
|
271
|
+
const isFailoverRequired = (err) => {
|
|
272
|
+
return !!(err?.code && failoverErrorCodes.has(`${err.code}`));
|
|
273
|
+
};
|
|
274
|
+
exports.isFailoverRequired = isFailoverRequired;
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@nestjs-kitchen/connextion-postgres",
|
|
3
3
|
"private": false,
|
|
4
4
|
"description": "A flexible module to provide node-postgres interface in NextJS.",
|
|
5
|
-
"version": "2.0
|
|
5
|
+
"version": "2.1.0",
|
|
6
6
|
"homepage": "https://github.com/yikenman/nestjs-kitchen",
|
|
7
7
|
"repository": "https://github.com/yikenman/nestjs-kitchen",
|
|
8
8
|
"author": "yikenman",
|