nestjs-redis-ui 0.1.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 (38) hide show
  1. package/README.md +256 -0
  2. package/dist/redis/constants/redis.constants.d.ts +2 -0
  3. package/dist/redis/constants/redis.constants.js +6 -0
  4. package/dist/redis/constants/redis.constants.js.map +1 -0
  5. package/dist/redis/index.d.ts +6 -0
  6. package/dist/redis/index.js +15 -0
  7. package/dist/redis/index.js.map +1 -0
  8. package/dist/redis/interfaces/index.d.ts +3 -0
  9. package/dist/redis/interfaces/index.js +3 -0
  10. package/dist/redis/interfaces/index.js.map +1 -0
  11. package/dist/redis/interfaces/redis-module-options.interface.d.ts +20 -0
  12. package/dist/redis/interfaces/redis-module-options.interface.js +3 -0
  13. package/dist/redis/interfaces/redis-module-options.interface.js.map +1 -0
  14. package/dist/redis/interfaces/redis-ui-options.interface.d.ts +18 -0
  15. package/dist/redis/interfaces/redis-ui-options.interface.js +3 -0
  16. package/dist/redis/interfaces/redis-ui-options.interface.js.map +1 -0
  17. package/dist/redis/interfaces/redis-ui-store.interface.d.ts +11 -0
  18. package/dist/redis/interfaces/redis-ui-store.interface.js +3 -0
  19. package/dist/redis/interfaces/redis-ui-store.interface.js.map +1 -0
  20. package/dist/redis/providers/redis.providers.d.ts +4 -0
  21. package/dist/redis/providers/redis.providers.js +60 -0
  22. package/dist/redis/providers/redis.providers.js.map +1 -0
  23. package/dist/redis/redis.module.d.ts +6 -0
  24. package/dist/redis/redis.module.js +49 -0
  25. package/dist/redis/redis.module.js.map +1 -0
  26. package/dist/redis/services/redis.service.d.ts +15 -0
  27. package/dist/redis/services/redis.service.js +83 -0
  28. package/dist/redis/services/redis.service.js.map +1 -0
  29. package/dist/redis/ui/assets/client.js +203 -0
  30. package/dist/redis/ui/assets/index.html +46 -0
  31. package/dist/redis/ui/assets/styles.css +266 -0
  32. package/dist/redis/ui/redis-ui.d.ts +13 -0
  33. package/dist/redis/ui/redis-ui.js +117 -0
  34. package/dist/redis/ui/redis-ui.js.map +1 -0
  35. package/dist/redis/ui/resolve-redis-ui-options.d.ts +10 -0
  36. package/dist/redis/ui/resolve-redis-ui-options.js +25 -0
  37. package/dist/redis/ui/resolve-redis-ui-options.js.map +1 -0
  38. package/package.json +113 -0
