@sqb/nestjs 4.21.1 → 4.22.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/get-sqb-config.d.ts +1 -1
- package/index.d.ts +0 -2
- package/index.js +0 -2
- package/package.json +6 -5
- package/sqb-core.module.d.ts +11 -13
- package/sqb-core.module.js +77 -118
- package/sqb.interface.d.ts +11 -39
- package/sqb.decorators.d.ts +0 -1
- package/sqb.decorators.js +0 -3
- package/sqb.utils.d.ts +0 -11
- package/sqb.utils.js +0 -35
package/get-sqb-config.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { SqbClientConnectionOptions } from './sqb.interface.js';
|
|
1
|
+
import type { SqbClientConnectionOptions } from './sqb.interface.js';
|
|
2
2
|
export declare function getSqbConfig(moduleOptions: SqbClientConnectionOptions, prefix?: string): SqbClientConnectionOptions;
|
package/index.d.ts
CHANGED
package/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,19 +1,20 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sqb/nestjs",
|
|
3
3
|
"description": "Nestjs module for data connection using SQB",
|
|
4
|
-
"version": "4.
|
|
4
|
+
"version": "4.22.0",
|
|
5
5
|
"author": "Panates",
|
|
6
6
|
"license": "Apache-2.0",
|
|
7
7
|
"dependencies": {
|
|
8
|
-
"@jsopen/objects": "^2.
|
|
9
|
-
"
|
|
8
|
+
"@jsopen/objects": "^2.1.1",
|
|
9
|
+
"ansi-colors": "^4.1.3",
|
|
10
|
+
"putil-varhelpers": "^1.7.0",
|
|
10
11
|
"tslib": "^2.8.1"
|
|
11
12
|
},
|
|
12
13
|
"peerDependencies": {
|
|
13
14
|
"@nestjs/common": ">=7.4.0",
|
|
14
15
|
"@nestjs/core": ">=7.4.0",
|
|
15
|
-
"@sqb/builder": "^4.
|
|
16
|
-
"@sqb/connect": "^4.
|
|
16
|
+
"@sqb/builder": "^4.22.0",
|
|
17
|
+
"@sqb/connect": "^4.22.0",
|
|
17
18
|
"reflect-metadata": "^0.2.2",
|
|
18
19
|
"rxjs": ">=6.6.0"
|
|
19
20
|
},
|
package/sqb-core.module.d.ts
CHANGED
|
@@ -1,16 +1,14 @@
|
|
|
1
|
-
import { DynamicModule, Logger, OnApplicationShutdown } from '@nestjs/common';
|
|
2
|
-
import {
|
|
3
|
-
import type { SqbModuleAsyncOptions, SqbModuleOptions } from './sqb.interface.js';
|
|
4
|
-
export declare class SqbCoreModule implements OnApplicationShutdown {
|
|
5
|
-
|
|
6
|
-
private readonly
|
|
7
|
-
private logger
|
|
8
|
-
|
|
9
|
-
static
|
|
10
|
-
static
|
|
1
|
+
import { DynamicModule, Logger, OnApplicationBootstrap, OnApplicationShutdown } from '@nestjs/common';
|
|
2
|
+
import { SqbClient } from '@sqb/connect';
|
|
3
|
+
import type { SqbClientConnectionOptions, SqbModuleAsyncOptions, SqbModuleOptions } from './sqb.interface.js';
|
|
4
|
+
export declare class SqbCoreModule implements OnApplicationBootstrap, OnApplicationShutdown {
|
|
5
|
+
protected readonly client: SqbClient;
|
|
6
|
+
private readonly connectionOptions;
|
|
7
|
+
private logger;
|
|
8
|
+
static forRoot(moduleOptions?: SqbModuleOptions): DynamicModule;
|
|
9
|
+
static forRootAsync(asyncOptions: SqbModuleAsyncOptions): DynamicModule;
|
|
10
|
+
private static _createDynamicModule;
|
|
11
|
+
constructor(client: SqbClient, connectionOptions: SqbClientConnectionOptions, logger: Logger);
|
|
11
12
|
onApplicationBootstrap(): Promise<void> | undefined;
|
|
12
13
|
onApplicationShutdown(): Promise<void>;
|
|
13
|
-
private static createAsyncProviders;
|
|
14
|
-
private static createAsyncOptionsProvider;
|
|
15
|
-
private static createConnection;
|
|
16
14
|
}
|
package/sqb-core.module.js
CHANGED
|
@@ -1,153 +1,112 @@
|
|
|
1
1
|
var SqbCoreModule_1;
|
|
2
2
|
import { __decorate, __metadata, __param } from "tslib";
|
|
3
|
+
import assert from 'node:assert';
|
|
3
4
|
import { Global, Inject, Logger, Module, } from '@nestjs/common';
|
|
4
|
-
import { ModuleRef } from '@nestjs/core';
|
|
5
5
|
import { SqbClient } from '@sqb/connect';
|
|
6
|
+
import colors from 'ansi-colors';
|
|
6
7
|
import * as crypto from 'crypto';
|
|
7
|
-
import { defer } from 'rxjs';
|
|
8
|
-
import * as rxjs from 'rxjs';
|
|
9
8
|
import { getSqbConfig } from './get-sqb-config.js';
|
|
10
9
|
import { SQB_CONNECTION_OPTIONS, SQB_MODULE_ID, SQB_MODULE_OPTIONS, } from './sqb.constants.js';
|
|
11
|
-
|
|
10
|
+
const CLIENT_TOKEN = Symbol('CLIENT_TOKEN');
|
|
12
11
|
let SqbCoreModule = SqbCoreModule_1 = class SqbCoreModule {
|
|
13
|
-
|
|
14
|
-
|
|
12
|
+
client;
|
|
13
|
+
connectionOptions;
|
|
15
14
|
logger;
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
this.
|
|
19
|
-
|
|
20
|
-
}
|
|
21
|
-
static forRoot(options = {}) {
|
|
22
|
-
const optionsProvider = {
|
|
23
|
-
provide: SQB_MODULE_OPTIONS,
|
|
24
|
-
useValue: options,
|
|
25
|
-
};
|
|
26
|
-
const connectionProvider = {
|
|
27
|
-
provide: getSQBToken(options.name),
|
|
28
|
-
inject: [SQB_CONNECTION_OPTIONS],
|
|
29
|
-
useFactory: (sqbConnectionOptions) => this.createConnection(options, sqbConnectionOptions),
|
|
30
|
-
};
|
|
31
|
-
return {
|
|
32
|
-
module: SqbCoreModule_1,
|
|
15
|
+
static forRoot(moduleOptions = {}) {
|
|
16
|
+
const connectionOptions = getSqbConfig(moduleOptions.useValue || {}, moduleOptions.envPrefix);
|
|
17
|
+
return this._createDynamicModule(moduleOptions, {
|
|
18
|
+
global: moduleOptions.global,
|
|
33
19
|
providers: [
|
|
34
|
-
connectionProvider,
|
|
35
|
-
optionsProvider,
|
|
36
20
|
{
|
|
37
21
|
provide: SQB_CONNECTION_OPTIONS,
|
|
38
|
-
useValue:
|
|
39
|
-
},
|
|
40
|
-
{
|
|
41
|
-
provide: Logger,
|
|
42
|
-
useValue: typeof options.logger === 'string'
|
|
43
|
-
? new Logger(options.logger)
|
|
44
|
-
: options.logger,
|
|
22
|
+
useValue: connectionOptions,
|
|
45
23
|
},
|
|
46
24
|
],
|
|
47
|
-
|
|
48
|
-
};
|
|
25
|
+
});
|
|
49
26
|
}
|
|
50
|
-
static forRootAsync(
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
useFactory: async (sqbOptions, sqbConnectionOptions) => this.createConnection(sqbOptions, sqbConnectionOptions),
|
|
55
|
-
};
|
|
56
|
-
const asyncProviders = this.createAsyncProviders(options);
|
|
57
|
-
return {
|
|
58
|
-
module: SqbCoreModule_1,
|
|
59
|
-
imports: options.imports,
|
|
27
|
+
static forRootAsync(asyncOptions) {
|
|
28
|
+
assert.ok(asyncOptions.useFactory, 'useFactory is required');
|
|
29
|
+
return this._createDynamicModule(asyncOptions, {
|
|
30
|
+
global: asyncOptions.global,
|
|
60
31
|
providers: [
|
|
61
|
-
...asyncProviders,
|
|
62
|
-
connectionProvider,
|
|
63
|
-
{
|
|
64
|
-
provide: SQB_MODULE_OPTIONS,
|
|
65
|
-
useValue: options,
|
|
66
|
-
},
|
|
67
32
|
{
|
|
68
|
-
provide:
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
? new Logger(options.logger)
|
|
75
|
-
: options.logger,
|
|
33
|
+
provide: SQB_CONNECTION_OPTIONS,
|
|
34
|
+
inject: asyncOptions.inject,
|
|
35
|
+
useFactory: async (...args) => {
|
|
36
|
+
const opts = await asyncOptions.useFactory(...args);
|
|
37
|
+
return getSqbConfig(opts, asyncOptions.envPrefix);
|
|
38
|
+
},
|
|
76
39
|
},
|
|
77
40
|
],
|
|
78
|
-
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
static _createDynamicModule(opts, metadata) {
|
|
44
|
+
const token = opts.token || SqbClient;
|
|
45
|
+
const providers = [
|
|
46
|
+
...(metadata.providers ?? []),
|
|
47
|
+
{
|
|
48
|
+
provide: SQB_MODULE_OPTIONS,
|
|
49
|
+
useValue: opts,
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
provide: token,
|
|
53
|
+
inject: [SQB_CONNECTION_OPTIONS],
|
|
54
|
+
useFactory: (sqbConnectionOptions) => new SqbClient(sqbConnectionOptions),
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
provide: CLIENT_TOKEN,
|
|
58
|
+
useExisting: token,
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
provide: SQB_MODULE_ID,
|
|
62
|
+
useValue: crypto.randomUUID(),
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
provide: Logger,
|
|
66
|
+
useValue: opts.logger || new Logger('SQB'),
|
|
67
|
+
},
|
|
68
|
+
];
|
|
69
|
+
return {
|
|
70
|
+
module: SqbCoreModule_1,
|
|
71
|
+
...metadata,
|
|
72
|
+
providers,
|
|
73
|
+
exports: [...(metadata.exports ?? []), SQB_CONNECTION_OPTIONS, token],
|
|
79
74
|
};
|
|
80
75
|
}
|
|
76
|
+
constructor(client, connectionOptions, logger) {
|
|
77
|
+
this.client = client;
|
|
78
|
+
this.connectionOptions = connectionOptions;
|
|
79
|
+
this.logger = logger;
|
|
80
|
+
}
|
|
81
81
|
onApplicationBootstrap() {
|
|
82
|
-
|
|
83
|
-
const op = this.moduleRef.get(SQB_CONNECTION_OPTIONS);
|
|
84
|
-
if (this.options.lazyConnect)
|
|
82
|
+
if (this.connectionOptions.lazyConnect)
|
|
85
83
|
return;
|
|
86
|
-
this.logger?.log(`Connecting to database [${op.database}] at ${op.host}:${op.port} using ${op.dialect} dialect`);
|
|
87
84
|
Logger.flush();
|
|
88
|
-
|
|
89
|
-
this.logger?.
|
|
85
|
+
const logTimer = setTimeout(() => {
|
|
86
|
+
this.logger?.verbose(`Waiting to connect to Database [${colors.blue(this.connectionOptions.dialect || '')}]`);
|
|
87
|
+
}, 1000);
|
|
88
|
+
return this.client
|
|
89
|
+
.test()
|
|
90
|
+
.catch(e => {
|
|
91
|
+
clearTimeout(logTimer);
|
|
92
|
+
this.logger?.error('Database connection failed: ' + e.message);
|
|
90
93
|
throw e;
|
|
94
|
+
})
|
|
95
|
+
.then(() => {
|
|
96
|
+
clearTimeout(logTimer);
|
|
97
|
+
this.logger?.log(`Database connection established`);
|
|
91
98
|
});
|
|
92
99
|
}
|
|
93
100
|
async onApplicationShutdown() {
|
|
94
|
-
|
|
95
|
-
const op = this.moduleRef.get(SQB_CONNECTION_OPTIONS);
|
|
96
|
-
if (client)
|
|
97
|
-
await client.close(op.shutdownWaitMs);
|
|
98
|
-
}
|
|
99
|
-
static createAsyncProviders(options) {
|
|
100
|
-
if (options.useExisting || options.useFactory)
|
|
101
|
-
return [this.createAsyncOptionsProvider(options)];
|
|
102
|
-
if (options.useClass) {
|
|
103
|
-
return [
|
|
104
|
-
this.createAsyncOptionsProvider(options),
|
|
105
|
-
{
|
|
106
|
-
provide: options.useClass,
|
|
107
|
-
useClass: options.useClass,
|
|
108
|
-
},
|
|
109
|
-
];
|
|
110
|
-
}
|
|
111
|
-
throw new Error('Invalid configuration. Must provide useFactory, useClass or useExisting');
|
|
112
|
-
}
|
|
113
|
-
static createAsyncOptionsProvider(options) {
|
|
114
|
-
if (options.useFactory) {
|
|
115
|
-
return {
|
|
116
|
-
provide: SQB_CONNECTION_OPTIONS,
|
|
117
|
-
useFactory: options.useFactory,
|
|
118
|
-
inject: options.inject || [],
|
|
119
|
-
};
|
|
120
|
-
}
|
|
121
|
-
const useClass = options.useClass || options.useExisting;
|
|
122
|
-
if (useClass) {
|
|
123
|
-
return {
|
|
124
|
-
provide: SQB_CONNECTION_OPTIONS,
|
|
125
|
-
useFactory: (optionsFactory) => optionsFactory.createSqbOptions(options.name),
|
|
126
|
-
inject: [useClass],
|
|
127
|
-
};
|
|
128
|
-
}
|
|
129
|
-
throw new Error('Invalid configuration. Must provide useFactory, useClass or useExisting');
|
|
130
|
-
}
|
|
131
|
-
static async createConnection(moduleOptions, sqbConnectionOptions) {
|
|
132
|
-
const connectionToken = moduleOptions.name;
|
|
133
|
-
// NestJS 8
|
|
134
|
-
// @ts-ignore
|
|
135
|
-
if (rxjs.lastValueFrom) {
|
|
136
|
-
// @ts-ignore
|
|
137
|
-
return await rxjs.lastValueFrom(defer(async () => new SqbClient(sqbConnectionOptions)).pipe(handleRetry(connectionToken, sqbConnectionOptions.retryAttempts, sqbConnectionOptions.retryDelay, sqbConnectionOptions.verboseRetryLog, sqbConnectionOptions.toRetry)));
|
|
138
|
-
}
|
|
139
|
-
// NestJS 7
|
|
140
|
-
// @ts-ignore
|
|
141
|
-
return await defer(async () => new SqbClient(sqbConnectionOptions))
|
|
142
|
-
.pipe(handleRetry(connectionToken, sqbConnectionOptions.retryAttempts, sqbConnectionOptions.retryDelay, sqbConnectionOptions.verboseRetryLog, sqbConnectionOptions.toRetry))
|
|
143
|
-
.toPromise();
|
|
101
|
+
await this.client.close(this.connectionOptions.shutdownWaitMs);
|
|
144
102
|
}
|
|
145
103
|
};
|
|
146
104
|
SqbCoreModule = SqbCoreModule_1 = __decorate([
|
|
147
105
|
Global(),
|
|
148
106
|
Module({}),
|
|
149
|
-
__param(0, Inject(
|
|
150
|
-
|
|
151
|
-
|
|
107
|
+
__param(0, Inject(CLIENT_TOKEN)),
|
|
108
|
+
__param(1, Inject(SQB_CONNECTION_OPTIONS)),
|
|
109
|
+
__param(2, Inject(Logger)),
|
|
110
|
+
__metadata("design:paramtypes", [SqbClient, Object, Logger])
|
|
152
111
|
], SqbCoreModule);
|
|
153
112
|
export { SqbCoreModule };
|
package/sqb.interface.d.ts
CHANGED
|
@@ -1,57 +1,29 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { ModuleMetadata } from '@nestjs/common/interfaces';
|
|
3
|
-
import { ClientConfiguration } from '@sqb/connect';
|
|
1
|
+
import type { InjectionToken, LoggerService } from '@nestjs/common';
|
|
2
|
+
import type { ModuleMetadata } from '@nestjs/common/interfaces';
|
|
3
|
+
import type { ClientConfiguration } from '@sqb/connect';
|
|
4
4
|
export interface SqbClientConnectionOptions extends ClientConfiguration {
|
|
5
|
-
/**
|
|
6
|
-
* Number of times to retry connecting
|
|
7
|
-
* Default: 10
|
|
8
|
-
*/
|
|
9
|
-
retryAttempts?: number;
|
|
10
|
-
/**
|
|
11
|
-
* Delay between connection retry attempts (ms)
|
|
12
|
-
* Default: 3000
|
|
13
|
-
*/
|
|
14
|
-
retryDelay?: number;
|
|
15
|
-
/**
|
|
16
|
-
* Function that determines whether the module should
|
|
17
|
-
* attempt to connect upon failure.
|
|
18
|
-
*
|
|
19
|
-
* @param err error that was thrown
|
|
20
|
-
* @returns whether to retry connection or not
|
|
21
|
-
*/
|
|
22
|
-
toRetry?: (err: any) => boolean;
|
|
23
|
-
/**
|
|
24
|
-
* If `true`, connection will not be closed on application shutdown.
|
|
25
|
-
*/
|
|
26
|
-
keepConnectionAlive?: boolean;
|
|
27
|
-
/**
|
|
28
|
-
* If `true`, will show verbose error messages on each connection retry.
|
|
29
|
-
*/
|
|
30
|
-
verboseRetryLog?: boolean;
|
|
31
5
|
/**
|
|
32
6
|
* Number of ms to wait closing connection on shutdown
|
|
33
7
|
* Default: 10
|
|
34
8
|
*/
|
|
35
9
|
shutdownWaitMs?: number;
|
|
10
|
+
/**
|
|
11
|
+
* If `true`, will not connect to database on application start
|
|
12
|
+
* Default: `false`
|
|
13
|
+
*/
|
|
14
|
+
lazyConnect?: boolean;
|
|
36
15
|
}
|
|
37
16
|
interface BaseModuleOptions {
|
|
17
|
+
token?: InjectionToken;
|
|
38
18
|
envPrefix?: string;
|
|
39
19
|
logger?: LoggerService | string;
|
|
40
20
|
global?: boolean;
|
|
41
|
-
name?: string;
|
|
42
|
-
lazyConnect?: boolean;
|
|
43
21
|
}
|
|
44
22
|
export interface SqbModuleOptions extends BaseModuleOptions {
|
|
45
23
|
useValue?: SqbClientConnectionOptions;
|
|
46
24
|
}
|
|
47
|
-
export interface
|
|
48
|
-
createSqbOptions(connectionName?: string): Promise<SqbClientConnectionOptions> | SqbClientConnectionOptions;
|
|
49
|
-
}
|
|
50
|
-
export interface SqbModuleAsyncOptions extends BaseModuleOptions, Pick<ModuleMetadata, 'imports'> {
|
|
51
|
-
name?: string;
|
|
52
|
-
useExisting?: Type<SqbOptionsFactory>;
|
|
53
|
-
useClass?: Type<SqbOptionsFactory>;
|
|
54
|
-
useFactory?: (...args: any[]) => Promise<SqbClientConnectionOptions> | SqbClientConnectionOptions;
|
|
25
|
+
export interface SqbModuleAsyncOptions extends BaseModuleOptions, Partial<Pick<ModuleMetadata, 'imports'>> {
|
|
55
26
|
inject?: any[];
|
|
27
|
+
useFactory?: (...args: any[]) => Promise<SqbClientConnectionOptions> | SqbClientConnectionOptions;
|
|
56
28
|
}
|
|
57
29
|
export {};
|
package/sqb.decorators.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare const InjectSQB: (name?: string) => ParameterDecorator;
|
package/sqb.decorators.js
DELETED
package/sqb.utils.d.ts
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { Type } from '@nestjs/common';
|
|
2
|
-
import { SqbClient } from '@sqb/connect';
|
|
3
|
-
import { Observable } from 'rxjs';
|
|
4
|
-
/**
|
|
5
|
-
* This function returns a Connection injection token for the given connection name.
|
|
6
|
-
* @param {string | symbol} [name=SQB_DEFAULT_CONNECTION] This optional parameter is either
|
|
7
|
-
* a SqbClient, or a ConnectionOptions or a string.
|
|
8
|
-
* @returns {string | symbol} The Connection injection token.
|
|
9
|
-
*/
|
|
10
|
-
export declare function getSQBToken(name?: string | symbol | Type<SqbClient>): string | symbol | Type<SqbClient>;
|
|
11
|
-
export declare function handleRetry(connectionName?: string | symbol | Type<SqbClient>, retryAttempts?: number, retryDelay?: number, verboseRetryLog?: boolean, toRetry?: (err: any) => boolean): <T>(source: Observable<T>) => Observable<T>;
|
package/sqb.utils.js
DELETED
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import { Logger } from '@nestjs/common';
|
|
2
|
-
import { SqbClient } from '@sqb/connect';
|
|
3
|
-
import { delay, retryWhen, scan } from 'rxjs/operators';
|
|
4
|
-
const logger = new Logger('SqbModule');
|
|
5
|
-
/**
|
|
6
|
-
* This function returns a Connection injection token for the given connection name.
|
|
7
|
-
* @param {string | symbol} [name=SQB_DEFAULT_CONNECTION] This optional parameter is either
|
|
8
|
-
* a SqbClient, or a ConnectionOptions or a string.
|
|
9
|
-
* @returns {string | symbol} The Connection injection token.
|
|
10
|
-
*/
|
|
11
|
-
export function getSQBToken(name) {
|
|
12
|
-
if (!name)
|
|
13
|
-
return SqbClient;
|
|
14
|
-
if (typeof name === 'symbol' || typeof name === 'function')
|
|
15
|
-
return name;
|
|
16
|
-
return `${name}_SqbConnection`;
|
|
17
|
-
}
|
|
18
|
-
export function handleRetry(connectionName, retryAttempts = 9, retryDelay = 3000, verboseRetryLog = false, toRetry) {
|
|
19
|
-
return (source) => source.pipe(retryWhen(e => e.pipe(scan((errorCount, error) => {
|
|
20
|
-
if (toRetry && !toRetry(error)) {
|
|
21
|
-
throw error;
|
|
22
|
-
}
|
|
23
|
-
const connectionInfo = !connectionName || connectionName === SqbClient
|
|
24
|
-
? 'default'
|
|
25
|
-
: ` (${String(connectionName)})`;
|
|
26
|
-
const verboseMessage = verboseRetryLog
|
|
27
|
-
? ` Message: ${error.message}.`
|
|
28
|
-
: '';
|
|
29
|
-
logger.error(`Unable to connect to the database ${connectionInfo}.${verboseMessage} Retrying (${errorCount + 1})...`, error.stack);
|
|
30
|
-
if (errorCount + 1 >= retryAttempts) {
|
|
31
|
-
throw error;
|
|
32
|
-
}
|
|
33
|
-
return errorCount + 1;
|
|
34
|
-
}, 0), delay(retryDelay))));
|
|
35
|
-
}
|