@flusys/nestjs-shared 5.1.2 → 5.2.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.
@@ -20,12 +20,40 @@ function _ts_decorate(decorators, target, key, desc) {
20
20
  function _ts_metadata(k, v) {
21
21
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
22
22
  }
23
- import { InternalServerErrorException, NotFoundException } from '@nestjs/common';
24
- import { In } from 'typeorm';
23
+ import { Injectable, InternalServerErrorException, NotFoundException, Scope } from '@nestjs/common';
24
+ import { EntityTarget, In } from 'typeorm';
25
25
  import { ERROR_MESSAGES, SYSTEM_MESSAGES } from '../constants';
26
26
  import { LogAction } from '../decorators/log-action.decorator';
27
27
  import { DeleteDto } from '../dtos';
28
- /** Generic API service with CRUD operations and caching support */ export class ApiService {
28
+ import { IDataSourceProvider } from '../interfaces';
29
+ import { UtilsService } from '../modules/utils/utils.service';
30
+ import { HybridCache } from './hybrid-cache.class';
31
+ export class ApiService {
32
+ resolveEntity() {
33
+ return this._entity;
34
+ }
35
+ getDataSourceProvider() {
36
+ return this._dataSourceProvider;
37
+ }
38
+ async ensureDataSourceRepository() {
39
+ if (!this.repositoryInitialized) {
40
+ const entity = this.resolveEntity();
41
+ const provider = this.getDataSourceProvider();
42
+ this.repository = await provider.getRepository(entity);
43
+ this.repositoryInitialized = true;
44
+ }
45
+ }
46
+ async resolveRepositories(entities) {
47
+ const provider = this.getDataSourceProvider();
48
+ const repositories = [];
49
+ for (const entity of entities){
50
+ repositories.push(await provider.getRepository(entity));
51
+ }
52
+ return repositories;
53
+ }
54
+ async getDataSourceForService() {
55
+ return this.getDataSourceProvider().getDataSource();
56
+ }
29
57
  async insert(dto, user) {
30
58
  return this.executeInTransaction('insert', async (qr)=>{
31
59
  await this.beforeInsertOperation(dto, user, qr);
@@ -98,7 +126,7 @@ import { DeleteDto } from '../dtos';
98
126
  });
99
127
  }
100
128
  async findByIds(ids, user, select) {
101
- await this.ensureRepositoryInitialized();
129
+ await this.ensureDataSourceRepository();
102
130
  try {
103
131
  const query = this.repository.createQueryBuilder(this.entityName);
104
132
  query.where({
@@ -126,7 +154,7 @@ import { DeleteDto } from '../dtos';
126
154
  }
127
155
  }
128
156
  async findById(id, user, select) {
129
- await this.ensureRepositoryInitialized();
157
+ await this.ensureDataSourceRepository();
130
158
  try {
131
159
  const query = this.repository.createQueryBuilder(this.entityName);
132
160
  query.where({
@@ -140,18 +168,17 @@ import { DeleteDto } from '../dtos';
140
168
  result = await this.cacheManager.get(cacheKey);
141
169
  }
142
170
  if (!result) {
143
- let output;
144
171
  if (isRaw) {
145
- output = await finalQuery.getRawMany();
146
- const convertResult = this.convertEntityListToResponseListDto(output, isRaw);
172
+ const rawOutput = await finalQuery.getRawMany();
173
+ const convertResult = this.convertEntityListToResponseListDto(rawOutput, isRaw);
147
174
  if (convertResult.length) result = convertResult[0];
148
175
  } else {
149
- output = await finalQuery.getOne();
150
- if (!output) throw new NotFoundException({
176
+ const singleOutput = await finalQuery.getOne();
177
+ if (!singleOutput) throw new NotFoundException({
151
178
  message: 'No Data Found',
152
179
  messageKey: ERROR_MESSAGES.NOT_FOUND
153
180
  });
154
- result = this.convertEntityToResponseDto(output, false);
181
+ result = this.convertEntityToResponseDto(singleOutput, false);
155
182
  }
156
183
  if (this.isCacheable) {
157
184
  await this.cacheManager.set(cacheKey, result);
@@ -167,41 +194,34 @@ import { DeleteDto } from '../dtos';
167
194
  }
168
195
  }
169
196
  async getAll(search, filterAndPaginationDto, user) {
170
- await this.ensureRepositoryInitialized();
197
+ await this.ensureDataSourceRepository();
171
198
  try {
172
199
  let data;
173
200
  let total;
174
201
  let isRaw = false;
175
202
  let query = this.repository.createQueryBuilder(this.entityName);
176
- // Apply filters
177
203
  if (filterAndPaginationDto.filter) {
178
204
  const { query: filterQuery, isRaw: filterIsRaw } = await this.getFilterQuery(query, filterAndPaginationDto.filter, user);
179
205
  query = filterQuery;
180
206
  isRaw = isRaw || filterIsRaw;
181
207
  }
182
- // Apply search
183
208
  if (search) {
184
209
  const { query: searchQuery, isRaw: searchIsRaw } = await this.getGlobalSearchQuery(query, search, user);
185
210
  query = searchQuery;
186
211
  isRaw = isRaw || searchIsRaw;
187
212
  }
188
- // Apply select — always call so subclasses can define a default column set
189
213
  const { query: selectQuery, isRaw: selectIsRaw } = await this.getSelectQuery(query, user, filterAndPaginationDto.select);
190
214
  query = selectQuery;
191
215
  isRaw = isRaw || selectIsRaw;
192
- // Apply sort
193
216
  if (filterAndPaginationDto.sort) {
194
217
  const { query: sortQuery, isRaw: sortIsRaw } = await this.getSortQuery(query, filterAndPaginationDto.sort, user);
195
218
  query = sortQuery;
196
219
  isRaw = isRaw || sortIsRaw;
197
220
  }
198
- // Include soft-deleted if requested
199
221
  if (filterAndPaginationDto.withDeleted) query.withDeleted();
200
- // Extra manipulation
201
222
  const { query: extraQuery, isRaw: extraIsRaw } = await this.getExtraManipulateQuery(query, filterAndPaginationDto, user);
202
223
  query = extraQuery;
203
224
  isRaw = isRaw || extraIsRaw;
204
- // Pagination
205
225
  if (filterAndPaginationDto.pagination) {
206
226
  const offset = filterAndPaginationDto.pagination.currentPage * filterAndPaginationDto.pagination.pageSize;
207
227
  const limit = filterAndPaginationDto.pagination.pageSize;
@@ -211,7 +231,6 @@ import { DeleteDto } from '../dtos';
211
231
  query.skip(offset).take(limit);
212
232
  }
213
233
  }
214
- // Generate cache key
215
234
  let cacheKey = '';
216
235
  if (this.isCacheable) {
217
236
  cacheKey = this.utilsService.getCacheKey(this.entityName, {
@@ -225,7 +244,6 @@ import { DeleteDto } from '../dtos';
225
244
  }
226
245
  }
227
246
  if (isRaw) {
228
- // Handle raw query count manually
229
247
  const rawSubQuery = query.clone().offset(undefined).limit(undefined).distinct(true);
230
248
  const countSql = `
231
249
  SELECT COUNT(*) as count
@@ -273,7 +291,7 @@ import { DeleteDto } from '../dtos';
273
291
  }
274
292
  }
275
293
  async delete(option, user) {
276
- await this.ensureRepositoryInitialized();
294
+ await this.ensureDataSourceRepository();
277
295
  const queryRunner = this.repository.manager.connection.createQueryRunner();
278
296
  await queryRunner.connect();
279
297
  await queryRunner.startTransaction();
@@ -305,7 +323,6 @@ import { DeleteDto } from '../dtos';
305
323
  this.clearCacheForAll(),
306
324
  this.clearCacheForId(ids)
307
325
  ]);
308
- // return null per IService contract
309
326
  return null;
310
327
  } catch (error) {
311
328
  await queryRunner.rollbackTransaction();
@@ -314,7 +331,6 @@ import { DeleteDto } from '../dtos';
314
331
  await queryRunner.release();
315
332
  }
316
333
  }
317
- // Caching
318
334
  async clearCacheForAll() {
319
335
  await this.utilsService.clearCache(this.entityName, this.cacheManager);
320
336
  }
@@ -330,13 +346,13 @@ import { DeleteDto } from '../dtos';
330
346
  messageKey: ERROR_MESSAGES.INTERNAL
331
347
  });
332
348
  }
333
- /** Ensures value is always an array */ ensureArray(value) {
349
+ ensureArray(value) {
334
350
  return Array.isArray(value) ? value : [
335
351
  value
336
352
  ];
337
353
  }
338
- /** Executes operation in transaction with automatic cache clearing */ async executeInTransaction(operation, fn) {
339
- await this.ensureRepositoryInitialized();
354
+ async executeInTransaction(operation, fn) {
355
+ await this.ensureDataSourceRepository();
340
356
  const qr = this.repository.manager.connection.createQueryRunner();
341
357
  await qr.connect();
342
358
  await qr.startTransaction();
@@ -361,8 +377,6 @@ import { DeleteDto } from '../dtos';
361
377
  await qr.release();
362
378
  }
363
379
  }
364
- // Hooks (override in child classes)
365
- async ensureRepositoryInitialized() {}
366
380
  async beforeInsertOperation(_dto, _user, _queryRunner) {}
367
381
  async afterInsertOperation(_entity, _user, _queryRunner) {}
368
382
  async beforeUpdateOperation(_dto, _user, _queryRunner) {}
@@ -411,7 +425,6 @@ import { DeleteDto } from '../dtos';
411
425
  isRaw: false
412
426
  };
413
427
  }
414
- // DTO conversion
415
428
  async convertRequestDtoToEntity(dto, user) {
416
429
  return Array.isArray(dto) ? await this.convertArrayDtoToEntities(dto, user) : [
417
430
  await this.convertSingleDtoToEntity(dto, user)
@@ -446,21 +459,26 @@ import { DeleteDto } from '../dtos';
446
459
  async getEntityClass() {
447
460
  return await this.repository.create();
448
461
  }
449
- constructor(entityName, repository, cacheManager, utilsService, _loggerName, isCacheable = false, moduleName){
462
+ constructor(entityName, cacheManager, utilsService, _loggerName, isCacheable = false, moduleName, entity, dataSourceProvider){
450
463
  _define_property(this, "entityName", void 0);
451
- _define_property(this, "repository", void 0);
452
464
  _define_property(this, "cacheManager", void 0);
453
465
  _define_property(this, "utilsService", void 0);
454
466
  _define_property(this, "_loggerName", void 0);
455
467
  _define_property(this, "isCacheable", void 0);
456
468
  _define_property(this, "moduleName", void 0);
469
+ _define_property(this, "repository", void 0);
470
+ _define_property(this, "repositoryInitialized", void 0);
471
+ _define_property(this, "_entity", void 0);
472
+ _define_property(this, "_dataSourceProvider", void 0);
457
473
  this.entityName = entityName;
458
- this.repository = repository;
459
474
  this.cacheManager = cacheManager;
460
475
  this.utilsService = utilsService;
461
476
  this._loggerName = _loggerName;
462
477
  this.isCacheable = isCacheable;
463
478
  this.moduleName = moduleName;
479
+ this.repositoryInitialized = false;
480
+ this._entity = entity;
481
+ this._dataSourceProvider = dataSourceProvider;
464
482
  }
465
483
  }
466
484
  _ts_decorate([
@@ -530,3 +548,19 @@ _ts_decorate([
530
548
  ]),
531
549
  _ts_metadata("design:returntype", Promise)
532
550
  ], ApiService.prototype, "delete", null);
551
+ ApiService = _ts_decorate([
552
+ Injectable({
553
+ scope: Scope.REQUEST
554
+ }),
555
+ _ts_metadata("design:type", Function),
556
+ _ts_metadata("design:paramtypes", [
557
+ String,
558
+ typeof HybridCache === "undefined" ? Object : HybridCache,
559
+ typeof UtilsService === "undefined" ? Object : UtilsService,
560
+ String,
561
+ Boolean,
562
+ String,
563
+ typeof EntityTarget === "undefined" ? Object : EntityTarget,
564
+ typeof IDataSourceProvider === "undefined" ? Object : IDataSourceProvider
565
+ ])
566
+ ], ApiService);
@@ -2,7 +2,6 @@ export * from './api-controller.class';
2
2
  export * from './api-service.class';
3
3
  export * from './handle-custome-db-column-type';
4
4
  export * from './hybrid-cache.class';
5
- export * from './request-scoped-api.service';
6
5
  export * from './winston.logger.class';
7
6
  // Re-export permission constants for convenience
8
7
  export * from '../constants/permissions';
@@ -1,20 +1 @@
1
- /**
2
- * Interface for DataSource providers used by RequestScopedApiService.
3
- * Implement this interface in each module's DataSourceProvider to ensure type safety.
4
- *
5
- * @example
6
- * ```typescript
7
- * @Injectable()
8
- * export class IAMDataSourceProvider implements IDataSourceProvider {
9
- * constructor(private readonly dataSource: DataSource) {}
10
- *
11
- * async getRepository<T extends ObjectLiteral>(entity: EntityTarget<T>): Promise<Repository<T>> {
12
- * return this.dataSource.getRepository(entity);
13
- * }
14
- *
15
- * async getDataSource(): Promise<DataSource> {
16
- * return this.dataSource;
17
- * }
18
- * }
19
- * ```
20
- */ export { };
1
+ export { };
@@ -1,2 +1 @@
1
- export * from './datasource.module';
2
1
  export * from './multi-tenant-datasource.service';
@@ -33,21 +33,21 @@ import { Request } from 'express';
33
33
  import { DataSource } from 'typeorm';
34
34
  import { SnakeNamingStrategy } from 'typeorm-naming-strategies';
35
35
  export class MultiTenantDataSourceService {
36
+ get self() {
37
+ return this.constructor;
38
+ }
36
39
  initializeFromOptions() {
37
40
  if (!this.options) return;
38
- if (!MultiTenantDataSourceService.initialized) {
41
+ if (!this.self.initialized) {
39
42
  this.registerTenants();
40
- MultiTenantDataSourceService.initialized = true;
43
+ this.self.initialized = true;
41
44
  }
42
45
  }
43
46
  registerTenants() {
44
47
  this.options?.tenants?.forEach((tenant)=>{
45
- MultiTenantDataSourceService.tenantsRegistry.set(tenant.id, tenant);
48
+ this.self.tenantsRegistry.set(tenant.id, tenant);
46
49
  });
47
50
  }
48
- setTenantHeader(header) {
49
- this.tenantHeader = header;
50
- }
51
51
  getDatabaseMode() {
52
52
  return this.options?.bootstrapAppConfig?.databaseMode ?? 'single';
53
53
  }
@@ -71,91 +71,33 @@ export class MultiTenantDataSourceService {
71
71
  return tenantId ? this.getTenant(tenantId) : null;
72
72
  }
73
73
  getTenant(tenantId) {
74
- return MultiTenantDataSourceService.tenantsRegistry.get(tenantId) ?? null;
75
- }
76
- getAllTenants() {
77
- return Array.from(MultiTenantDataSourceService.tenantsRegistry.values());
78
- }
79
- getActiveTenants() {
80
- return this.getAllTenants();
74
+ return this.self.tenantsRegistry.get(tenantId) ?? null;
81
75
  }
82
76
  async getDataSource() {
83
77
  return this.isMultiTenant() ? this.getTenantDataSource() : this.getSingleDataSource();
84
78
  }
85
- async getDataSourceForTenant(tenantId) {
86
- const tenant = this.getTenant(tenantId);
87
- if (!tenant) {
88
- throw new BadRequestException({
89
- message: `Tenant '${tenantId}' not found`,
90
- messageKey: SYSTEM_MESSAGES.TENANT_NOT_FOUND,
91
- messageVariables: {
92
- tenantId
93
- }
94
- });
95
- }
96
- return this.getOrCreateTenantConnection(tenant);
97
- }
98
- setDataSource(dataSource) {
99
- MultiTenantDataSourceService.singleDataSource = dataSource;
100
- }
101
79
  async getRepository(entity) {
102
80
  const dataSource = await this.getDataSource();
103
81
  return dataSource.getRepository(entity);
104
82
  }
105
- async withTenant(tenantId, callback) {
106
- const dataSource = await this.getDataSourceForTenant(tenantId);
107
- return callback(dataSource);
108
- }
109
- async forAllTenants(callback) {
110
- const results = new Map();
111
- for (const tenant of this.getActiveTenants()){
112
- try {
113
- const dataSource = await this.getOrCreateTenantConnection(tenant);
114
- results.set(tenant.id, await callback(tenant, dataSource));
115
- } catch {
116
- // Silent failure for individual tenant
117
- }
118
- }
119
- return results;
120
- }
121
- registerTenant(tenant) {
122
- MultiTenantDataSourceService.tenantsRegistry.set(tenant.id, tenant);
123
- }
124
- async removeTenant(tenantId) {
125
- await this.closeTenantConnection(tenantId);
126
- MultiTenantDataSourceService.tenantsRegistry.delete(tenantId);
127
- }
128
83
  async closeTenantConnection(tenantId) {
129
- const connection = MultiTenantDataSourceService.tenantConnections.get(tenantId);
84
+ const connection = this.self.tenantConnections.get(tenantId);
130
85
  if (connection?.isInitialized) {
131
86
  await connection.destroy();
132
- MultiTenantDataSourceService.tenantConnections.delete(tenantId);
87
+ this.self.tenantConnections.delete(tenantId);
133
88
  }
134
89
  }
135
90
  async onModuleDestroy() {
136
- for (const [tenantId] of MultiTenantDataSourceService.tenantConnections){
91
+ for (const [tenantId] of this.self.tenantConnections){
137
92
  await this.closeTenantConnection(tenantId);
138
93
  }
139
94
  }
140
- static reset() {
141
- MultiTenantDataSourceService.initialized = false;
142
- MultiTenantDataSourceService.singleDataSource = null;
143
- MultiTenantDataSourceService.singleConnectionLock = null;
144
- MultiTenantDataSourceService.tenantConnections.clear();
145
- MultiTenantDataSourceService.tenantsRegistry.clear();
146
- MultiTenantDataSourceService.connectionLocks.clear();
147
- }
148
- // Protected Methods (for subclasses)
149
- /**
150
- * Get single database DataSource with connection locking to prevent race conditions
151
- */ async getSingleDataSource() {
152
- // Return existing initialized connection
153
- if (MultiTenantDataSourceService.singleDataSource?.isInitialized) {
154
- return MultiTenantDataSourceService.singleDataSource;
95
+ async getSingleDataSource() {
96
+ if (this.self.singleDataSource?.isInitialized) {
97
+ return this.self.singleDataSource;
155
98
  }
156
- // If another request is creating the connection, wait for it
157
- if (MultiTenantDataSourceService.singleConnectionLock) {
158
- return MultiTenantDataSourceService.singleConnectionLock;
99
+ if (this.self.singleConnectionLock) {
100
+ return this.self.singleConnectionLock;
159
101
  }
160
102
  const config = this.getDefaultDatabaseConfig();
161
103
  if (!config) {
@@ -164,20 +106,17 @@ export class MultiTenantDataSourceService {
164
106
  messageKey: SYSTEM_MESSAGES.DATABASE_CONFIG_NOT_AVAILABLE
165
107
  });
166
108
  }
167
- // Create connection with lock to prevent race conditions
168
109
  const connectionPromise = this.createDataSourceFromConfig(config);
169
- MultiTenantDataSourceService.singleConnectionLock = connectionPromise;
110
+ this.self.singleConnectionLock = connectionPromise;
170
111
  try {
171
112
  const dataSource = await connectionPromise;
172
- MultiTenantDataSourceService.singleDataSource = dataSource;
113
+ this.self.singleDataSource = dataSource;
173
114
  return dataSource;
174
115
  } finally{
175
- MultiTenantDataSourceService.singleConnectionLock = null;
116
+ this.self.singleConnectionLock = null;
176
117
  }
177
118
  }
178
- /**
179
- * Get tenant-specific DataSource
180
- */ async getTenantDataSource() {
119
+ async getTenantDataSource() {
181
120
  const tenant = this.getCurrentTenant();
182
121
  if (!tenant) {
183
122
  throw new BadRequestException({
@@ -191,19 +130,19 @@ export class MultiTenantDataSourceService {
191
130
  return this.getOrCreateTenantConnection(tenant);
192
131
  }
193
132
  async getOrCreateTenantConnection(tenant) {
194
- const existing = MultiTenantDataSourceService.tenantConnections.get(tenant.id);
133
+ const existing = this.self.tenantConnections.get(tenant.id);
195
134
  if (existing?.isInitialized) return existing;
196
- const pendingConnection = MultiTenantDataSourceService.connectionLocks.get(tenant.id);
135
+ const pendingConnection = this.self.connectionLocks.get(tenant.id);
197
136
  if (pendingConnection) return pendingConnection;
198
137
  const config = this.buildTenantDatabaseConfig(tenant);
199
138
  const connectionPromise = this.createDataSourceFromConfig(config);
200
- MultiTenantDataSourceService.connectionLocks.set(tenant.id, connectionPromise);
139
+ this.self.connectionLocks.set(tenant.id, connectionPromise);
201
140
  try {
202
141
  const dataSource = await connectionPromise;
203
- MultiTenantDataSourceService.tenantConnections.set(tenant.id, dataSource);
142
+ this.self.tenantConnections.set(tenant.id, dataSource);
204
143
  return dataSource;
205
144
  } finally{
206
- MultiTenantDataSourceService.connectionLocks.delete(tenant.id);
145
+ this.self.connectionLocks.delete(tenant.id);
207
146
  }
208
147
  }
209
148
  getDefaultDatabaseConfig() {
@@ -6,7 +6,7 @@ export declare class PermissionGuard implements CanActivate {
6
6
  private readonly reflector;
7
7
  private readonly cache?;
8
8
  private readonly config;
9
- constructor(reflector: Reflector, cache?: HybridCache, config?: PermissionGuardConfig);
9
+ constructor(reflector: Reflector, cache?: HybridCache | undefined, config?: PermissionGuardConfig);
10
10
  canActivate(context: ExecutionContext): Promise<boolean>;
11
11
  private normalizeToLogicNode;
12
12
  private evaluateLogicNode;
@@ -5,6 +5,6 @@ export declare class IdempotencyInterceptor implements NestInterceptor {
5
5
  private readonly cache?;
6
6
  private readonly CACHE_TTL;
7
7
  private readonly PROCESSING_MARKER;
8
- constructor(cache?: HybridCache);
8
+ constructor(cache?: HybridCache | undefined);
9
9
  intercept<T = any>(context: ExecutionContext, next: CallHandler<T>): Promise<Observable<T>>;
10
10
  }
@@ -1,22 +1,21 @@
1
1
  import { NotificationType } from '../enums/notification-type.enum';
2
- export interface INotificationAdapter {
3
- send(options: NotificationSendOptions): Promise<void>;
4
- sendToMany(options: NotificationBulkSendOptions): Promise<void>;
5
- broadcastToCompany?(companyId: string, title: string, message?: string, type?: NotificationType, data?: Record<string, unknown>): Promise<void>;
6
- isUserOnline?(userId: string): boolean;
7
- }
8
- interface NotificationBaseOptions {
2
+ export declare const NOTIFICATION_ADAPTER = "NOTIFICATION_ADAPTER";
3
+ export interface INotificationContent {
9
4
  title: string;
10
- message?: string;
5
+ message?: string | null;
11
6
  type?: NotificationType;
12
- data?: Record<string, unknown>;
13
- companyId?: string;
7
+ data?: Record<string, unknown> | null;
8
+ companyId?: string | null;
9
+ realtime?: boolean;
14
10
  }
15
- export interface NotificationSendOptions extends NotificationBaseOptions {
11
+ export interface INotificationSendOptions extends INotificationContent {
16
12
  userId: string;
17
13
  }
18
- export interface NotificationBulkSendOptions extends NotificationBaseOptions {
14
+ export interface INotificationBulkSendOptions extends INotificationContent {
19
15
  userIds: string[];
20
16
  }
21
- export declare const NOTIFICATION_ADAPTER = "NOTIFICATION_ADAPTER";
22
- export {};
17
+ export interface INotificationAdapter {
18
+ send(options: INotificationSendOptions): Promise<void>;
19
+ sendToMany(options: INotificationBulkSendOptions): Promise<void>;
20
+ isUserOnline?(userId: string): boolean;
21
+ }
@@ -1,2 +1 @@
1
- export * from './datasource.module';
2
1
  export * from './multi-tenant-datasource.service';
@@ -3,8 +3,8 @@ import { OnModuleDestroy } from '@nestjs/common';
3
3
  import { Request } from 'express';
4
4
  import { DataSource, EntityTarget, ObjectLiteral, Repository } from 'typeorm';
5
5
  export declare class MultiTenantDataSourceService implements OnModuleDestroy {
6
- protected readonly options?: IDataSourceServiceOptions;
7
- protected readonly request?: Request;
6
+ protected readonly options?: IDataSourceServiceOptions | undefined;
7
+ protected readonly request?: Request | undefined;
8
8
  protected static readonly tenantConnections: Map<string, DataSource>;
9
9
  protected static singleDataSource: DataSource | null;
10
10
  protected static readonly tenantsRegistry: Map<string, ITenantDatabaseConfig>;
@@ -12,28 +12,19 @@ export declare class MultiTenantDataSourceService implements OnModuleDestroy {
12
12
  protected static readonly connectionLocks: Map<string, Promise<DataSource>>;
13
13
  protected static singleConnectionLock: Promise<DataSource> | null;
14
14
  protected tenantHeader: string;
15
- constructor(options?: IDataSourceServiceOptions, request?: Request);
15
+ constructor(options?: IDataSourceServiceOptions | undefined, request?: Request | undefined);
16
+ private get self();
16
17
  private initializeFromOptions;
17
18
  private registerTenants;
18
- setTenantHeader(header: string): void;
19
19
  getDatabaseMode(): DatabaseMode;
20
20
  isMultiTenant(): boolean;
21
21
  getCurrentTenantId(): string | null;
22
22
  getCurrentTenant(): ITenantDatabaseConfig | null;
23
23
  getTenant(tenantId: string): ITenantDatabaseConfig | null;
24
- getAllTenants(): ITenantDatabaseConfig[];
25
- getActiveTenants(): ITenantDatabaseConfig[];
26
24
  getDataSource(): Promise<DataSource>;
27
- getDataSourceForTenant(tenantId: string): Promise<DataSource>;
28
- setDataSource(dataSource: DataSource): void;
29
25
  getRepository<T extends ObjectLiteral>(entity: EntityTarget<T>): Promise<Repository<T>>;
30
- withTenant<T>(tenantId: string, callback: (ds: DataSource) => Promise<T>): Promise<T>;
31
- forAllTenants<T>(callback: (tenant: ITenantDatabaseConfig, ds: DataSource) => Promise<T>): Promise<Map<string, T>>;
32
- registerTenant(tenant: ITenantDatabaseConfig): void;
33
- removeTenant(tenantId: string): Promise<void>;
34
26
  closeTenantConnection(tenantId: string): Promise<void>;
35
27
  onModuleDestroy(): Promise<void>;
36
- static reset(): void;
37
28
  protected getSingleDataSource(): Promise<DataSource>;
38
29
  protected getTenantDataSource(): Promise<DataSource>;
39
30
  protected getOrCreateTenantConnection(tenant: ITenantDatabaseConfig): Promise<DataSource>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flusys/nestjs-shared",
3
- "version": "5.1.2",
3
+ "version": "5.2.0",
4
4
  "description": "Common shared utilities for Flusys NestJS applications",
5
5
  "main": "cjs/index.js",
6
6
  "module": "fesm/index.js",
@@ -93,25 +93,25 @@
93
93
  }
94
94
  },
95
95
  "peerDependencies": {
96
- "@keyv/redis": "^5.0.1",
97
- "@nestjs/common": "^10.0.0 || ^11.0.0",
98
- "@nestjs/config": "^3.0.0 || ^4.0.0",
99
- "@nestjs/core": "^10.0.0 || ^11.0.0",
100
- "@nestjs/jwt": "^10.0.0 || ^11.0.0",
101
- "@nestjs/passport": "^10.0.0 || ^11.0.0",
102
- "@nestjs/swagger": "^7.0.0 || ^11.0.0",
103
- "@nestjs/typeorm": "^10.0.0 || ^11.0.0",
104
- "cacheable": "^2.0.0",
105
- "class-transformer": "^0.5.0",
106
- "class-validator": "^0.14.0",
107
- "keyv": "^5.0.1",
96
+ "@keyv/redis": "^5.1.0",
97
+ "@nestjs/common": "^11.0.0",
98
+ "@nestjs/config": "^4.0.0",
99
+ "@nestjs/core": "^11.0.0",
100
+ "@nestjs/jwt": "^11.0.0",
101
+ "@nestjs/passport": "^11.0.0",
102
+ "@nestjs/swagger": "^11.0.0",
103
+ "@nestjs/typeorm": "^11.0.0",
104
+ "cacheable": "^2.1.0",
105
+ "class-transformer": "^0.5.1",
106
+ "class-validator": "^0.14.0 || ^0.15.0",
107
+ "keyv": "^5.0.0",
108
108
  "typeorm": "^0.3.0",
109
109
  "winston": "^3.0.0",
110
110
  "winston-daily-rotate-file": "^5.0.0",
111
- "express": "^4.18.0",
111
+ "express": "^4.18.0 || ^5.0.0",
112
112
  "rxjs": "^7.8.0"
113
113
  },
114
114
  "dependencies": {
115
- "@flusys/nestjs-core": "5.1.2"
115
+ "@flusys/nestjs-core": "5.2.0"
116
116
  }
117
117
  }