package/README.md ADDED
@@ -0,0 +1,256 @@
1
+ # redis-ui
2
+
3
+ NestJS용 Redis 모듈 + 웹 UI 패키지입니다.
4
+ Swagger처럼 `main.ts`에서 UI를 붙이고, `RedisModule` / `RedisService`로 Redis에 접근할 수 있습니다.
5
+
6
+ ## 설치
7
+
8
+ ```bash
9
+ npm install redis-ui ioredis
10
+ ```
11
+
12
+ Peer dependency:
13
+
14
+ - `@nestjs/common` >= 10
15
+ - `@nestjs/core` >= 10
16
+ - `ioredis` >= 5
17
+
18
+ ## 빠른 시작
19
+
20
+ ### 1. 모듈 등록
21
+
22
+ ```ts
23
+ // app.module.ts
24
+ import { Module } from '@nestjs/common';
25
+ import { RedisModule } from 'redis-ui';
26
+
27
+ @Module({
28
+ imports: [
29
+ RedisModule.forRoot({
30
+ host: '127.0.0.1',
31
+ port: 6379,
32
+ // password: 'secret',
33
+ // db: 0,
34
+ // tls: true,
35
+ }),
36
+ ],
37
+ })
38
+ export class AppModule {}
39
+ ```
40
+
41
+ ### 2. UI 마운트
42
+
43
+ ```ts
44
+ // main.ts
45
+ import { NestFactory } from '@nestjs/core';
46
+ import { AppModule } from './app.module';
47
+ import { RedisService, RedisUi } from 'redis-ui';
48
+
49
+ async function bootstrap() {
50
+ const app = await NestFactory.create(AppModule);
51
+
52
+ RedisUi.setup(app, {
53
+ enabled: true,
54
+ store: app.get(RedisService),
55
+ path: 'redis-ui',
56
+ auth: {
57
+ username: 'admin',
58
+ password: 'secret',
59
+ },
60
+ });
61
+
62
+ await app.listen(3000);
63
+ }
64
+ bootstrap();
65
+ ```
66
+
67
+ 브라우저에서 `http://localhost:3000/redis-ui` 로 접속합니다.
68
+
69
+ ---
70
+
71
+ ## RedisModule
72
+
73
+ ### `forRoot`
74
+
75
+ 동기 설정입니다.
76
+
77
+ ```ts
78
+ RedisModule.forRoot({
79
+ host: '127.0.0.1',
80
+ port: 6379,
81
+ password: undefined,
82
+ db: 0,
83
+ keyPrefix: 'app:',
84
+ tls: false,
85
+ // ioredis 추가 옵션
86
+ redisOptions: {
87
+ connectTimeout: 10_000,
88
+ },
89
+ });
90
+ ```
91
+
92
+ | 옵션 | 타입 | 기본값 | 설명 |
93
+ |------|------|--------|------|
94
+ | `host` | `string` | `127.0.0.1` | Redis 호스트 |
95
+ | `port` | `number` | `6379` | Redis 포트 |
96
+ | `password` | `string` | - | 비밀번호 |
97
+ | `db` | `number` | `0` | DB index |
98
+ | `keyPrefix` | `string` | - | 키 prefix |
99
+ | `tls` | `boolean \| object` | - | TLS 사용 |
100
+ | `redisOptions` | `RedisOptions` | - | ioredis 추가 옵션 |
101
+
102
+ ### `forRootAsync`
103
+
104
+ 환경변수 / ConfigModule과 같이 쓸 때 사용합니다.
105
+
106
+ ```ts
107
+ RedisModule.forRootAsync({
108
+ imports: [ConfigModule],
109
+ inject: [ConfigService],
110
+ useFactory: (config: ConfigService) => ({
111
+ host: config.get('REDIS_HOST', '127.0.0.1'),
112
+ port: config.get<number>('REDIS_PORT', 6379),
113
+ password: config.get('REDIS_PASSWORD'),
114
+ tls: config.get('REDIS_TLS') === 'true',
115
+ }),
116
+ });
117
+ ```
118
+
119
+ ---
120
+
121
+ ## RedisService
122
+
123
+ 어디서든 DI로 주입해 사용합니다. `RedisUiStore`도 구현하므로 UI에 그대로 넘길 수 있습니다.
124
+
125
+ ```ts
126
+ import { Injectable } from '@nestjs/common';
127
+ import { RedisService } from 'redis-ui';
128
+
129
+ @Injectable()
130
+ export class ExampleService {
131
+ constructor(private readonly redis: RedisService) {}
132
+
133
+ async demo() {
134
+ await this.redis.set('user:1', { name: 'kim' }, 300); // TTL 300초
135
+ const value = await this.redis.get<{ name: string }>('user:1');
136
+ const keys = await this.redis.keys('user:*');
137
+ const ttl = await this.redis.ttl('user:1');
138
+ const entry = await this.redis.getEntry('user:1');
139
+ await this.redis.delete('user:1');
140
+
141
+ // 필요하면 raw ioredis 클라이언트
142
+ const client = this.redis.getClient();
143
+ }
144
+ }
145
+ ```
146
+
147
+ ### API
148
+
149
+ | 메서드 | 설명 |
150
+ |--------|------|
151
+ | `get<T>(key)` | 값 조회 (JSON이면 파싱) |
152
+ | `set(key, value, ttlSeconds?)` | 값 저장 |
153
+ | `delete(key)` | 키 삭제 |
154
+ | `keys(pattern?)` | SCAN 기반 키 목록 (`*` 기본) |
155
+ | `ttl(key)` | TTL(초) |
156
+ | `getEntry(key)` | `{ key, value, ttl, type }` |
157
+ | `getClient()` | ioredis 인스턴스 |
158
+
159
+ 토큰으로 클라이언트만 주입할 수도 있습니다.
160
+
161
+ ```ts
162
+ import { Inject } from '@nestjs/common';
163
+ import { REDIS_CLIENT } from 'redis-ui';
164
+ import type Redis from 'ioredis';
165
+
166
+ constructor(@Inject(REDIS_CLIENT) private readonly client: Redis) {}
167
+ ```
168
+
169
+ ---
170
+
171
+ ## RedisUi
172
+
173
+ `RedisUi.setup(app, options)` 로 Express 라우트와 정적 UI를 붙입니다.
174
+
175
+ ```ts
176
+ RedisUi.setup(app, {
177
+ enabled: true,
178
+ store: app.get(RedisService),
179
+ path: 'redis-ui',
180
+ title: 'Redis UI',
181
+ badge: 'CACHE',
182
+ defaultPattern: '*',
183
+ allowDelete: true,
184
+ auth: false, // 또는 { username, password }
185
+ });
186
+ ```
187
+
188
+ | 옵션 | 타입 | 기본값 | 설명 |
189
+ |------|------|--------|------|
190
+ | `enabled` | `boolean` | (필수) | UI 활성화 |
191
+ | `store` | `RedisUiStore` | (필수) | 데이터 접근 구현체 |
192
+ | `path` | `string` | `redis-ui` | URL 경로 |
193
+ | `title` | `string` | `Redis UI` | 페이지 타이틀 |
194
+ | `badge` | `string` | `CACHE` | 헤더 뱃지 |
195
+ | `defaultPattern` | `string` | `*` | 초기 키 패턴 |
196
+ | `allowDelete` | `boolean` | `true` | UI에서 삭제 허용 |
197
+ | `auth` | `{ username, password } \| false` | `false` | Basic Auth |
198
+
199
+ ### 엔드포인트
200
+
201
+ | Method | Path | 설명 |
202
+ |--------|------|------|
203
+ | `GET` | `/{path}` | UI 페이지 |
204
+ | `GET` | `/{path}/api/keys?pattern=*` | 키 목록 |
205
+ | `GET` | `/{path}/api/entry?key=...` | 키 상세 |
206
+ | `DELETE` | `/{path}/api/entry?key=...` | 키 삭제 (`allowDelete: true`) |
207
+
208
+ ### 커스텀 Store
209
+
210
+ 자체 Redis 래퍼를 쓰는 경우 `RedisUiStore`만 맞추면 됩니다.
211
+
212
+ ```ts
213
+ import type { RedisUiEntry, RedisUiStore } from 'redis-ui';
214
+
215
+ class MyStore implements RedisUiStore {
216
+ async keys(pattern = '*'): Promise<string[]> { /* ... */ }
217
+ async getEntry(key: string): Promise<RedisUiEntry> { /* ... */ }
218
+ async delete(key: string): Promise<void> { /* ... */ }
219
+ }
220
+
221
+ RedisUi.setup(app, {
222
+ enabled: true,
223
+ store: new MyStore(),
224
+ });
225
+ ```
226
+
227
+ ---
228
+
229
+ ## 로컬 개발 (이 레포)
230
+
231
+ ```bash
232
+ npm install
233
+ npm run start:dev
234
+ ```
235
+
236
+ 기본 접속: `http://localhost:3000/redis-ui`
237
+
238
+ 환경변수 예시:
239
+
240
+ ```env
241
+ PORT=3000
242
+ REDIS_HOST=127.0.0.1
243
+ REDIS_PORT=6379
244
+ REDIS_PASSWORD=
245
+ REDIS_TLS=false
246
+ REDIS_UI_ENABLED=true
247
+ REDIS_UI_PATH=redis-ui
248
+ REDIS_UI_USER=admin
249
+ REDIS_UI_PASS=secret
250
+ ```
251
+
252
+ ---
253
+
254
+ ## License
255
+
256
+ MIT
@@ -0,0 +1,2 @@
1
+ export declare const REDIS_MODULE_OPTIONS: unique symbol;
2
+ export declare const REDIS_CLIENT: unique symbol;
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.REDIS_CLIENT = exports.REDIS_MODULE_OPTIONS = void 0;
4
+ exports.REDIS_MODULE_OPTIONS = Symbol('REDIS_MODULE_OPTIONS');
5
+ exports.REDIS_CLIENT = Symbol('REDIS_CLIENT');
6
+ //# sourceMappingURL=redis.constants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redis.constants.js","sourceRoot":"","sources":["../../../src/redis/constants/redis.constants.ts"],"names":[],"mappings":";;;AAAa,QAAA,oBAAoB,GAAG,MAAM,CAAC,sBAAsB,CAAC,CAAC;AACtD,QAAA,YAAY,GAAG,MAAM,CAAC,cAAc,CAAC,CAAC"}
@@ -0,0 +1,6 @@
1
+ export { REDIS_CLIENT, REDIS_MODULE_OPTIONS, } from './constants/redis.constants';
2
+ export type { RedisModuleAsyncOptions, RedisModuleOptions, RedisOptionsFactory, RedisUiAuthOptions, RedisUiEntry, RedisUiOptions, RedisUiStore, ResolvedRedisUiOptions, } from './interfaces';
3
+ export { RedisModule } from './redis.module';
4
+ export { RedisService } from './services/redis.service';
5
+ export { RedisUi } from './ui/redis-ui';
6
+ export { REDIS_UI_DEFAULTS } from './ui/resolve-redis-ui-options';
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.REDIS_UI_DEFAULTS = exports.RedisUi = exports.RedisService = exports.RedisModule = exports.REDIS_MODULE_OPTIONS = exports.REDIS_CLIENT = void 0;
4
+ var redis_constants_1 = require("./constants/redis.constants");
5
+ Object.defineProperty(exports, "REDIS_CLIENT", { enumerable: true, get: function () { return redis_constants_1.REDIS_CLIENT; } });
6
+ Object.defineProperty(exports, "REDIS_MODULE_OPTIONS", { enumerable: true, get: function () { return redis_constants_1.REDIS_MODULE_OPTIONS; } });
7
+ var redis_module_1 = require("./redis.module");
8
+ Object.defineProperty(exports, "RedisModule", { enumerable: true, get: function () { return redis_module_1.RedisModule; } });
9
+ var redis_service_1 = require("./services/redis.service");
10
+ Object.defineProperty(exports, "RedisService", { enumerable: true, get: function () { return redis_service_1.RedisService; } });
11
+ var redis_ui_1 = require("./ui/redis-ui");
12
+ Object.defineProperty(exports, "RedisUi", { enumerable: true, get: function () { return redis_ui_1.RedisUi; } });
13
+ var resolve_redis_ui_options_1 = require("./ui/resolve-redis-ui-options");
14
+ Object.defineProperty(exports, "REDIS_UI_DEFAULTS", { enumerable: true, get: function () { return resolve_redis_ui_options_1.REDIS_UI_DEFAULTS; } });
15
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/redis/index.ts"],"names":[],"mappings":";;;AAAA,+DAGqC;AAFnC,+GAAA,YAAY,OAAA;AACZ,uHAAA,oBAAoB,OAAA;AAYtB,+CAA6C;AAApC,2GAAA,WAAW,OAAA;AACpB,0DAAwD;AAA/C,6GAAA,YAAY,OAAA;AACrB,0CAAwC;AAA/B,mGAAA,OAAO,OAAA;AAChB,0EAAkE;AAAzD,6HAAA,iBAAiB,OAAA"}
@@ -0,0 +1,3 @@
1
+ export type { RedisModuleAsyncOptions, RedisModuleOptions, RedisOptionsFactory, } from './redis-module-options.interface';
2
+ export type { RedisUiAuthOptions, RedisUiOptions, ResolvedRedisUiOptions, } from './redis-ui-options.interface';
3
+ export type { RedisUiEntry, RedisUiStore } from './redis-ui-store.interface';
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/redis/interfaces/index.ts"],"names":[],"mappings":""}
@@ -0,0 +1,20 @@
1
+ import type { InjectionToken, ModuleMetadata, OptionalFactoryDependency, Type } from '@nestjs/common';
2
+ import type { ConnectionOptions } from 'tls';
3
+ export interface RedisModuleOptions {
4
+ host?: string;
5
+ port?: number;
6
+ password?: string;
7
+ db?: number;
8
+ keyPrefix?: string;
9
+ tls?: boolean | ConnectionOptions;
10
+ redisOptions?: Record<string, any>;
11
+ }
12
+ export interface RedisOptionsFactory {
13
+ createRedisOptions(): Promise<RedisModuleOptions> | RedisModuleOptions;
14
+ }
15
+ export interface RedisModuleAsyncOptions extends Pick<ModuleMetadata, 'imports'> {
16
+ useExisting?: Type<RedisOptionsFactory>;
17
+ useClass?: Type<RedisOptionsFactory>;
18
+ useFactory?: (...args: any[]) => Promise<RedisModuleOptions> | RedisModuleOptions;
19
+ inject?: Array<InjectionToken | OptionalFactoryDependency>;
20
+ }
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=redis-module-options.interface.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redis-module-options.interface.js","sourceRoot":"","sources":["../../../src/redis/interfaces/redis-module-options.interface.ts"],"names":[],"mappings":""}
@@ -0,0 +1,18 @@
1
+ import type { RedisUiStore } from './redis-ui-store.interface';
2
+ export interface RedisUiAuthOptions {
3
+ username: string;
4
+ password: string;
5
+ }
6
+ export interface RedisUiOptions {
7
+ enabled: boolean;
8
+ store: RedisUiStore;
9
+ path?: string;
10
+ title?: string;
11
+ badge?: string;
12
+ defaultPattern?: string;
13
+ allowDelete?: boolean;
14
+ auth?: RedisUiAuthOptions | false;
15
+ }
16
+ export type ResolvedRedisUiOptions = Required<Omit<RedisUiOptions, 'auth'>> & {
17
+ auth: RedisUiAuthOptions | false;
18
+ };
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=redis-ui-options.interface.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redis-ui-options.interface.js","sourceRoot":"","sources":["../../../src/redis/interfaces/redis-ui-options.interface.ts"],"names":[],"mappings":""}
@@ -0,0 +1,11 @@
1
+ export type RedisUiEntry = {
2
+ key: string;
3
+ value: unknown;
4
+ ttl: number;
5
+ type: string;
6
+ };
7
+ export interface RedisUiStore {
8
+ keys(pattern?: string): Promise<string[]>;
9
+ getEntry(key: string): Promise<RedisUiEntry>;
10
+ delete(key: string): Promise<void>;
11
+ }
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=redis-ui-store.interface.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redis-ui-store.interface.js","sourceRoot":"","sources":["../../../src/redis/interfaces/redis-ui-store.interface.ts"],"names":[],"mappings":""}
@@ -0,0 +1,4 @@
1
+ import type { Provider } from '@nestjs/common';
2
+ import type { RedisModuleAsyncOptions } from '../interfaces/redis-module-options.interface';
3
+ export declare function createRedisClientProvider(): Provider;
4
+ export declare function createAsyncProviders(options: RedisModuleAsyncOptions): Provider[];
@@ -0,0 +1,60 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.createRedisClientProvider = createRedisClientProvider;
7
+ exports.createAsyncProviders = createAsyncProviders;
8
+ const ioredis_1 = __importDefault(require("ioredis"));
9
+ const redis_constants_1 = require("../constants/redis.constants");
10
+ function createRedisClient(options) {
11
+ const { host = '127.0.0.1', port = 6379, password, db = 0, keyPrefix, tls, redisOptions, } = options;
12
+ return new ioredis_1.default({
13
+ host,
14
+ port,
15
+ password,
16
+ db,
17
+ keyPrefix,
18
+ ...(tls ? { tls: tls === true ? {} : tls } : {}),
19
+ ...redisOptions,
20
+ });
21
+ }
22
+ function createRedisClientProvider() {
23
+ return {
24
+ provide: redis_constants_1.REDIS_CLIENT,
25
+ inject: [redis_constants_1.REDIS_MODULE_OPTIONS],
26
+ useFactory: (options) => createRedisClient(options),
27
+ };
28
+ }
29
+ function createAsyncProviders(options) {
30
+ if (options.useFactory) {
31
+ return [
32
+ {
33
+ provide: redis_constants_1.REDIS_MODULE_OPTIONS,
34
+ useFactory: options.useFactory,
35
+ inject: options.inject ?? [],
36
+ },
37
+ createRedisClientProvider(),
38
+ ];
39
+ }
40
+ const injectTarget = options.useExisting ?? options.useClass;
41
+ if (!injectTarget) {
42
+ throw new Error('Invalid RedisModuleAsyncOptions: provide useFactory, useClass, or useExisting');
43
+ }
44
+ const providers = [
45
+ {
46
+ provide: redis_constants_1.REDIS_MODULE_OPTIONS,
47
+ useFactory: async (factory) => factory.createRedisOptions(),
48
+ inject: [injectTarget],
49
+ },
50
+ createRedisClientProvider(),
51
+ ];
52
+ if (options.useClass) {
53
+ providers.push({
54
+ provide: options.useClass,
55
+ useClass: options.useClass,
56
+ });
57
+ }
58
+ return providers;
59
+ }
60
+ //# sourceMappingURL=redis.providers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redis.providers.js","sourceRoot":"","sources":["../../../src/redis/providers/redis.providers.ts"],"names":[],"mappings":";;;;;AAkCA,8DAMC;AAED,oDAuCC;AAhFD,sDAA4B;AAC5B,kEAGsC;AAOtC,SAAS,iBAAiB,CAAC,OAA2B;IACpD,MAAM,EACJ,IAAI,GAAG,WAAW,EAClB,IAAI,GAAG,IAAI,EACX,QAAQ,EACR,EAAE,GAAG,CAAC,EACN,SAAS,EACT,GAAG,EACH,YAAY,GACb,GAAG,OAAO,CAAC;IAEZ,OAAO,IAAI,iBAAK,CAAC;QACf,IAAI;QACJ,IAAI;QACJ,QAAQ;QACR,EAAE;QACF,SAAS;QACT,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAChD,GAAG,YAAY;KAChB,CAAC,CAAC;AACL,CAAC;AAED,SAAgB,yBAAyB;IACvC,OAAO;QACL,OAAO,EAAE,8BAAY;QACrB,MAAM,EAAE,CAAC,sCAAoB,CAAC;QAC9B,UAAU,EAAE,CAAC,OAA2B,EAAE,EAAE,CAAC,iBAAiB,CAAC,OAAO,CAAC;KACxE,CAAC;AACJ,CAAC;AAED,SAAgB,oBAAoB,CAClC,OAAgC;IAEhC,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC;QACvB,OAAO;YACL;gBACE,OAAO,EAAE,sCAAoB;gBAC7B,UAAU,EAAE,OAAO,CAAC,UAAU;gBAC9B,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,EAAE;aAC7B;YACD,yBAAyB,EAAE;SAC5B,CAAC;IACJ,CAAC;IAED,MAAM,YAAY,GAAG,OAAO,CAAC,WAAW,IAAI,OAAO,CAAC,QAAQ,CAAC;IAC7D,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,MAAM,IAAI,KAAK,CACb,+EAA+E,CAChF,CAAC;IACJ,CAAC;IAED,MAAM,SAAS,GAAe;QAC5B;YACE,OAAO,EAAE,sCAAoB;YAC7B,UAAU,EAAE,KAAK,EAAE,OAA4B,EAAE,EAAE,CACjD,OAAO,CAAC,kBAAkB,EAAE;YAC9B,MAAM,EAAE,CAAC,YAAY,CAAC;SACvB;QACD,yBAAyB,EAAE;KAC5B,CAAC;IAEF,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;QACrB,SAAS,CAAC,IAAI,CAAC;YACb,OAAO,EAAE,OAAO,CAAC,QAAQ;YACzB,QAAQ,EAAE,OAAO,CAAC,QAAQ;SAC3B,CAAC,CAAC;IACL,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC"}
@@ -0,0 +1,6 @@
1
+ import { DynamicModule } from '@nestjs/common';
2
+ import type { RedisModuleAsyncOptions, RedisModuleOptions } from './interfaces';
3
+ export declare class RedisModule {
4
+ static forRoot(options?: RedisModuleOptions): DynamicModule;
5
+ static forRootAsync(options: RedisModuleAsyncOptions): DynamicModule;
6
+ }
@@ -0,0 +1,49 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var RedisModule_1;
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.RedisModule = void 0;
11
+ const common_1 = require("@nestjs/common");
12
+ const redis_constants_1 = require("./constants/redis.constants");
13
+ const redis_providers_1 = require("./providers/redis.providers");
14
+ const redis_service_1 = require("./services/redis.service");
15
+ let RedisModule = RedisModule_1 = class RedisModule {
16
+ static forRoot(options = {}) {
17
+ const providers = [
18
+ {
19
+ provide: redis_constants_1.REDIS_MODULE_OPTIONS,
20
+ useValue: options,
21
+ },
22
+ (0, redis_providers_1.createRedisClientProvider)(),
23
+ redis_service_1.RedisService,
24
+ ];
25
+ return {
26
+ module: RedisModule_1,
27
+ providers,
28
+ exports: [redis_service_1.RedisService, redis_constants_1.REDIS_CLIENT],
29
+ };
30
+ }
31
+ static forRootAsync(options) {
32
+ const providers = [
33
+ ...(0, redis_providers_1.createAsyncProviders)(options),
34
+ redis_service_1.RedisService,
35
+ ];
36
+ return {
37
+ module: RedisModule_1,
38
+ imports: options.imports ?? [],
39
+ providers,
40
+ exports: [redis_service_1.RedisService, redis_constants_1.REDIS_CLIENT],
41
+ };
42
+ }
43
+ };
44
+ exports.RedisModule = RedisModule;
45
+ exports.RedisModule = RedisModule = RedisModule_1 = __decorate([
46
+ (0, common_1.Global)(),
47
+ (0, common_1.Module)({})
48
+ ], RedisModule);
49
+ //# sourceMappingURL=redis.module.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redis.module.js","sourceRoot":"","sources":["../../src/redis/redis.module.ts"],"names":[],"mappings":";;;;;;;;;;AAAA,2CAAyE;AACzE,iEAGqC;AAErC,iEAGqC;AACrC,4DAAwD;AAIjD,IAAM,WAAW,mBAAjB,MAAM,WAAW;IACtB,MAAM,CAAC,OAAO,CAAC,UAA8B,EAAE;QAC7C,MAAM,SAAS,GAAe;YAC5B;gBACE,OAAO,EAAE,sCAAoB;gBAC7B,QAAQ,EAAE,OAAO;aAClB;YACD,IAAA,2CAAyB,GAAE;YAC3B,4BAAY;SACb,CAAC;QAEF,OAAO;YACL,MAAM,EAAE,aAAW;YACnB,SAAS;YACT,OAAO,EAAE,CAAC,4BAAY,EAAE,8BAAY,CAAC;SACtC,CAAC;IACJ,CAAC;IAED,MAAM,CAAC,YAAY,CAAC,OAAgC;QAClD,MAAM,SAAS,GAAe;YAC5B,GAAG,IAAA,sCAAoB,EAAC,OAAO,CAAC;YAChC,4BAAY;SACb,CAAC;QAEF,OAAO;YACL,MAAM,EAAE,aAAW;YACnB,OAAO,EAAE,OAAO,CAAC,OAAO,IAAI,EAAE;YAC9B,SAAS;YACT,OAAO,EAAE,CAAC,4BAAY,EAAE,8BAAY,CAAC;SACtC,CAAC;IACJ,CAAC;CACF,CAAA;AA/BY,kCAAW;sBAAX,WAAW;IAFvB,IAAA,eAAM,GAAE;IACR,IAAA,eAAM,EAAC,EAAE,CAAC;GACE,WAAW,CA+BvB"}
@@ -0,0 +1,15 @@
1
+ import { OnModuleDestroy } from '@nestjs/common';
2
+ import Redis from 'ioredis';
3
+ import type { RedisUiEntry, RedisUiStore } from '../interfaces';
4
+ export declare class RedisService implements RedisUiStore, OnModuleDestroy {
5
+ private readonly client;
6
+ constructor(client: Redis);
7
+ onModuleDestroy(): Promise<void>;
8
+ getClient(): Redis;
9
+ get<T = unknown>(key: string): Promise<T | null>;
10
+ set(key: string, value: unknown, ttlSeconds?: number): Promise<void>;
11
+ delete(key: string): Promise<void>;
12
+ keys(pattern?: string): Promise<string[]>;
13
+ ttl(key: string): Promise<number>;
14
+ getEntry(key: string): Promise<RedisUiEntry>;
15
+ }
@@ -0,0 +1,83 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
12
+ return function (target, key) { decorator(target, key, paramIndex); }
13
+ };
14
+ var __importDefault = (this && this.__importDefault) || function (mod) {
15
+ return (mod && mod.__esModule) ? mod : { "default": mod };
16
+ };
17
+ Object.defineProperty(exports, "__esModule", { value: true });
18
+ exports.RedisService = void 0;
19
+ const common_1 = require("@nestjs/common");
20
+ const ioredis_1 = __importDefault(require("ioredis"));
21
+ const redis_constants_1 = require("../constants/redis.constants");
22
+ let RedisService = class RedisService {
23
+ client;
24
+ constructor(client) {
25
+ this.client = client;
26
+ }
27
+ async onModuleDestroy() {
28
+ await this.client.quit();
29
+ }
30
+ getClient() {
31
+ return this.client;
32
+ }
33
+ async get(key) {
34
+ const value = await this.client.get(key);
35
+ if (value === null)
36
+ return null;
37
+ try {
38
+ return JSON.parse(value);
39
+ }
40
+ catch {
41
+ return value;
42
+ }
43
+ }
44
+ async set(key, value, ttlSeconds) {
45
+ const payload = typeof value === 'string' ? value : JSON.stringify(value);
46
+ if (ttlSeconds && ttlSeconds > 0) {
47
+ await this.client.set(key, payload, 'EX', ttlSeconds);
48
+ return;
49
+ }
50
+ await this.client.set(key, payload);
51
+ }
52
+ async delete(key) {
53
+ await this.client.del(key);
54
+ }
55
+ async keys(pattern = '*') {
56
+ const result = [];
57
+ let cursor = '0';
58
+ do {
59
+ const [nextCursor, batch] = await this.client.scan(cursor, 'MATCH', pattern, 'COUNT', 100);
60
+ cursor = nextCursor;
61
+ result.push(...batch);
62
+ } while (cursor !== '0');
63
+ return result;
64
+ }
65
+ ttl(key) {
66
+ return this.client.ttl(key);
67
+ }
68
+ async getEntry(key) {
69
+ const [value, ttl, type] = await Promise.all([
70
+ this.get(key),
71
+ this.ttl(key),
72
+ this.client.type(key),
73
+ ]);
74
+ return { key, value, ttl, type };
75
+ }
76
+ };
77
+ exports.RedisService = RedisService;
78
+ exports.RedisService = RedisService = __decorate([
79
+ (0, common_1.Injectable)(),
80
+ __param(0, (0, common_1.Inject)(redis_constants_1.REDIS_CLIENT)),
81
+ __metadata("design:paramtypes", [ioredis_1.default])
82
+ ], RedisService);
83
+ //# sourceMappingURL=redis.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redis.service.js","sourceRoot":"","sources":["../../../src/redis/services/redis.service.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;AAAA,2CAAqE;AACrE,sDAA4B;AAC5B,kEAA4D;AAIrD,IAAM,YAAY,GAAlB,MAAM,YAAY;IAC4B;IAAnD,YAAmD,MAAa;QAAb,WAAM,GAAN,MAAM,CAAO;IAAG,CAAC;IAEpE,KAAK,CAAC,eAAe;QACnB,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;IAC3B,CAAC;IAED,SAAS;QACP,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;IAED,KAAK,CAAC,GAAG,CAAc,GAAW;QAChC,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACzC,IAAI,KAAK,KAAK,IAAI;YAAE,OAAO,IAAI,CAAC;QAEhC,IAAI,CAAC;YACH,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,CAAM,CAAC;QAChC,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,KAAU,CAAC;QACpB,CAAC;IACH,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,GAAW,EAAE,KAAc,EAAE,UAAmB;QACxD,MAAM,OAAO,GAAG,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;QAE1E,IAAI,UAAU,IAAI,UAAU,GAAG,CAAC,EAAE,CAAC;YACjC,MAAM,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,UAAU,CAAC,CAAC;YACtD,OAAO;QACT,CAAC;QAED,MAAM,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IACtC,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,GAAW;QACtB,MAAM,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC7B,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,OAAO,GAAG,GAAG;QACtB,MAAM,MAAM,GAAa,EAAE,CAAC;QAC5B,IAAI,MAAM,GAAG,GAAG,CAAC;QAEjB,GAAG,CAAC;YACF,MAAM,CAAC,UAAU,EAAE,KAAK,CAAC,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,CAChD,MAAM,EACN,OAAO,EACP,OAAO,EACP,OAAO,EACP,GAAG,CACJ,CAAC;YACF,MAAM,GAAG,UAAU,CAAC;YACpB,MAAM,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,CAAC;QACxB,CAAC,QAAQ,MAAM,KAAK,GAAG,EAAE;QAEzB,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,GAAG,CAAC,GAAW;QACb,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC9B,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,GAAW;QACxB,MAAM,CAAC,KAAK,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;YAC3C,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;YACb,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;YACb,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC;SACtB,CAAC,CAAC;QAEH,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC;IACnC,CAAC;CACF,CAAA;AArEY,oCAAY;uBAAZ,YAAY;IADxB,IAAA,mBAAU,GAAE;IAEE,WAAA,IAAA,eAAM,EAAC,8BAAY,CAAC,CAAA;qCAA0B,iBAAK;GADrD,YAAY,CAqExB"}