@hg-ts/redis 0.5.17 → 0.5.18

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hg-ts/redis",
3
- "version": "0.5.17",
3
+ "version": "0.5.18",
4
4
  "main": "dist/index.js",
5
5
  "type": "module",
6
6
  "exports": {
@@ -16,11 +16,11 @@
16
16
  "lint:ts:fix": "lint-ts --fix"
17
17
  },
18
18
  "devDependencies": {
19
- "@hg-ts-config/typescript": "0.5.17",
20
- "@hg-ts/config-loader": "0.5.17",
21
- "@hg-ts/linter": "0.5.17",
22
- "@hg-ts/types": "0.5.17",
23
- "@hg-ts/validation": "0.5.17",
19
+ "@hg-ts-config/typescript": "0.5.18",
20
+ "@hg-ts/config-loader": "0.5.18",
21
+ "@hg-ts/linter": "0.5.18",
22
+ "@hg-ts/types": "0.5.18",
23
+ "@hg-ts/validation": "0.5.18",
24
24
  "@nestjs/common": "11.1.0",
25
25
  "@types/node": "22.19.1",
26
26
  "eslint": "9.18.0",
@@ -31,8 +31,8 @@
31
31
  "typescript": "5.7.3"
32
32
  },
33
33
  "peerDependencies": {
34
- "@hg-ts/config-loader": "0.5.17",
35
- "@hg-ts/validation": "0.5.17",
34
+ "@hg-ts/config-loader": "0.5.18",
35
+ "@hg-ts/validation": "0.5.18",
36
36
  "@nestjs/common": "*",
37
37
  "reflect-metadata": "*",
38
38
  "rxjs": "*",
package/src/index.ts ADDED
@@ -0,0 +1,2 @@
1
+ export * from './redis.module.js';
2
+ export * from './redis.client.js';
@@ -0,0 +1,30 @@
1
+ import {
2
+ Injectable,
3
+ OnModuleDestroy,
4
+ OnModuleInit,
5
+ } from '@nestjs/common';
6
+
7
+ import { Redis } from 'ioredis';
8
+
9
+ import { RedisConfig } from './redis.config.js';
10
+
11
+ @Injectable()
12
+ export class RedisClient extends Redis implements OnModuleInit, OnModuleDestroy {
13
+ public constructor(config: RedisConfig) {
14
+ super({
15
+ host: config.host,
16
+ port: config.port,
17
+ db: config.database,
18
+ enableReadyCheck: true,
19
+ lazyConnect: true,
20
+ });
21
+ }
22
+
23
+ public async onModuleInit(): Promise<void> {
24
+ await this.connect();
25
+ }
26
+
27
+ public async onModuleDestroy(): Promise<void> {
28
+ await this.quit();
29
+ }
30
+ }
@@ -0,0 +1,9 @@
1
+ import zod from '@hg-ts/validation';
2
+
3
+ export const REDIS_CONFIG_SCHEMA = zod.object({
4
+ host: zod.string().enforceEnv('REDIS_HOST'),
5
+ database: zod.number().int().min(0),
6
+ port: zod.number().positive().int(),
7
+ });
8
+
9
+ export class RedisConfig extends REDIS_CONFIG_SCHEMA.toClass() {}
@@ -0,0 +1,25 @@
1
+ import { ConfigLoader } from '@hg-ts/config-loader';
2
+
3
+ import {
4
+ Global,
5
+ Module,
6
+ } from '@nestjs/common';
7
+
8
+ import { RedisClient } from './redis.client.js';
9
+ import { RedisConfig } from './redis.config.js';
10
+
11
+ @Global()
12
+ @Module({
13
+ providers: [
14
+ {
15
+ provide: RedisConfig,
16
+ async useFactory(configLoader: ConfigLoader): Promise<RedisConfig> {
17
+ return configLoader.load(RedisConfig, 'redis');
18
+ },
19
+ inject: [ConfigLoader],
20
+ },
21
+ RedisClient,
22
+ ],
23
+ exports: [RedisClient, RedisConfig],
24
+ })
25
+ export class RedisModule {}
@@ -0,0 +1 @@
1
+ export * from './redis-testcontainer.module.js';
@@ -0,0 +1,12 @@
1
+ import {
2
+ Global,
3
+ Module,
4
+ } from '@nestjs/common';
5
+
6
+ import { RedisModule } from '../redis.module.js';
7
+
8
+ import { RedisTestContainerService } from './redis-testcontainer.service.js';
9
+
10
+ @Global()
11
+ @Module({ imports: [RedisModule], providers: [RedisTestContainerService] })
12
+ export class RedisTestContainerModule {}
@@ -0,0 +1,62 @@
1
+ import {
2
+ Inject,
3
+ OnModuleDestroy,
4
+ OnModuleInit,
5
+ } from '@nestjs/common';
6
+
7
+ import {
8
+ RedisContainer,
9
+ StartedRedisContainer,
10
+ } from '@testcontainers/redis';
11
+
12
+ import { RedisClient } from '../redis.client.js';
13
+ import { RedisConfig } from '../redis.config.js';
14
+
15
+ export class RedisTestContainerService implements OnModuleInit, OnModuleDestroy {
16
+ @Inject()
17
+ private readonly config: RedisConfig;
18
+
19
+ private container: StartedRedisContainer;
20
+
21
+ private initPromise: Nullable<Promise<void>> = null;
22
+
23
+ public constructor() {
24
+ this.enrichClient();
25
+ }
26
+
27
+ public async onModuleInit(): Promise<void> {
28
+ if (!this.initPromise) {
29
+ this.initPromise = this.startContainer();
30
+ }
31
+
32
+ return this.initPromise;
33
+ }
34
+
35
+ public async onModuleDestroy(): Promise<void> {
36
+ await this.stopContainer();
37
+ }
38
+
39
+ private async startContainer(): Promise<void> {
40
+ const container = new RedisContainer('redis')
41
+ .withReuse()
42
+ .withExposedPorts({ container: 6379, host: this.config.port });
43
+
44
+ this.container = await container.start();
45
+ }
46
+
47
+ private async stopContainer(): Promise<void> {
48
+ await this.container.stop();
49
+ }
50
+
51
+ private enrichClient(): void {
52
+ // eslint-disable-next-line @typescript/unbound-method
53
+ const originalInitHook = RedisClient.prototype.onModuleInit;
54
+ // eslint-disable-next-line @typescript/no-this-alias
55
+ const self = this;
56
+
57
+ RedisClient.prototype.onModuleInit = async function(this: OnModuleInit): Promise<void> {
58
+ await self.onModuleInit();
59
+ return originalInitHook.call(this);
60
+ };
61
+ }
62
+ }