@vritti/api-sdk 0.2.9 → 0.3.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.
- package/dist/cache.cjs +252 -0
- package/dist/cache.cjs.map +1 -0
- package/dist/cache.d.cts +25 -0
- package/dist/cache.d.ts +25 -0
- package/dist/cache.js +214 -0
- package/dist/cache.js.map +1 -0
- package/dist/cache.service-_SuJIcNA.d.cts +20 -0
- package/dist/cache.service-_SuJIcNA.d.ts +20 -0
- package/dist/catalog-resolver.cjs +364 -0
- package/dist/catalog-resolver.cjs.map +1 -0
- package/dist/catalog-resolver.d.cts +109 -0
- package/dist/catalog-resolver.d.ts +109 -0
- package/dist/catalog-resolver.js +330 -0
- package/dist/catalog-resolver.js.map +1 -0
- package/dist/email.cjs +691 -0
- package/dist/email.cjs.map +1 -0
- package/dist/email.d.cts +35 -0
- package/dist/email.d.ts +35 -0
- package/dist/email.js +665 -0
- package/dist/email.js.map +1 -0
- package/dist/fastify-augmentation-CQPBNS5a.d.cts +105 -0
- package/dist/fastify-augmentation-CQPBNS5a.d.ts +105 -0
- package/dist/icons.cjs +13803 -0
- package/dist/icons.cjs.map +1 -0
- package/dist/icons.d.cts +8 -0
- package/dist/icons.d.ts +8 -0
- package/dist/icons.js +13778 -0
- package/dist/icons.js.map +1 -0
- package/dist/index.cjs +750 -1368
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +103 -181
- package/dist/index.d.ts +103 -181
- package/dist/index.js +609 -1234
- package/dist/index.js.map +1 -1
- package/dist/license.cjs +104 -0
- package/dist/license.cjs.map +1 -0
- package/dist/license.d.cts +32 -0
- package/dist/license.d.ts +32 -0
- package/dist/license.js +75 -0
- package/dist/license.js.map +1 -0
- package/dist/money.cjs +93 -6
- package/dist/money.cjs.map +1 -1
- package/dist/money.d.cts +13 -1
- package/dist/money.d.ts +13 -1
- package/dist/money.js +115 -3
- package/dist/money.js.map +1 -1
- package/dist/nats.cjs +196 -179
- package/dist/nats.cjs.map +1 -1
- package/dist/nats.d.cts +13 -11
- package/dist/nats.d.ts +13 -11
- package/dist/nats.js +172 -155
- package/dist/nats.js.map +1 -1
- package/dist/types-DQRwj5rr.d.cts +113 -0
- package/dist/types-DQRwj5rr.d.ts +113 -0
- package/package.json +55 -1
package/dist/cache.cjs
ADDED
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
9
|
+
var __export = (target, all) => {
|
|
10
|
+
for (var name in all)
|
|
11
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
12
|
+
};
|
|
13
|
+
var __copyProps = (to, from, except, desc) => {
|
|
14
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
15
|
+
for (let key of __getOwnPropNames(from))
|
|
16
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
17
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
18
|
+
}
|
|
19
|
+
return to;
|
|
20
|
+
};
|
|
21
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
22
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
23
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
24
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
25
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
26
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
27
|
+
mod
|
|
28
|
+
));
|
|
29
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
30
|
+
|
|
31
|
+
// src/cache/index.ts
|
|
32
|
+
var cache_exports = {};
|
|
33
|
+
__export(cache_exports, {
|
|
34
|
+
CACHE_PROVIDER: () => CACHE_PROVIDER,
|
|
35
|
+
CacheModule: () => CacheModule,
|
|
36
|
+
CacheService: () => CacheService,
|
|
37
|
+
RedisCacheProvider: () => RedisCacheProvider
|
|
38
|
+
});
|
|
39
|
+
module.exports = __toCommonJS(cache_exports);
|
|
40
|
+
|
|
41
|
+
// src/cache/cache.module.ts
|
|
42
|
+
var import_common3 = require("@nestjs/common");
|
|
43
|
+
var import_config2 = require("@nestjs/config");
|
|
44
|
+
|
|
45
|
+
// src/cache/cache.service.ts
|
|
46
|
+
var import_common = require("@nestjs/common");
|
|
47
|
+
|
|
48
|
+
// src/cache/constants.ts
|
|
49
|
+
var CACHE_PROVIDER = Symbol("CACHE_PROVIDER");
|
|
50
|
+
|
|
51
|
+
// src/cache/cache.service.ts
|
|
52
|
+
function _ts_decorate(decorators, target, key, desc) {
|
|
53
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
54
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
55
|
+
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;
|
|
56
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
57
|
+
}
|
|
58
|
+
__name(_ts_decorate, "_ts_decorate");
|
|
59
|
+
function _ts_metadata(k, v) {
|
|
60
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
61
|
+
}
|
|
62
|
+
__name(_ts_metadata, "_ts_metadata");
|
|
63
|
+
function _ts_param(paramIndex, decorator) {
|
|
64
|
+
return function(target, key) {
|
|
65
|
+
decorator(target, key, paramIndex);
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
__name(_ts_param, "_ts_param");
|
|
69
|
+
var CacheService = class _CacheService {
|
|
70
|
+
static {
|
|
71
|
+
__name(this, "CacheService");
|
|
72
|
+
}
|
|
73
|
+
provider;
|
|
74
|
+
logger = new import_common.Logger(_CacheService.name);
|
|
75
|
+
constructor(provider) {
|
|
76
|
+
this.provider = provider;
|
|
77
|
+
}
|
|
78
|
+
// Stores a value with mandatory TTL — errors are logged and swallowed so DB writes still succeed
|
|
79
|
+
async set(key, value, ttlSeconds) {
|
|
80
|
+
try {
|
|
81
|
+
await this.provider.set(key, value, ttlSeconds);
|
|
82
|
+
} catch (err) {
|
|
83
|
+
this.logger.error(`Cache set failed for key "${key}"`, err);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
// Returns cached value or null on miss or any Redis error — callers fall back to DB
|
|
87
|
+
async get(key) {
|
|
88
|
+
try {
|
|
89
|
+
return await this.provider.get(key);
|
|
90
|
+
} catch (err) {
|
|
91
|
+
this.logger.error(`Cache get failed for key "${key}"`, err);
|
|
92
|
+
return null;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
// Deletes one or more keys — errors are logged and swallowed
|
|
96
|
+
async del(...keys) {
|
|
97
|
+
try {
|
|
98
|
+
await this.provider.del(...keys);
|
|
99
|
+
} catch (err) {
|
|
100
|
+
this.logger.error(`Cache del failed for keys "${keys.join(", ")}"`, err);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
// Returns all keys matching a glob pattern — returns empty array on error
|
|
104
|
+
async scanKeys(pattern) {
|
|
105
|
+
try {
|
|
106
|
+
return await this.provider.scanKeys(pattern);
|
|
107
|
+
} catch (err) {
|
|
108
|
+
this.logger.error(`Cache scanKeys failed for pattern "${pattern}"`, err);
|
|
109
|
+
return [];
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
// Returns raw memory info from the provider — returns empty string on error
|
|
113
|
+
async getMemoryInfo() {
|
|
114
|
+
try {
|
|
115
|
+
return await this.provider.getMemoryInfo();
|
|
116
|
+
} catch (err) {
|
|
117
|
+
this.logger.error("Cache getMemoryInfo failed", err);
|
|
118
|
+
return "";
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
};
|
|
122
|
+
CacheService = _ts_decorate([
|
|
123
|
+
(0, import_common.Injectable)(),
|
|
124
|
+
_ts_param(0, (0, import_common.Inject)(CACHE_PROVIDER)),
|
|
125
|
+
_ts_metadata("design:type", Function),
|
|
126
|
+
_ts_metadata("design:paramtypes", [
|
|
127
|
+
typeof ICacheProvider === "undefined" ? Object : ICacheProvider
|
|
128
|
+
])
|
|
129
|
+
], CacheService);
|
|
130
|
+
|
|
131
|
+
// src/cache/providers/redis.provider.ts
|
|
132
|
+
var import_common2 = require("@nestjs/common");
|
|
133
|
+
var import_config = require("@nestjs/config");
|
|
134
|
+
var import_ioredis = __toESM(require("ioredis"), 1);
|
|
135
|
+
function _ts_decorate2(decorators, target, key, desc) {
|
|
136
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
137
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
138
|
+
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;
|
|
139
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
140
|
+
}
|
|
141
|
+
__name(_ts_decorate2, "_ts_decorate");
|
|
142
|
+
function _ts_metadata2(k, v) {
|
|
143
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
144
|
+
}
|
|
145
|
+
__name(_ts_metadata2, "_ts_metadata");
|
|
146
|
+
var RedisCacheProvider = class _RedisCacheProvider {
|
|
147
|
+
static {
|
|
148
|
+
__name(this, "RedisCacheProvider");
|
|
149
|
+
}
|
|
150
|
+
configService;
|
|
151
|
+
logger = new import_common2.Logger(_RedisCacheProvider.name);
|
|
152
|
+
client;
|
|
153
|
+
constructor(configService) {
|
|
154
|
+
this.configService = configService;
|
|
155
|
+
}
|
|
156
|
+
// Creates the ioredis client and attaches connection/error listeners
|
|
157
|
+
onModuleInit() {
|
|
158
|
+
const url = this.configService.getOrThrow("REDIS_URL");
|
|
159
|
+
this.client = new import_ioredis.default(url, {
|
|
160
|
+
lazyConnect: true,
|
|
161
|
+
maxRetriesPerRequest: 3
|
|
162
|
+
});
|
|
163
|
+
this.client.on("connect", () => this.logger.log("Redis connected"));
|
|
164
|
+
this.client.on("error", (err) => this.logger.error("Redis error", err));
|
|
165
|
+
}
|
|
166
|
+
// Gracefully closes the ioredis connection on app shutdown
|
|
167
|
+
async onModuleDestroy() {
|
|
168
|
+
await this.client.quit();
|
|
169
|
+
this.logger.log("Redis disconnected");
|
|
170
|
+
}
|
|
171
|
+
// Serializes value to JSON and stores with a mandatory TTL
|
|
172
|
+
async set(key, value, ttlSeconds) {
|
|
173
|
+
const json = JSON.stringify(value);
|
|
174
|
+
await this.client.setex(key, ttlSeconds, json);
|
|
175
|
+
}
|
|
176
|
+
// Reads the stored JSON string and parses back to the original type
|
|
177
|
+
async get(key) {
|
|
178
|
+
const json = await this.client.get(key);
|
|
179
|
+
if (!json) return null;
|
|
180
|
+
return JSON.parse(json);
|
|
181
|
+
}
|
|
182
|
+
// Deletes one or more keys in a single command
|
|
183
|
+
async del(...keys) {
|
|
184
|
+
if (keys.length > 0) {
|
|
185
|
+
await this.client.del(...keys);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
// Cursor-iterates all keys matching a glob pattern — never uses KEYS command
|
|
189
|
+
async scanKeys(pattern) {
|
|
190
|
+
const keys = [];
|
|
191
|
+
let cursor = "0";
|
|
192
|
+
do {
|
|
193
|
+
const [nextCursor, batch] = await this.client.scan(cursor, "MATCH", pattern, "COUNT", 100);
|
|
194
|
+
cursor = nextCursor;
|
|
195
|
+
keys.push(...batch);
|
|
196
|
+
} while (cursor !== "0");
|
|
197
|
+
return keys;
|
|
198
|
+
}
|
|
199
|
+
// Returns raw INFO memory output for memory monitoring
|
|
200
|
+
async getMemoryInfo() {
|
|
201
|
+
return this.client.info("memory");
|
|
202
|
+
}
|
|
203
|
+
};
|
|
204
|
+
RedisCacheProvider = _ts_decorate2([
|
|
205
|
+
(0, import_common2.Injectable)(),
|
|
206
|
+
_ts_metadata2("design:type", Function),
|
|
207
|
+
_ts_metadata2("design:paramtypes", [
|
|
208
|
+
typeof import_config.ConfigService === "undefined" ? Object : import_config.ConfigService
|
|
209
|
+
])
|
|
210
|
+
], RedisCacheProvider);
|
|
211
|
+
|
|
212
|
+
// src/cache/cache.module.ts
|
|
213
|
+
function _ts_decorate3(decorators, target, key, desc) {
|
|
214
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
215
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
216
|
+
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;
|
|
217
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
218
|
+
}
|
|
219
|
+
__name(_ts_decorate3, "_ts_decorate");
|
|
220
|
+
var CacheModule = class {
|
|
221
|
+
static {
|
|
222
|
+
__name(this, "CacheModule");
|
|
223
|
+
}
|
|
224
|
+
};
|
|
225
|
+
CacheModule = _ts_decorate3([
|
|
226
|
+
(0, import_common3.Module)({
|
|
227
|
+
imports: [
|
|
228
|
+
import_config2.ConfigModule
|
|
229
|
+
],
|
|
230
|
+
providers: [
|
|
231
|
+
RedisCacheProvider,
|
|
232
|
+
{
|
|
233
|
+
provide: CACHE_PROVIDER,
|
|
234
|
+
useExisting: RedisCacheProvider
|
|
235
|
+
},
|
|
236
|
+
CacheService
|
|
237
|
+
],
|
|
238
|
+
exports: [
|
|
239
|
+
RedisCacheProvider,
|
|
240
|
+
CACHE_PROVIDER,
|
|
241
|
+
CacheService
|
|
242
|
+
]
|
|
243
|
+
})
|
|
244
|
+
], CacheModule);
|
|
245
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
246
|
+
0 && (module.exports = {
|
|
247
|
+
CACHE_PROVIDER,
|
|
248
|
+
CacheModule,
|
|
249
|
+
CacheService,
|
|
250
|
+
RedisCacheProvider
|
|
251
|
+
});
|
|
252
|
+
//# sourceMappingURL=cache.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/cache/index.ts","../src/cache/cache.module.ts","../src/cache/cache.service.ts","../src/cache/constants.ts","../src/cache/providers/redis.provider.ts"],"sourcesContent":["export { CacheModule } from './cache.module';\nexport { CacheService } from './cache.service';\nexport { CACHE_PROVIDER } from './constants';\nexport type { ICacheProvider } from './interfaces/cache-provider.interface';\nexport { RedisCacheProvider } from './providers/redis.provider';\n","import { Module } from '@nestjs/common';\nimport { ConfigModule } from '@nestjs/config';\nimport { CacheService } from './cache.service';\nimport { CACHE_PROVIDER } from './constants';\nimport { RedisCacheProvider } from './providers/redis.provider';\n\n// To add a new provider in the future:\n// 1. Create providers/memcached.provider.ts implementing ICacheProvider\n// 2. Replace RedisCacheProvider with the new class in useExisting below\n\n@Module({\n imports: [ConfigModule],\n providers: [\n RedisCacheProvider,\n {\n provide: CACHE_PROVIDER,\n useExisting: RedisCacheProvider,\n },\n CacheService,\n ],\n exports: [RedisCacheProvider, CACHE_PROVIDER, CacheService],\n})\nexport class CacheModule {}\n","import { Inject, Injectable, Logger } from '@nestjs/common';\nimport { CACHE_PROVIDER } from './constants';\nimport type { ICacheProvider } from './interfaces/cache-provider.interface';\n\n@Injectable()\nexport class CacheService {\n private readonly logger = new Logger(CacheService.name);\n\n constructor(@Inject(CACHE_PROVIDER) private readonly provider: ICacheProvider) {}\n\n // Stores a value with mandatory TTL — errors are logged and swallowed so DB writes still succeed\n async set<T>(key: string, value: T, ttlSeconds: number): Promise<void> {\n try {\n await this.provider.set(key, value, ttlSeconds);\n } catch (err) {\n this.logger.error(`Cache set failed for key \"${key}\"`, err);\n }\n }\n\n // Returns cached value or null on miss or any Redis error — callers fall back to DB\n async get<T>(key: string): Promise<T | null> {\n try {\n return await this.provider.get<T>(key);\n } catch (err) {\n this.logger.error(`Cache get failed for key \"${key}\"`, err);\n return null;\n }\n }\n\n // Deletes one or more keys — errors are logged and swallowed\n async del(...keys: string[]): Promise<void> {\n try {\n await this.provider.del(...keys);\n } catch (err) {\n this.logger.error(`Cache del failed for keys \"${keys.join(', ')}\"`, err);\n }\n }\n\n // Returns all keys matching a glob pattern — returns empty array on error\n async scanKeys(pattern: string): Promise<string[]> {\n try {\n return await this.provider.scanKeys(pattern);\n } catch (err) {\n this.logger.error(`Cache scanKeys failed for pattern \"${pattern}\"`, err);\n return [];\n }\n }\n\n // Returns raw memory info from the provider — returns empty string on error\n async getMemoryInfo(): Promise<string> {\n try {\n return await this.provider.getMemoryInfo();\n } catch (err) {\n this.logger.error('Cache getMemoryInfo failed', err);\n return '';\n }\n }\n}\n","// Injection token for the active cache provider — use this to inject ICacheProvider\nexport const CACHE_PROVIDER = Symbol('CACHE_PROVIDER');\n","import { Injectable, Logger, OnModuleDestroy, OnModuleInit } from '@nestjs/common';\nimport { ConfigService } from '@nestjs/config';\nimport Redis from 'ioredis';\nimport type { ICacheProvider } from '../interfaces/cache-provider.interface';\n\n@Injectable()\nexport class RedisCacheProvider implements ICacheProvider, OnModuleInit, OnModuleDestroy {\n private readonly logger = new Logger(RedisCacheProvider.name);\n private client: Redis;\n\n constructor(private readonly configService: ConfigService) {}\n\n // Creates the ioredis client and attaches connection/error listeners\n onModuleInit(): void {\n const url = this.configService.getOrThrow<string>('REDIS_URL');\n this.client = new Redis(url, {\n lazyConnect: true,\n maxRetriesPerRequest: 3,\n });\n this.client.on('connect', () => this.logger.log('Redis connected'));\n this.client.on('error', (err) => this.logger.error('Redis error', err));\n }\n\n // Gracefully closes the ioredis connection on app shutdown\n async onModuleDestroy(): Promise<void> {\n await this.client.quit();\n this.logger.log('Redis disconnected');\n }\n\n // Serializes value to JSON and stores with a mandatory TTL\n async set<T>(key: string, value: T, ttlSeconds: number): Promise<void> {\n const json = JSON.stringify(value);\n await this.client.setex(key, ttlSeconds, json);\n }\n\n // Reads the stored JSON string and parses back to the original type\n async get<T>(key: string): Promise<T | null> {\n const json = await this.client.get(key);\n if (!json) return null;\n return JSON.parse(json) as T;\n }\n\n // Deletes one or more keys in a single command\n async del(...keys: string[]): Promise<void> {\n if (keys.length > 0) {\n await this.client.del(...keys);\n }\n }\n\n // Cursor-iterates all keys matching a glob pattern — never uses KEYS command\n async scanKeys(pattern: string): Promise<string[]> {\n const keys: string[] = [];\n let cursor = '0';\n do {\n const [nextCursor, batch] = await this.client.scan(cursor, 'MATCH', pattern, 'COUNT', 100);\n cursor = nextCursor;\n keys.push(...batch);\n } while (cursor !== '0');\n return keys;\n }\n\n // Returns raw INFO memory output for memory monitoring\n async getMemoryInfo(): Promise<string> {\n return this.client.info('memory');\n }\n}\n"],"mappings":"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","names":["import_common","import_config","CACHE_PROVIDER","Symbol","CacheService","logger","Logger","name","provider","set","key","value","ttlSeconds","err","error","get","del","keys","join","scanKeys","pattern","getMemoryInfo","import_common","RedisCacheProvider","logger","Logger","name","client","configService","onModuleInit","url","getOrThrow","Redis","lazyConnect","maxRetriesPerRequest","on","log","err","error","onModuleDestroy","quit","set","key","value","ttlSeconds","json","JSON","stringify","setex","get","parse","del","keys","length","scanKeys","pattern","cursor","nextCursor","batch","scan","push","getMemoryInfo","info","CacheModule","imports","ConfigModule","providers","RedisCacheProvider","provide","CACHE_PROVIDER","useExisting","CacheService","exports"]}
|
package/dist/cache.d.cts
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { I as ICacheProvider } from './cache.service-_SuJIcNA.cjs';
|
|
2
|
+
export { C as CacheService } from './cache.service-_SuJIcNA.cjs';
|
|
3
|
+
import { OnModuleInit, OnModuleDestroy } from '@nestjs/common';
|
|
4
|
+
import { ConfigService } from '@nestjs/config';
|
|
5
|
+
|
|
6
|
+
declare class CacheModule {
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
declare const CACHE_PROVIDER: unique symbol;
|
|
10
|
+
|
|
11
|
+
declare class RedisCacheProvider implements ICacheProvider, OnModuleInit, OnModuleDestroy {
|
|
12
|
+
private readonly configService;
|
|
13
|
+
private readonly logger;
|
|
14
|
+
private client;
|
|
15
|
+
constructor(configService: ConfigService);
|
|
16
|
+
onModuleInit(): void;
|
|
17
|
+
onModuleDestroy(): Promise<void>;
|
|
18
|
+
set<T>(key: string, value: T, ttlSeconds: number): Promise<void>;
|
|
19
|
+
get<T>(key: string): Promise<T | null>;
|
|
20
|
+
del(...keys: string[]): Promise<void>;
|
|
21
|
+
scanKeys(pattern: string): Promise<string[]>;
|
|
22
|
+
getMemoryInfo(): Promise<string>;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export { CACHE_PROVIDER, CacheModule, ICacheProvider, RedisCacheProvider };
|
package/dist/cache.d.ts
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { I as ICacheProvider } from './cache.service-_SuJIcNA.js';
|
|
2
|
+
export { C as CacheService } from './cache.service-_SuJIcNA.js';
|
|
3
|
+
import { OnModuleInit, OnModuleDestroy } from '@nestjs/common';
|
|
4
|
+
import { ConfigService } from '@nestjs/config';
|
|
5
|
+
|
|
6
|
+
declare class CacheModule {
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
declare const CACHE_PROVIDER: unique symbol;
|
|
10
|
+
|
|
11
|
+
declare class RedisCacheProvider implements ICacheProvider, OnModuleInit, OnModuleDestroy {
|
|
12
|
+
private readonly configService;
|
|
13
|
+
private readonly logger;
|
|
14
|
+
private client;
|
|
15
|
+
constructor(configService: ConfigService);
|
|
16
|
+
onModuleInit(): void;
|
|
17
|
+
onModuleDestroy(): Promise<void>;
|
|
18
|
+
set<T>(key: string, value: T, ttlSeconds: number): Promise<void>;
|
|
19
|
+
get<T>(key: string): Promise<T | null>;
|
|
20
|
+
del(...keys: string[]): Promise<void>;
|
|
21
|
+
scanKeys(pattern: string): Promise<string[]>;
|
|
22
|
+
getMemoryInfo(): Promise<string>;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export { CACHE_PROVIDER, CacheModule, ICacheProvider, RedisCacheProvider };
|
package/dist/cache.js
ADDED
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
3
|
+
|
|
4
|
+
// src/cache/cache.module.ts
|
|
5
|
+
import { Module } from "@nestjs/common";
|
|
6
|
+
import { ConfigModule } from "@nestjs/config";
|
|
7
|
+
|
|
8
|
+
// src/cache/cache.service.ts
|
|
9
|
+
import { Inject, Injectable, Logger } from "@nestjs/common";
|
|
10
|
+
|
|
11
|
+
// src/cache/constants.ts
|
|
12
|
+
var CACHE_PROVIDER = Symbol("CACHE_PROVIDER");
|
|
13
|
+
|
|
14
|
+
// src/cache/cache.service.ts
|
|
15
|
+
function _ts_decorate(decorators, target, key, desc) {
|
|
16
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
17
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
18
|
+
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;
|
|
19
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
20
|
+
}
|
|
21
|
+
__name(_ts_decorate, "_ts_decorate");
|
|
22
|
+
function _ts_metadata(k, v) {
|
|
23
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
24
|
+
}
|
|
25
|
+
__name(_ts_metadata, "_ts_metadata");
|
|
26
|
+
function _ts_param(paramIndex, decorator) {
|
|
27
|
+
return function(target, key) {
|
|
28
|
+
decorator(target, key, paramIndex);
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
__name(_ts_param, "_ts_param");
|
|
32
|
+
var CacheService = class _CacheService {
|
|
33
|
+
static {
|
|
34
|
+
__name(this, "CacheService");
|
|
35
|
+
}
|
|
36
|
+
provider;
|
|
37
|
+
logger = new Logger(_CacheService.name);
|
|
38
|
+
constructor(provider) {
|
|
39
|
+
this.provider = provider;
|
|
40
|
+
}
|
|
41
|
+
// Stores a value with mandatory TTL — errors are logged and swallowed so DB writes still succeed
|
|
42
|
+
async set(key, value, ttlSeconds) {
|
|
43
|
+
try {
|
|
44
|
+
await this.provider.set(key, value, ttlSeconds);
|
|
45
|
+
} catch (err) {
|
|
46
|
+
this.logger.error(`Cache set failed for key "${key}"`, err);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
// Returns cached value or null on miss or any Redis error — callers fall back to DB
|
|
50
|
+
async get(key) {
|
|
51
|
+
try {
|
|
52
|
+
return await this.provider.get(key);
|
|
53
|
+
} catch (err) {
|
|
54
|
+
this.logger.error(`Cache get failed for key "${key}"`, err);
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
// Deletes one or more keys — errors are logged and swallowed
|
|
59
|
+
async del(...keys) {
|
|
60
|
+
try {
|
|
61
|
+
await this.provider.del(...keys);
|
|
62
|
+
} catch (err) {
|
|
63
|
+
this.logger.error(`Cache del failed for keys "${keys.join(", ")}"`, err);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
// Returns all keys matching a glob pattern — returns empty array on error
|
|
67
|
+
async scanKeys(pattern) {
|
|
68
|
+
try {
|
|
69
|
+
return await this.provider.scanKeys(pattern);
|
|
70
|
+
} catch (err) {
|
|
71
|
+
this.logger.error(`Cache scanKeys failed for pattern "${pattern}"`, err);
|
|
72
|
+
return [];
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
// Returns raw memory info from the provider — returns empty string on error
|
|
76
|
+
async getMemoryInfo() {
|
|
77
|
+
try {
|
|
78
|
+
return await this.provider.getMemoryInfo();
|
|
79
|
+
} catch (err) {
|
|
80
|
+
this.logger.error("Cache getMemoryInfo failed", err);
|
|
81
|
+
return "";
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
CacheService = _ts_decorate([
|
|
86
|
+
Injectable(),
|
|
87
|
+
_ts_param(0, Inject(CACHE_PROVIDER)),
|
|
88
|
+
_ts_metadata("design:type", Function),
|
|
89
|
+
_ts_metadata("design:paramtypes", [
|
|
90
|
+
typeof ICacheProvider === "undefined" ? Object : ICacheProvider
|
|
91
|
+
])
|
|
92
|
+
], CacheService);
|
|
93
|
+
|
|
94
|
+
// src/cache/providers/redis.provider.ts
|
|
95
|
+
import { Injectable as Injectable2, Logger as Logger2 } from "@nestjs/common";
|
|
96
|
+
import { ConfigService } from "@nestjs/config";
|
|
97
|
+
import Redis from "ioredis";
|
|
98
|
+
function _ts_decorate2(decorators, target, key, desc) {
|
|
99
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
100
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
101
|
+
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;
|
|
102
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
103
|
+
}
|
|
104
|
+
__name(_ts_decorate2, "_ts_decorate");
|
|
105
|
+
function _ts_metadata2(k, v) {
|
|
106
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
107
|
+
}
|
|
108
|
+
__name(_ts_metadata2, "_ts_metadata");
|
|
109
|
+
var RedisCacheProvider = class _RedisCacheProvider {
|
|
110
|
+
static {
|
|
111
|
+
__name(this, "RedisCacheProvider");
|
|
112
|
+
}
|
|
113
|
+
configService;
|
|
114
|
+
logger = new Logger2(_RedisCacheProvider.name);
|
|
115
|
+
client;
|
|
116
|
+
constructor(configService) {
|
|
117
|
+
this.configService = configService;
|
|
118
|
+
}
|
|
119
|
+
// Creates the ioredis client and attaches connection/error listeners
|
|
120
|
+
onModuleInit() {
|
|
121
|
+
const url = this.configService.getOrThrow("REDIS_URL");
|
|
122
|
+
this.client = new Redis(url, {
|
|
123
|
+
lazyConnect: true,
|
|
124
|
+
maxRetriesPerRequest: 3
|
|
125
|
+
});
|
|
126
|
+
this.client.on("connect", () => this.logger.log("Redis connected"));
|
|
127
|
+
this.client.on("error", (err) => this.logger.error("Redis error", err));
|
|
128
|
+
}
|
|
129
|
+
// Gracefully closes the ioredis connection on app shutdown
|
|
130
|
+
async onModuleDestroy() {
|
|
131
|
+
await this.client.quit();
|
|
132
|
+
this.logger.log("Redis disconnected");
|
|
133
|
+
}
|
|
134
|
+
// Serializes value to JSON and stores with a mandatory TTL
|
|
135
|
+
async set(key, value, ttlSeconds) {
|
|
136
|
+
const json = JSON.stringify(value);
|
|
137
|
+
await this.client.setex(key, ttlSeconds, json);
|
|
138
|
+
}
|
|
139
|
+
// Reads the stored JSON string and parses back to the original type
|
|
140
|
+
async get(key) {
|
|
141
|
+
const json = await this.client.get(key);
|
|
142
|
+
if (!json) return null;
|
|
143
|
+
return JSON.parse(json);
|
|
144
|
+
}
|
|
145
|
+
// Deletes one or more keys in a single command
|
|
146
|
+
async del(...keys) {
|
|
147
|
+
if (keys.length > 0) {
|
|
148
|
+
await this.client.del(...keys);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
// Cursor-iterates all keys matching a glob pattern — never uses KEYS command
|
|
152
|
+
async scanKeys(pattern) {
|
|
153
|
+
const keys = [];
|
|
154
|
+
let cursor = "0";
|
|
155
|
+
do {
|
|
156
|
+
const [nextCursor, batch] = await this.client.scan(cursor, "MATCH", pattern, "COUNT", 100);
|
|
157
|
+
cursor = nextCursor;
|
|
158
|
+
keys.push(...batch);
|
|
159
|
+
} while (cursor !== "0");
|
|
160
|
+
return keys;
|
|
161
|
+
}
|
|
162
|
+
// Returns raw INFO memory output for memory monitoring
|
|
163
|
+
async getMemoryInfo() {
|
|
164
|
+
return this.client.info("memory");
|
|
165
|
+
}
|
|
166
|
+
};
|
|
167
|
+
RedisCacheProvider = _ts_decorate2([
|
|
168
|
+
Injectable2(),
|
|
169
|
+
_ts_metadata2("design:type", Function),
|
|
170
|
+
_ts_metadata2("design:paramtypes", [
|
|
171
|
+
typeof ConfigService === "undefined" ? Object : ConfigService
|
|
172
|
+
])
|
|
173
|
+
], RedisCacheProvider);
|
|
174
|
+
|
|
175
|
+
// src/cache/cache.module.ts
|
|
176
|
+
function _ts_decorate3(decorators, target, key, desc) {
|
|
177
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
178
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
179
|
+
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;
|
|
180
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
181
|
+
}
|
|
182
|
+
__name(_ts_decorate3, "_ts_decorate");
|
|
183
|
+
var CacheModule = class {
|
|
184
|
+
static {
|
|
185
|
+
__name(this, "CacheModule");
|
|
186
|
+
}
|
|
187
|
+
};
|
|
188
|
+
CacheModule = _ts_decorate3([
|
|
189
|
+
Module({
|
|
190
|
+
imports: [
|
|
191
|
+
ConfigModule
|
|
192
|
+
],
|
|
193
|
+
providers: [
|
|
194
|
+
RedisCacheProvider,
|
|
195
|
+
{
|
|
196
|
+
provide: CACHE_PROVIDER,
|
|
197
|
+
useExisting: RedisCacheProvider
|
|
198
|
+
},
|
|
199
|
+
CacheService
|
|
200
|
+
],
|
|
201
|
+
exports: [
|
|
202
|
+
RedisCacheProvider,
|
|
203
|
+
CACHE_PROVIDER,
|
|
204
|
+
CacheService
|
|
205
|
+
]
|
|
206
|
+
})
|
|
207
|
+
], CacheModule);
|
|
208
|
+
export {
|
|
209
|
+
CACHE_PROVIDER,
|
|
210
|
+
CacheModule,
|
|
211
|
+
CacheService,
|
|
212
|
+
RedisCacheProvider
|
|
213
|
+
};
|
|
214
|
+
//# sourceMappingURL=cache.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/cache/cache.module.ts","../src/cache/cache.service.ts","../src/cache/constants.ts","../src/cache/providers/redis.provider.ts"],"sourcesContent":["import { Module } from '@nestjs/common';\nimport { ConfigModule } from '@nestjs/config';\nimport { CacheService } from './cache.service';\nimport { CACHE_PROVIDER } from './constants';\nimport { RedisCacheProvider } from './providers/redis.provider';\n\n// To add a new provider in the future:\n// 1. Create providers/memcached.provider.ts implementing ICacheProvider\n// 2. Replace RedisCacheProvider with the new class in useExisting below\n\n@Module({\n imports: [ConfigModule],\n providers: [\n RedisCacheProvider,\n {\n provide: CACHE_PROVIDER,\n useExisting: RedisCacheProvider,\n },\n CacheService,\n ],\n exports: [RedisCacheProvider, CACHE_PROVIDER, CacheService],\n})\nexport class CacheModule {}\n","import { Inject, Injectable, Logger } from '@nestjs/common';\nimport { CACHE_PROVIDER } from './constants';\nimport type { ICacheProvider } from './interfaces/cache-provider.interface';\n\n@Injectable()\nexport class CacheService {\n private readonly logger = new Logger(CacheService.name);\n\n constructor(@Inject(CACHE_PROVIDER) private readonly provider: ICacheProvider) {}\n\n // Stores a value with mandatory TTL — errors are logged and swallowed so DB writes still succeed\n async set<T>(key: string, value: T, ttlSeconds: number): Promise<void> {\n try {\n await this.provider.set(key, value, ttlSeconds);\n } catch (err) {\n this.logger.error(`Cache set failed for key \"${key}\"`, err);\n }\n }\n\n // Returns cached value or null on miss or any Redis error — callers fall back to DB\n async get<T>(key: string): Promise<T | null> {\n try {\n return await this.provider.get<T>(key);\n } catch (err) {\n this.logger.error(`Cache get failed for key \"${key}\"`, err);\n return null;\n }\n }\n\n // Deletes one or more keys — errors are logged and swallowed\n async del(...keys: string[]): Promise<void> {\n try {\n await this.provider.del(...keys);\n } catch (err) {\n this.logger.error(`Cache del failed for keys \"${keys.join(', ')}\"`, err);\n }\n }\n\n // Returns all keys matching a glob pattern — returns empty array on error\n async scanKeys(pattern: string): Promise<string[]> {\n try {\n return await this.provider.scanKeys(pattern);\n } catch (err) {\n this.logger.error(`Cache scanKeys failed for pattern \"${pattern}\"`, err);\n return [];\n }\n }\n\n // Returns raw memory info from the provider — returns empty string on error\n async getMemoryInfo(): Promise<string> {\n try {\n return await this.provider.getMemoryInfo();\n } catch (err) {\n this.logger.error('Cache getMemoryInfo failed', err);\n return '';\n }\n }\n}\n","// Injection token for the active cache provider — use this to inject ICacheProvider\nexport const CACHE_PROVIDER = Symbol('CACHE_PROVIDER');\n","import { Injectable, Logger, OnModuleDestroy, OnModuleInit } from '@nestjs/common';\nimport { ConfigService } from '@nestjs/config';\nimport Redis from 'ioredis';\nimport type { ICacheProvider } from '../interfaces/cache-provider.interface';\n\n@Injectable()\nexport class RedisCacheProvider implements ICacheProvider, OnModuleInit, OnModuleDestroy {\n private readonly logger = new Logger(RedisCacheProvider.name);\n private client: Redis;\n\n constructor(private readonly configService: ConfigService) {}\n\n // Creates the ioredis client and attaches connection/error listeners\n onModuleInit(): void {\n const url = this.configService.getOrThrow<string>('REDIS_URL');\n this.client = new Redis(url, {\n lazyConnect: true,\n maxRetriesPerRequest: 3,\n });\n this.client.on('connect', () => this.logger.log('Redis connected'));\n this.client.on('error', (err) => this.logger.error('Redis error', err));\n }\n\n // Gracefully closes the ioredis connection on app shutdown\n async onModuleDestroy(): Promise<void> {\n await this.client.quit();\n this.logger.log('Redis disconnected');\n }\n\n // Serializes value to JSON and stores with a mandatory TTL\n async set<T>(key: string, value: T, ttlSeconds: number): Promise<void> {\n const json = JSON.stringify(value);\n await this.client.setex(key, ttlSeconds, json);\n }\n\n // Reads the stored JSON string and parses back to the original type\n async get<T>(key: string): Promise<T | null> {\n const json = await this.client.get(key);\n if (!json) return null;\n return JSON.parse(json) as T;\n }\n\n // Deletes one or more keys in a single command\n async del(...keys: string[]): Promise<void> {\n if (keys.length > 0) {\n await this.client.del(...keys);\n }\n }\n\n // Cursor-iterates all keys matching a glob pattern — never uses KEYS command\n async scanKeys(pattern: string): Promise<string[]> {\n const keys: string[] = [];\n let cursor = '0';\n do {\n const [nextCursor, batch] = await this.client.scan(cursor, 'MATCH', pattern, 'COUNT', 100);\n cursor = nextCursor;\n keys.push(...batch);\n } while (cursor !== '0');\n return keys;\n }\n\n // Returns raw INFO memory output for memory monitoring\n async getMemoryInfo(): Promise<string> {\n return this.client.info('memory');\n }\n}\n"],"mappings":"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","names":["Module","ConfigModule","Inject","Injectable","Logger","CACHE_PROVIDER","Symbol","CacheService","logger","Logger","name","provider","set","key","value","ttlSeconds","err","error","get","del","keys","join","scanKeys","pattern","getMemoryInfo","Injectable","Logger","ConfigService","Redis","RedisCacheProvider","logger","Logger","name","client","configService","onModuleInit","url","getOrThrow","Redis","lazyConnect","maxRetriesPerRequest","on","log","err","error","onModuleDestroy","quit","set","key","value","ttlSeconds","json","JSON","stringify","setex","get","parse","del","keys","length","scanKeys","pattern","cursor","nextCursor","batch","scan","push","getMemoryInfo","info","CacheModule","imports","ConfigModule","providers","RedisCacheProvider","provide","CACHE_PROVIDER","useExisting","CacheService","exports"]}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
interface ICacheProvider {
|
|
2
|
+
set<T>(key: string, value: T, ttlSeconds: number): Promise<void>;
|
|
3
|
+
get<T>(key: string): Promise<T | null>;
|
|
4
|
+
del(...keys: string[]): Promise<void>;
|
|
5
|
+
scanKeys(pattern: string): Promise<string[]>;
|
|
6
|
+
getMemoryInfo(): Promise<string>;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
declare class CacheService {
|
|
10
|
+
private readonly provider;
|
|
11
|
+
private readonly logger;
|
|
12
|
+
constructor(provider: ICacheProvider);
|
|
13
|
+
set<T>(key: string, value: T, ttlSeconds: number): Promise<void>;
|
|
14
|
+
get<T>(key: string): Promise<T | null>;
|
|
15
|
+
del(...keys: string[]): Promise<void>;
|
|
16
|
+
scanKeys(pattern: string): Promise<string[]>;
|
|
17
|
+
getMemoryInfo(): Promise<string>;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export { CacheService as C, type ICacheProvider as I };
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
interface ICacheProvider {
|
|
2
|
+
set<T>(key: string, value: T, ttlSeconds: number): Promise<void>;
|
|
3
|
+
get<T>(key: string): Promise<T | null>;
|
|
4
|
+
del(...keys: string[]): Promise<void>;
|
|
5
|
+
scanKeys(pattern: string): Promise<string[]>;
|
|
6
|
+
getMemoryInfo(): Promise<string>;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
declare class CacheService {
|
|
10
|
+
private readonly provider;
|
|
11
|
+
private readonly logger;
|
|
12
|
+
constructor(provider: ICacheProvider);
|
|
13
|
+
set<T>(key: string, value: T, ttlSeconds: number): Promise<void>;
|
|
14
|
+
get<T>(key: string): Promise<T | null>;
|
|
15
|
+
del(...keys: string[]): Promise<void>;
|
|
16
|
+
scanKeys(pattern: string): Promise<string[]>;
|
|
17
|
+
getMemoryInfo(): Promise<string>;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export { CacheService as C, type ICacheProvider as I };
|