redis-wizard 0.0.1 → 0.0.3

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 CHANGED
@@ -0,0 +1,227 @@
1
+ # Redis Wizard
2
+
3
+ Redis Wizard는 `redis` 라이브러리를 감싸서 간편한 데이터베이스 작업을 제공하는 TypeScript 기반 Redis 유틸리티 패키지입니다.
4
+
5
+ ## 주요 기능
6
+
7
+ - 🔑 **자동 키 프리픽스 관리**: 테이블/스코프 프리픽스를 자동으로 추가하여 키를 체계적으로 관리
8
+ - 🔄 **자동 직렬화/역직렬화**: 객체를 자동으로 JSON으로 변환하여 저장하고 읽을 때 자동 파싱
9
+ - ⏰ **만료 시간 관리**: 기본 만료 시간 설정 및 개별 키별 만료 시간 설정 지원
10
+ - 🛡️ **타입 안정성**: TypeScript 제네릭을 통한 완전한 타입 지원
11
+ - 🔌 **자동 연결 관리**: Redis 연결을 자동으로 초기화하고 관리
12
+ - 📦 **간단한 API**: 직관적이고 사용하기 쉬운 메서드 제공
13
+
14
+ ## 설치
15
+
16
+ ```bash
17
+ npm install redis-wizard
18
+ ```
19
+
20
+ ## 환경 변수 설정
21
+
22
+ Redis 연결을 위해 다음 환경 변수를 설정하세요:
23
+
24
+ ```bash
25
+ # Redis URL (필수)
26
+ REDIS_URL=redis://localhost:6379
27
+
28
+ # 또는 Redis 포트만 지정 (기본 호스트: localhost)
29
+ REDIS_PORT=6379
30
+
31
+ # 연결 풀 설정 (선택사항)
32
+ REDIS_CONNECT_TIMEOUT=10000
33
+ REDIS_KEEP_ALIVE=true
34
+ REDIS_KEEP_ALIVE_DELAY=0
35
+ REDIS_LAZY_CONNECT=false
36
+ REDIS_MAX_RETRIES=10
37
+ ```
38
+
39
+ ## 사용 예제
40
+
41
+ ### 기본 사용법
42
+
43
+ ```typescript
44
+ import { createRedis } from 'redis-wizard';
45
+
46
+ // 타입 정의
47
+ interface Application {
48
+ id: string;
49
+ title: string;
50
+ status: 'draft' | 'published';
51
+ createdAt: Date;
52
+ }
53
+
54
+ // Redis Wizard 인스턴스 생성
55
+ const redis = createRedis<Application>({
56
+ table: "draft:applications",
57
+ cacheExpired: 3600, // 기본 만료 시간: 1시간
58
+ });
59
+
60
+ // 데이터 생성
61
+ await redis.create("app-123", {
62
+ id: "app-123",
63
+ title: "My Application",
64
+ status: "draft",
65
+ createdAt: new Date(),
66
+ });
67
+
68
+ // 데이터 조회
69
+ const app = await redis.read("app-123");
70
+ console.log(app); // { id: "app-123", title: "My Application", ... }
71
+
72
+ // 데이터 부분 업데이트
73
+ const updated = await redis.update("app-123", {
74
+ status: "published"
75
+ });
76
+ console.log(updated); // 업데이트된 전체 객체
77
+
78
+ // 키 존재 여부 확인
79
+ const exists = await redis.exists("app-123");
80
+ console.log(exists); // true
81
+
82
+ // 만료 시간 설정
83
+ await redis.setExpire("app-123", 7200); // 2시간
84
+
85
+ // 남은 만료 시간 조회
86
+ const ttl = await redis.getTtl("app-123");
87
+ console.log(ttl); // 남은 초 수 (예: 3600)
88
+
89
+ // 데이터 삭제
90
+ await redis.delete("app-123");
91
+ ```
92
+
93
+ ### 개별 만료 시간 설정
94
+
95
+ ```typescript
96
+ // create 시 만료 시간 지정
97
+ await redis.create("app-456", appData, 1800); // 30분
98
+
99
+ // update 시 만료 시간 지정
100
+ await redis.update("app-456", { status: "published" }, 3600); // 1시간
101
+ ```
102
+
103
+ ### 연결 관리
104
+
105
+ ```typescript
106
+ import { disconnect, getRedisClient } from 'redis-wizard';
107
+
108
+ // Redis 클라이언트 직접 접근 (필요한 경우)
109
+ const client = await getRedisClient();
110
+
111
+ // 연결 종료
112
+ await disconnect();
113
+ ```
114
+
115
+ ## API 문서
116
+
117
+ ### `createRedis<T>(config: RedisWizardConfig): RedisWizard<T>`
118
+
119
+ Redis Wizard 인스턴스를 생성합니다.
120
+
121
+ **파라미터:**
122
+ - `config.table` (string, 필수): 테이블/스코프 프리픽스 (예: "draft:applications")
123
+ - `config.cacheExpired` (number, 선택): 기본 캐시 만료 시간(초)
124
+
125
+ **반환값:** RedisWizard 인스턴스
126
+
127
+ ### `read(key: string): Promise<T | null>`
128
+
129
+ 키에 해당하는 값을 조회합니다.
130
+
131
+ **파라미터:**
132
+ - `key` (string): 조회할 키 (table 프리픽스는 자동 추가)
133
+
134
+ **반환값:** 값이 존재하면 파싱된 객체, 없으면 `null`
135
+
136
+ ### `create(key: string, value: T, expireSeconds?: number): Promise<void>`
137
+
138
+ 키-값 쌍을 저장합니다.
139
+
140
+ **파라미터:**
141
+ - `key` (string): 저장할 키 (table 프리픽스는 자동 추가)
142
+ - `value` (T): 저장할 값 (객체는 자동 직렬화)
143
+ - `expireSeconds` (number, 선택): 만료 시간(초), 지정하지 않으면 `config.cacheExpired` 사용
144
+
145
+ ### `update(key: string, partial: Partial<T>, expireSeconds?: number): Promise<T | null>`
146
+
147
+ 키의 값을 부분 업데이트합니다.
148
+
149
+ **파라미터:**
150
+ - `key` (string): 업데이트할 키 (table 프리픽스는 자동 추가)
151
+ - `partial` (Partial<T>): 업데이트할 부분 값
152
+ - `expireSeconds` (number, 선택): 만료 시간(초), 지정하지 않으면 `config.cacheExpired` 사용
153
+
154
+ **반환값:** 업데이트된 값, 키가 존재하지 않으면 `null`
155
+
156
+ ### `delete(key: string): Promise<boolean>`
157
+
158
+ 키를 삭제합니다.
159
+
160
+ **파라미터:**
161
+ - `key` (string): 삭제할 키 (table 프리픽스는 자동 추가)
162
+
163
+ **반환값:** 삭제 성공 여부
164
+
165
+ ### `exists(key: string): Promise<boolean>`
166
+
167
+ 키의 존재 여부를 확인합니다.
168
+
169
+ **파라미터:**
170
+ - `key` (string): 확인할 키 (table 프리픽스는 자동 추가)
171
+
172
+ **반환값:** 키가 존재하면 `true`
173
+
174
+ ### `setExpire(key: string, seconds?: number): Promise<boolean>`
175
+
176
+ 키의 만료 시간을 설정합니다.
177
+
178
+ **파라미터:**
179
+ - `key` (string): 만료 시간을 설정할 키 (table 프리픽스는 자동 추가)
180
+ - `seconds` (number, 선택): 만료 시간(초), 지정하지 않으면 `config.cacheExpired` 사용
181
+
182
+ **반환값:** 설정 성공 여부
183
+
184
+ ### `getTtl(key: string): Promise<number | null>`
185
+
186
+ 키의 남은 만료 시간을 조회합니다.
187
+
188
+ **파라미터:**
189
+ - `key` (string): 조회할 키 (table 프리픽스는 자동 추가)
190
+
191
+ **반환값:** 남은 만료 시간(초), 만료 시간이 없으면 `null`
192
+
193
+ ## 키 네이밍 규칙
194
+
195
+ Redis Wizard는 자동으로 키에 프리픽스를 추가합니다:
196
+
197
+ ```typescript
198
+ const redis = createRedis({
199
+ table: "draft:applications"
200
+ });
201
+
202
+ // "app-123" 키는 실제로 "draft:applications:app-123"로 저장됩니다
203
+ await redis.create("app-123", data);
204
+ ```
205
+
206
+ 이를 통해 여러 테이블/스코프를 체계적으로 관리할 수 있습니다.
207
+
208
+ ## 개발
209
+
210
+ ```bash
211
+ # 개발 모드 실행
212
+ npm run dev
213
+
214
+ # 빌드
215
+ npm run build
216
+
217
+ # 배포 (빌드 + 버전 업데이트 + 패키지 설정)
218
+ npm run deploy
219
+ ```
220
+
221
+ ## 라이선스
222
+
223
+ MIT
224
+
225
+ ## 작성자
226
+
227
+ park-minhyeong
package/index.d.ts CHANGED
@@ -10,7 +10,7 @@ export interface RedisWizardConfig {
10
10
  /**
11
11
  * Redis Wizard 인스턴스 인터페이스
12
12
  */
13
- export interface RedisWizard<T = any> {
13
+ export interface RedisWizard<T = any, AutoSetKeys extends keyof T = never> {
14
14
  /**
15
15
  * 키에 해당하는 값을 조회합니다.
16
16
  * @param key - 조회할 키 (table 프리픽스는 자동 추가)
@@ -20,10 +20,10 @@ export interface RedisWizard<T = any> {
20
20
  /**
21
21
  * 키-값 쌍을 저장합니다.
22
22
  * @param key - 저장할 키 (table 프리픽스는 자동 추가)
23
- * @param value - 저장할 값 (객체는 자동 직렬화)
23
+ * @param value - 저장할 값 (객체는 자동 직렬화, AutoSetKeys는 제외됨)
24
24
  * @param expireSeconds - 만료 시간(초), 지정하지 않으면 config.cacheExpired 사용
25
25
  */
26
- create(key: string, value: T, expireSeconds?: number): Promise<void>;
26
+ create(key: string, value: Omit<T, AutoSetKeys>, expireSeconds?: number): Promise<void>;
27
27
  /**
28
28
  * 키의 값을 부분 업데이트합니다.
29
29
  * @param key - 업데이트할 키 (table 프리픽스는 자동 추가)
@@ -69,12 +69,19 @@ export interface RedisWizard<T = any> {
69
69
  * status: 'draft' | 'published';
70
70
  * }
71
71
  *
72
+ * // AutoSetKeys 없이 사용
72
73
  * const redis = createRedis<Application>({
73
74
  * table: "draft:applications",
74
75
  * cacheExpired: 10000,
75
76
  * });
76
77
  *
77
- * await redis.create("app-123", { id: "app-123", title: "My App", status: "draft" });
78
+ * // AutoSetKeys 지정 (id 자동 설정되므로 create에서 제외)
79
+ * const redis = createRedis<Application, "id">({
80
+ * table: "draft:applications",
81
+ * cacheExpired: 10000,
82
+ * });
83
+ *
84
+ * await redis.create("app-123", { title: "My App", status: "draft" }); // id 제외
78
85
  * const app = await redis.read("app-123");
79
86
  * await redis.update("app-123", { status: "published" });
80
87
  * await redis.delete("app-123");
@@ -83,6 +90,6 @@ export interface RedisWizard<T = any> {
83
90
  * @param config - Redis Wizard 설정
84
91
  * @returns Redis Wizard 인스턴스
85
92
  */
86
- export declare function createRedis<T = any>(config: RedisWizardConfig): RedisWizard<T>;
93
+ export declare function createRedis<T = any, AutoSetKeys extends keyof T = never>(config: RedisWizardConfig): RedisWizard<T, AutoSetKeys>;
87
94
  export { disconnect } from "./services/config";
88
95
  export { getRedisClient } from "./services/config";
package/index.js CHANGED
@@ -20,12 +20,19 @@ const getTtl_1 = require("./services/getTtl");
20
20
  * status: 'draft' | 'published';
21
21
  * }
22
22
  *
23
+ * // AutoSetKeys 없이 사용
23
24
  * const redis = createRedis<Application>({
24
25
  * table: "draft:applications",
25
26
  * cacheExpired: 10000,
26
27
  * });
27
28
  *
28
- * await redis.create("app-123", { id: "app-123", title: "My App", status: "draft" });
29
+ * // AutoSetKeys 지정 (id 자동 설정되므로 create에서 제외)
30
+ * const redis = createRedis<Application, "id">({
31
+ * table: "draft:applications",
32
+ * cacheExpired: 10000,
33
+ * });
34
+ *
35
+ * await redis.create("app-123", { title: "My App", status: "draft" }); // id 제외
29
36
  * const app = await redis.read("app-123");
30
37
  * await redis.update("app-123", { status: "published" });
31
38
  * await redis.delete("app-123");
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "redis-wizard",
3
3
  "description": "A modern TypeScript-based Redis database utility package that provides an enhanced wrapper around the redis library, offering simplified database operations with elegant chainable queries.",
4
- "version": "0.0.1",
4
+ "version": "0.0.3",
5
5
  "main": "index.js",
6
6
  "scripts": {},
7
7
  "author": "park-minhyeong",
@@ -48,11 +48,11 @@ const initializeRedis = async (poolConfig) => {
48
48
  const redisUrl = process.env.REDIS_PORT ? `redis://localhost:${process.env.REDIS_PORT}` : process.env.REDIS_URL;
49
49
  if (!redisUrl) {
50
50
  const error = new Error("Redis configuration error: REDIS_URL or REDIS_PORT environment variable is not set");
51
- console.error("[Redis Config] Initialization failed:", error.message);
51
+ console.error("[Redis Wizard] Initialization failed:", error.message);
52
52
  throw error;
53
53
  }
54
54
  if (redisClient && isConnected) {
55
- console.log("[Redis Config] Client already connected, skipping initialization");
55
+ console.log("[Redis Wizard] Client already connected, skipping initialization");
56
56
  return;
57
57
  }
58
58
  // 환경 변수에서 연결 풀 설정 읽기
@@ -93,7 +93,7 @@ const initializeRedis = async (poolConfig) => {
93
93
  ...(finalPoolConfig.lazyConnect !== undefined && { lazyConnect: finalPoolConfig.lazyConnect }),
94
94
  ...(finalPoolConfig.maxRetriesPerRequest !== undefined && { maxRetriesPerRequest: finalPoolConfig.maxRetriesPerRequest }),
95
95
  };
96
- console.log(`[Redis Config] Initializing Redis client with URL: ${redisUrl.replace(/:[^:@]+@/, ":****@")}`, {
96
+ console.log(`[Redis Wizard] Initializing Redis client with URL: ${redisUrl.replace(/:[^:@]+@/, ":****@")}`, {
97
97
  poolConfig: {
98
98
  connectTimeout: finalPoolConfig.connectTimeout,
99
99
  keepAlive: finalPoolConfig.keepAlive,
@@ -104,7 +104,7 @@ const initializeRedis = async (poolConfig) => {
104
104
  });
105
105
  redisClient = (0, redis_1.createClient)(clientOptions);
106
106
  redisClient.on("error", (err) => {
107
- console.error("[Redis Config] Connection error occurred:", {
107
+ console.error("[Redis Wizard] Connection error occurred:", {
108
108
  message: err.message,
109
109
  stack: err.stack,
110
110
  timestamp: new Date().toISOString(),
@@ -112,34 +112,31 @@ const initializeRedis = async (poolConfig) => {
112
112
  isConnected = false;
113
113
  });
114
114
  redisClient.on("connect", () => {
115
- console.log("[Redis Config] Connecting to Redis server...");
115
+ console.log("[Redis Wizard] Connecting to Redis server...");
116
116
  });
117
117
  redisClient.on("ready", () => {
118
- console.log("[Redis Config] Redis client connected and ready", {
119
- url: redisUrl.replace(/:[^:@]+@/, ":****@"),
120
- timestamp: new Date().toISOString(),
121
- });
118
+ console.log("[Redis Wizard] Redis client connected and ready at url: " + redisUrl);
122
119
  isConnected = true;
123
120
  });
124
121
  redisClient.on("reconnecting", () => {
125
- console.warn("[Redis Config] Attempting to reconnect to Redis server...", {
122
+ console.warn("[Redis Wizard] Attempting to reconnect to Redis server...", {
126
123
  timestamp: new Date().toISOString(),
127
124
  });
128
125
  isConnected = false;
129
126
  });
130
127
  redisClient.on("end", () => {
131
- console.log("[Redis Config] Redis connection ended", {
128
+ console.log("[Redis Wizard] Redis connection ended", {
132
129
  timestamp: new Date().toISOString(),
133
130
  });
134
131
  isConnected = false;
135
132
  });
136
133
  try {
137
- console.log("[Redis Config] Establishing connection...");
134
+ console.log("[Redis Wizard] Establishing connection...");
138
135
  await redisClient.connect();
139
136
  }
140
137
  catch (error) {
141
138
  const errorMessage = error instanceof Error ? error.message : String(error);
142
- console.error("[Redis Config] Failed to connect to Redis:", {
139
+ console.error("[Redis Wizard] Failed to connect to Redis:", {
143
140
  message: errorMessage,
144
141
  url: redisUrl.replace(/:[^:@]+@/, ":****@"),
145
142
  timestamp: new Date().toISOString(),
@@ -157,12 +154,12 @@ const initializeRedis = async (poolConfig) => {
157
154
  */
158
155
  const getRedisClient = async (poolConfig) => {
159
156
  if (!redisClient || !isConnected) {
160
- console.log("[Redis Config] Client not available, initializing...");
157
+ console.log("[Redis Wizard] Client not available, initializing...");
161
158
  await initializeRedis(poolConfig);
162
159
  }
163
160
  if (!redisClient) {
164
161
  const error = new Error("Redis client initialization failed: client is null after initialization attempt");
165
- console.error("[Redis Config]", error.message);
162
+ console.error("[Redis Wizard]", error.message);
166
163
  throw error;
167
164
  }
168
165
  return redisClient;
@@ -177,7 +174,7 @@ exports.getRedisClient = getRedisClient;
177
174
  */
178
175
  const configurePool = async (poolConfig) => {
179
176
  if (redisClient && isConnected) {
180
- console.warn("[Redis Config] Pool configuration change requires reconnection. Disconnecting current client...");
177
+ console.warn("[Redis Wizard] Pool configuration change requires reconnection. Disconnecting current client...");
181
178
  await (0, exports.disconnect)();
182
179
  }
183
180
  await initializeRedis(poolConfig);
@@ -190,15 +187,15 @@ exports.configurePool = configurePool;
190
187
  */
191
188
  const disconnect = async () => {
192
189
  if (redisClient && isConnected) {
193
- console.log("[Redis Config] Disconnecting Redis client...");
190
+ console.log("[Redis Wizard] Disconnecting Redis client...");
194
191
  try {
195
192
  await redisClient.quit();
196
- console.log("[Redis Config] Redis client disconnected successfully", {
193
+ console.log("[Redis Wizard] Redis client disconnected successfully", {
197
194
  timestamp: new Date().toISOString(),
198
195
  });
199
196
  }
200
197
  catch (error) {
201
- console.error("[Redis Config] Error during disconnection:", {
198
+ console.error("[Redis Wizard] Error during disconnection:", {
202
199
  message: error instanceof Error ? error.message : String(error),
203
200
  timestamp: new Date().toISOString(),
204
201
  });
@@ -208,13 +205,13 @@ const disconnect = async () => {
208
205
  redisClient = null;
209
206
  }
210
207
  else {
211
- console.log("[Redis Config] No active connection to disconnect");
208
+ console.log("[Redis Wizard] No active connection to disconnect");
212
209
  }
213
210
  };
214
211
  exports.disconnect = disconnect;
215
212
  // 애플리케이션 시작 시 Redis 연결 초기화
216
213
  initializeRedis().catch((error) => {
217
- console.error("[Redis Config] Failed to initialize Redis on application startup:", {
214
+ console.error("[Redis Wizard] Failed to initialize Redis on application startup:", {
218
215
  message: error instanceof Error ? error.message : String(error),
219
216
  stack: error instanceof Error ? error.stack : undefined,
220
217
  timestamp: new Date().toISOString(),
package/version.txt CHANGED
@@ -1 +1 @@
1
- 0.0.1
1
+ 0.0.3