ts-cache-mongoose 1.7.6 → 2.0.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.
- package/README.md +79 -56
- package/biome.json +1 -1
- package/dist/index.cjs +86 -5
- package/dist/index.d.cts +2 -2
- package/dist/index.d.cts.map +1 -0
- package/dist/index.d.mts +2 -2
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +86 -5
- package/dist/nest/index.cjs +111 -0
- package/dist/nest/index.d.cts +40 -0
- package/dist/nest/index.d.cts.map +1 -0
- package/dist/nest/index.d.mts +40 -0
- package/dist/nest/index.d.mts.map +1 -0
- package/dist/nest/index.mjs +108 -0
- package/package.json +52 -26
- package/src/cache/Cache.ts +1 -1
- package/src/cache/engine/MemoryCacheEngine.ts +1 -1
- package/src/cache/engine/RedisCacheEngine.ts +1 -1
- package/src/key.ts +2 -2
- package/src/ms.ts +55 -0
- package/src/nest/cache.module.ts +79 -0
- package/src/nest/cache.service.ts +37 -0
- package/src/nest/index.ts +4 -0
- package/src/nest/interfaces.ts +17 -0
- package/src/sort-keys.ts +38 -0
- package/src/types.ts +1 -2
- package/src/version.ts +1 -2
- package/tests/ms.test.ts +93 -0
- package/tests/nest.test.ts +158 -0
- package/tests/sort-keys.test.ts +80 -0
- package/tsconfig.json +1 -0
package/README.md
CHANGED
|
@@ -23,8 +23,8 @@ Caching queries is a good way to improve performance of your application
|
|
|
23
23
|
|
|
24
24
|
```json
|
|
25
25
|
{
|
|
26
|
-
"node": "
|
|
27
|
-
"mongoose": ">=6.6.x || 7.x || 8.x",
|
|
26
|
+
"node": "20.x || 22.x || 24.x",
|
|
27
|
+
"mongoose": ">=6.6.x || 7.x || 8.x || 9.x",
|
|
28
28
|
}
|
|
29
29
|
```
|
|
30
30
|
|
|
@@ -51,94 +51,117 @@ yarn add ts-cache-mongoose
|
|
|
51
51
|
bun add ts-cache-mongoose
|
|
52
52
|
```
|
|
53
53
|
|
|
54
|
-
- This plugin requires mongoose
|
|
54
|
+
- This plugin requires `mongoose` to be installed as a peer dependency
|
|
55
55
|
|
|
56
56
|
```bash
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
bun add mongoose@6
|
|
62
|
-
# For latest mongoose 7
|
|
63
|
-
npm install mongoose@7
|
|
64
|
-
pnpm add mongoose@7
|
|
65
|
-
yarn add mongoose@7
|
|
66
|
-
bun add mongoose@7
|
|
67
|
-
# For latest mongoose 8
|
|
68
|
-
npm install mongoose@8
|
|
69
|
-
pnpm add mongoose@8
|
|
70
|
-
yarn add mongoose@8
|
|
71
|
-
bun add mongoose@8
|
|
57
|
+
npm install mongoose
|
|
58
|
+
pnpm add mongoose
|
|
59
|
+
yarn add mongoose
|
|
60
|
+
bun add mongoose
|
|
72
61
|
```
|
|
73
62
|
|
|
74
63
|
## Example
|
|
75
64
|
|
|
65
|
+
Works with any Node.js framework — Express, Fastify, Koa, Hono, etc:
|
|
66
|
+
|
|
76
67
|
```typescript
|
|
77
|
-
// On your application startup
|
|
78
68
|
import mongoose from 'mongoose'
|
|
79
69
|
import cache from 'ts-cache-mongoose'
|
|
80
70
|
|
|
81
|
-
// In-memory
|
|
82
|
-
|
|
71
|
+
// In-memory
|
|
72
|
+
cache.init(mongoose, {
|
|
83
73
|
defaultTTL: '60 seconds',
|
|
84
74
|
engine: 'memory',
|
|
85
|
-
debug: true, // Debug mode enables hit/miss logs in console, not for production use
|
|
86
75
|
})
|
|
87
76
|
|
|
88
|
-
//
|
|
89
|
-
|
|
90
|
-
// Redis example
|
|
91
|
-
const instance = cache.init(mongoose, {
|
|
77
|
+
// Or Redis
|
|
78
|
+
cache.init(mongoose, {
|
|
92
79
|
defaultTTL: '60 seconds',
|
|
93
80
|
engine: 'redis',
|
|
94
81
|
engineOptions: {
|
|
95
82
|
host: 'localhost',
|
|
96
83
|
port: 6379,
|
|
97
84
|
},
|
|
98
|
-
debug: true, // Debug mode enables hit/miss logs in console, not for production use
|
|
99
85
|
})
|
|
100
86
|
|
|
101
|
-
// Connect to your database
|
|
102
87
|
mongoose.connect('mongodb://localhost:27017/my-database')
|
|
88
|
+
```
|
|
103
89
|
|
|
104
|
-
|
|
105
|
-
const users = await User.find({ role: 'user' }).cache('10 seconds').exec()
|
|
106
|
-
// Cache hit
|
|
107
|
-
const users = await User.find({ role: 'user' }).cache('10 seconds').exec()
|
|
90
|
+
### Query caching
|
|
108
91
|
|
|
92
|
+
```typescript
|
|
93
|
+
const users = await User.find({ role: 'user' }).cache('10 seconds').exec()
|
|
109
94
|
const book = await Book.findById(id).cache('1 hour').exec()
|
|
110
|
-
const
|
|
95
|
+
const count = await Book.countDocuments().cache('1 minute').exec()
|
|
111
96
|
const authors = await Book.distinct('author').cache('30 seconds').exec()
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### Aggregate caching
|
|
112
100
|
|
|
101
|
+
```typescript
|
|
113
102
|
const books = await Book.aggregate([
|
|
114
|
-
{
|
|
115
|
-
|
|
116
|
-
genre: 'fantasy',
|
|
117
|
-
},
|
|
118
|
-
},
|
|
119
|
-
{
|
|
120
|
-
$group: {
|
|
121
|
-
_id: '$author',
|
|
122
|
-
count: { $sum: 1 },
|
|
123
|
-
},
|
|
124
|
-
},
|
|
125
|
-
{
|
|
126
|
-
$project: {
|
|
127
|
-
_id: 0,
|
|
128
|
-
author: '$_id',
|
|
129
|
-
count: 1,
|
|
130
|
-
},
|
|
131
|
-
}
|
|
103
|
+
{ $match: { genre: 'fantasy' } },
|
|
104
|
+
{ $group: { _id: '$author', count: { $sum: 1 } } },
|
|
132
105
|
]).cache('1 minute').exec()
|
|
106
|
+
```
|
|
133
107
|
|
|
134
|
-
|
|
108
|
+
### Cache invalidation
|
|
135
109
|
|
|
136
|
-
|
|
110
|
+
```typescript
|
|
111
|
+
const instance = cache.init(mongoose, { engine: 'memory', defaultTTL: '60 seconds' })
|
|
112
|
+
|
|
113
|
+
// Clear all cache
|
|
137
114
|
await instance.clear()
|
|
138
115
|
|
|
139
|
-
//
|
|
140
|
-
const user = await User.findById(
|
|
141
|
-
await instance.clear('
|
|
116
|
+
// Or use custom cache key
|
|
117
|
+
const user = await User.findById(id).cache('1 minute', 'user-key').exec()
|
|
118
|
+
await instance.clear('user-key')
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
### NestJS (because it's special)
|
|
122
|
+
|
|
123
|
+
Import `CacheModule` from `ts-cache-mongoose/nest`:
|
|
124
|
+
|
|
125
|
+
```typescript
|
|
126
|
+
import { CacheModule } from 'ts-cache-mongoose/nest'
|
|
127
|
+
|
|
128
|
+
@Module({
|
|
129
|
+
imports: [
|
|
130
|
+
MongooseModule.forRoot(process.env.MONGO_URI),
|
|
131
|
+
CacheModule.forRoot({
|
|
132
|
+
engine: 'memory',
|
|
133
|
+
defaultTTL: '60 seconds',
|
|
134
|
+
}),
|
|
135
|
+
],
|
|
136
|
+
})
|
|
137
|
+
export class AppModule {}
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
With `ConfigService`:
|
|
141
|
+
|
|
142
|
+
```typescript
|
|
143
|
+
CacheModule.forRootAsync({
|
|
144
|
+
inject: [ConfigService],
|
|
145
|
+
useFactory: (config: ConfigService) => ({
|
|
146
|
+
engine: config.get('CACHE_ENGINE', 'memory'),
|
|
147
|
+
defaultTTL: config.get('CACHE_TTL', '60 seconds'),
|
|
148
|
+
}),
|
|
149
|
+
})
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
Inject `CacheService` for programmatic cache clearing:
|
|
153
|
+
|
|
154
|
+
```typescript
|
|
155
|
+
import { CacheService } from 'ts-cache-mongoose/nest'
|
|
156
|
+
|
|
157
|
+
@Injectable()
|
|
158
|
+
export class SomeService {
|
|
159
|
+
constructor(private readonly cacheService: CacheService) {}
|
|
160
|
+
|
|
161
|
+
async clearUserCache() {
|
|
162
|
+
await this.cacheService.clear('user-cache-key')
|
|
163
|
+
}
|
|
164
|
+
}
|
|
142
165
|
```
|
|
143
166
|
|
|
144
167
|
## Check my other projects
|
package/biome.json
CHANGED
package/dist/index.cjs
CHANGED
|
@@ -1,12 +1,59 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var ms = require('ms');
|
|
4
3
|
var bson = require('bson');
|
|
5
4
|
var IORedis = require('ioredis');
|
|
6
5
|
var mongoose = require('mongoose');
|
|
7
|
-
var semver = require('semver');
|
|
8
6
|
var node_crypto = require('node:crypto');
|
|
9
|
-
|
|
7
|
+
|
|
8
|
+
const s = 1e3;
|
|
9
|
+
const m = s * 60;
|
|
10
|
+
const h = m * 60;
|
|
11
|
+
const d = h * 24;
|
|
12
|
+
const w = d * 7;
|
|
13
|
+
const y = d * 365.25;
|
|
14
|
+
const RE = /^(-?(?:\d+)?\.?\d+)\s*(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i;
|
|
15
|
+
const UNITS = {
|
|
16
|
+
years: y,
|
|
17
|
+
year: y,
|
|
18
|
+
yrs: y,
|
|
19
|
+
yr: y,
|
|
20
|
+
y,
|
|
21
|
+
weeks: w,
|
|
22
|
+
week: w,
|
|
23
|
+
w,
|
|
24
|
+
days: d,
|
|
25
|
+
day: d,
|
|
26
|
+
d,
|
|
27
|
+
hours: h,
|
|
28
|
+
hour: h,
|
|
29
|
+
hrs: h,
|
|
30
|
+
hr: h,
|
|
31
|
+
h,
|
|
32
|
+
minutes: m,
|
|
33
|
+
minute: m,
|
|
34
|
+
mins: m,
|
|
35
|
+
min: m,
|
|
36
|
+
m,
|
|
37
|
+
seconds: s,
|
|
38
|
+
second: s,
|
|
39
|
+
secs: s,
|
|
40
|
+
sec: s,
|
|
41
|
+
s,
|
|
42
|
+
milliseconds: 1,
|
|
43
|
+
millisecond: 1,
|
|
44
|
+
msecs: 1,
|
|
45
|
+
msec: 1,
|
|
46
|
+
ms: 1
|
|
47
|
+
};
|
|
48
|
+
const ms = (val) => {
|
|
49
|
+
const str = String(val);
|
|
50
|
+
if (str.length > 100) return 0;
|
|
51
|
+
const match = RE.exec(str);
|
|
52
|
+
if (!match) return 0;
|
|
53
|
+
const n = Number.parseFloat(match[1] ?? "");
|
|
54
|
+
const type = (match[2] ?? "ms").toLowerCase();
|
|
55
|
+
return n * (UNITS[type] ?? 0);
|
|
56
|
+
};
|
|
10
57
|
|
|
11
58
|
var __typeError$3 = (msg) => {
|
|
12
59
|
throw TypeError(msg);
|
|
@@ -48,7 +95,7 @@ class MemoryCacheEngine {
|
|
|
48
95
|
}
|
|
49
96
|
_cache = new WeakMap();
|
|
50
97
|
|
|
51
|
-
const isMongooseLessThan7 =
|
|
98
|
+
const isMongooseLessThan7 = Number.parseInt(mongoose.version, 10) < 7;
|
|
52
99
|
const convertToObject = (value) => {
|
|
53
100
|
if (isMongooseLessThan7) {
|
|
54
101
|
if (value != null && typeof value === "object" && !Array.isArray(value) && value.toObject) {
|
|
@@ -176,8 +223,42 @@ _defaultTTL = new WeakMap();
|
|
|
176
223
|
_debug = new WeakMap();
|
|
177
224
|
_engines = new WeakMap();
|
|
178
225
|
|
|
226
|
+
const isPlainObject = (value) => {
|
|
227
|
+
if (typeof value !== "object" || value === null) return false;
|
|
228
|
+
const proto = Object.getPrototypeOf(value);
|
|
229
|
+
return proto === Object.prototype || proto === null;
|
|
230
|
+
};
|
|
231
|
+
const sortKeys = (input) => {
|
|
232
|
+
const seen = /* @__PURE__ */ new WeakSet();
|
|
233
|
+
const sortObject = (obj) => {
|
|
234
|
+
if (seen.has(obj)) return obj;
|
|
235
|
+
seen.add(obj);
|
|
236
|
+
const sorted = {};
|
|
237
|
+
for (const key of Object.keys(obj).sort((a, b) => a.localeCompare(b))) {
|
|
238
|
+
const value = obj[key];
|
|
239
|
+
if (Array.isArray(value)) {
|
|
240
|
+
sorted[key] = sortArray(value);
|
|
241
|
+
} else if (isPlainObject(value)) {
|
|
242
|
+
sorted[key] = sortObject(value);
|
|
243
|
+
} else {
|
|
244
|
+
sorted[key] = value;
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
return sorted;
|
|
248
|
+
};
|
|
249
|
+
const sortArray = (arr) => {
|
|
250
|
+
return arr.map((item) => {
|
|
251
|
+
if (Array.isArray(item)) return sortArray(item);
|
|
252
|
+
if (isPlainObject(item)) return sortObject(item);
|
|
253
|
+
return item;
|
|
254
|
+
});
|
|
255
|
+
};
|
|
256
|
+
if (Array.isArray(input)) return sortArray(input);
|
|
257
|
+
return sortObject(input);
|
|
258
|
+
};
|
|
259
|
+
|
|
179
260
|
function getKey(data) {
|
|
180
|
-
const sortedObj = sortKeys(data
|
|
261
|
+
const sortedObj = sortKeys(data);
|
|
181
262
|
const sortedStr = JSON.stringify(sortedObj, (_, val) => {
|
|
182
263
|
return val instanceof RegExp ? String(val) : val;
|
|
183
264
|
});
|
package/dist/index.d.cts
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { Mongoose } from 'mongoose';
|
|
2
2
|
import { RedisOptions } from 'ioredis';
|
|
3
|
-
import { StringValue } from 'ms';
|
|
4
3
|
|
|
5
|
-
type CacheTTL = number |
|
|
4
|
+
type CacheTTL = number | string;
|
|
6
5
|
type CacheData = Record<string, unknown> | Record<string, unknown>[] | unknown[] | number | undefined;
|
|
7
6
|
type CacheOptions = {
|
|
8
7
|
engine: 'memory' | 'redis';
|
|
@@ -50,3 +49,4 @@ declare class CacheMongoose {
|
|
|
50
49
|
|
|
51
50
|
export { CacheMongoose as default };
|
|
52
51
|
export type { CacheData, CacheEngine, CacheOptions, CacheTTL };
|
|
52
|
+
//# sourceMappingURL=index.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.cts","sources":["../src/types.ts","../src/index.ts"],"mappings":";;;AAEM,KAAM,QAAQ;AAEd,KAAM,SAAS,GAAG,MAAM,oBAAoB,MAAM;AAElD,KAAM,YAAY;;oBAEN,YAAY;iBACf,QAAQ;;;AAIjB,UAAW,WAAW;0BACJ,OAAO,CAAC,SAAS,IAAI,SAAS;8BAC1B,SAAS,QAAQ,QAAQ,KAAK,OAAO;0BACzC,OAAO;iBAChB,OAAO;iBACP,OAAO;;;ACTtB;;8EAE0E,QAAQ;;;cAGxE,QAAQ;iFAC2D,QAAQ;;;;;;;;mDAStC,QAAQ;;;cAG7C,QAAQ;sDACgC,QAAQ;;;AAI1D,cAAM,aAAa;;;;0BAQY,QAAQ,gBAAgB,YAAY,GAAG,aAAa;+BAczC,OAAO;aAQzB,OAAO","names":[]}
|
package/dist/index.d.mts
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { Mongoose } from 'mongoose';
|
|
2
2
|
import { RedisOptions } from 'ioredis';
|
|
3
|
-
import { StringValue } from 'ms';
|
|
4
3
|
|
|
5
|
-
type CacheTTL = number |
|
|
4
|
+
type CacheTTL = number | string;
|
|
6
5
|
type CacheData = Record<string, unknown> | Record<string, unknown>[] | unknown[] | number | undefined;
|
|
7
6
|
type CacheOptions = {
|
|
8
7
|
engine: 'memory' | 'redis';
|
|
@@ -50,3 +49,4 @@ declare class CacheMongoose {
|
|
|
50
49
|
|
|
51
50
|
export { CacheMongoose as default };
|
|
52
51
|
export type { CacheData, CacheEngine, CacheOptions, CacheTTL };
|
|
52
|
+
//# sourceMappingURL=index.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.mts","sources":["../src/types.ts","../src/index.ts"],"mappings":";;;AAEM,KAAM,QAAQ;AAEd,KAAM,SAAS,GAAG,MAAM,oBAAoB,MAAM;AAElD,KAAM,YAAY;;oBAEN,YAAY;iBACf,QAAQ;;;AAIjB,UAAW,WAAW;0BACJ,OAAO,CAAC,SAAS,IAAI,SAAS;8BAC1B,SAAS,QAAQ,QAAQ,KAAK,OAAO;0BACzC,OAAO;iBAChB,OAAO;iBACP,OAAO;;;ACTtB;;8EAE0E,QAAQ;;;cAGxE,QAAQ;iFAC2D,QAAQ;;;;;;;;mDAStC,QAAQ;;;cAG7C,QAAQ;sDACgC,QAAQ;;;AAI1D,cAAM,aAAa;;;;0BAQY,QAAQ,gBAAgB,YAAY,GAAG,aAAa;+BAczC,OAAO;aAQzB,OAAO","names":[]}
|
package/dist/index.mjs
CHANGED
|
@@ -1,10 +1,57 @@
|
|
|
1
|
-
import ms from 'ms';
|
|
2
1
|
import { EJSON } from 'bson';
|
|
3
2
|
import IORedis from 'ioredis';
|
|
4
3
|
import mongoose from 'mongoose';
|
|
5
|
-
import { satisfies } from 'semver';
|
|
6
4
|
import { createHash } from 'node:crypto';
|
|
7
|
-
|
|
5
|
+
|
|
6
|
+
const s = 1e3;
|
|
7
|
+
const m = s * 60;
|
|
8
|
+
const h = m * 60;
|
|
9
|
+
const d = h * 24;
|
|
10
|
+
const w = d * 7;
|
|
11
|
+
const y = d * 365.25;
|
|
12
|
+
const RE = /^(-?(?:\d+)?\.?\d+)\s*(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i;
|
|
13
|
+
const UNITS = {
|
|
14
|
+
years: y,
|
|
15
|
+
year: y,
|
|
16
|
+
yrs: y,
|
|
17
|
+
yr: y,
|
|
18
|
+
y,
|
|
19
|
+
weeks: w,
|
|
20
|
+
week: w,
|
|
21
|
+
w,
|
|
22
|
+
days: d,
|
|
23
|
+
day: d,
|
|
24
|
+
d,
|
|
25
|
+
hours: h,
|
|
26
|
+
hour: h,
|
|
27
|
+
hrs: h,
|
|
28
|
+
hr: h,
|
|
29
|
+
h,
|
|
30
|
+
minutes: m,
|
|
31
|
+
minute: m,
|
|
32
|
+
mins: m,
|
|
33
|
+
min: m,
|
|
34
|
+
m,
|
|
35
|
+
seconds: s,
|
|
36
|
+
second: s,
|
|
37
|
+
secs: s,
|
|
38
|
+
sec: s,
|
|
39
|
+
s,
|
|
40
|
+
milliseconds: 1,
|
|
41
|
+
millisecond: 1,
|
|
42
|
+
msecs: 1,
|
|
43
|
+
msec: 1,
|
|
44
|
+
ms: 1
|
|
45
|
+
};
|
|
46
|
+
const ms = (val) => {
|
|
47
|
+
const str = String(val);
|
|
48
|
+
if (str.length > 100) return 0;
|
|
49
|
+
const match = RE.exec(str);
|
|
50
|
+
if (!match) return 0;
|
|
51
|
+
const n = Number.parseFloat(match[1] ?? "");
|
|
52
|
+
const type = (match[2] ?? "ms").toLowerCase();
|
|
53
|
+
return n * (UNITS[type] ?? 0);
|
|
54
|
+
};
|
|
8
55
|
|
|
9
56
|
var __typeError$3 = (msg) => {
|
|
10
57
|
throw TypeError(msg);
|
|
@@ -46,7 +93,7 @@ class MemoryCacheEngine {
|
|
|
46
93
|
}
|
|
47
94
|
_cache = new WeakMap();
|
|
48
95
|
|
|
49
|
-
const isMongooseLessThan7 =
|
|
96
|
+
const isMongooseLessThan7 = Number.parseInt(mongoose.version, 10) < 7;
|
|
50
97
|
const convertToObject = (value) => {
|
|
51
98
|
if (isMongooseLessThan7) {
|
|
52
99
|
if (value != null && typeof value === "object" && !Array.isArray(value) && value.toObject) {
|
|
@@ -174,8 +221,42 @@ _defaultTTL = new WeakMap();
|
|
|
174
221
|
_debug = new WeakMap();
|
|
175
222
|
_engines = new WeakMap();
|
|
176
223
|
|
|
224
|
+
const isPlainObject = (value) => {
|
|
225
|
+
if (typeof value !== "object" || value === null) return false;
|
|
226
|
+
const proto = Object.getPrototypeOf(value);
|
|
227
|
+
return proto === Object.prototype || proto === null;
|
|
228
|
+
};
|
|
229
|
+
const sortKeys = (input) => {
|
|
230
|
+
const seen = /* @__PURE__ */ new WeakSet();
|
|
231
|
+
const sortObject = (obj) => {
|
|
232
|
+
if (seen.has(obj)) return obj;
|
|
233
|
+
seen.add(obj);
|
|
234
|
+
const sorted = {};
|
|
235
|
+
for (const key of Object.keys(obj).sort((a, b) => a.localeCompare(b))) {
|
|
236
|
+
const value = obj[key];
|
|
237
|
+
if (Array.isArray(value)) {
|
|
238
|
+
sorted[key] = sortArray(value);
|
|
239
|
+
} else if (isPlainObject(value)) {
|
|
240
|
+
sorted[key] = sortObject(value);
|
|
241
|
+
} else {
|
|
242
|
+
sorted[key] = value;
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
return sorted;
|
|
246
|
+
};
|
|
247
|
+
const sortArray = (arr) => {
|
|
248
|
+
return arr.map((item) => {
|
|
249
|
+
if (Array.isArray(item)) return sortArray(item);
|
|
250
|
+
if (isPlainObject(item)) return sortObject(item);
|
|
251
|
+
return item;
|
|
252
|
+
});
|
|
253
|
+
};
|
|
254
|
+
if (Array.isArray(input)) return sortArray(input);
|
|
255
|
+
return sortObject(input);
|
|
256
|
+
};
|
|
257
|
+
|
|
177
258
|
function getKey(data) {
|
|
178
|
-
const sortedObj = sortKeys(data
|
|
259
|
+
const sortedObj = sortKeys(data);
|
|
179
260
|
const sortedStr = JSON.stringify(sortedObj, (_, val) => {
|
|
180
261
|
return val instanceof RegExp ? String(val) : val;
|
|
181
262
|
});
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var common = require('@nestjs/common');
|
|
4
|
+
var mongoose = require('mongoose');
|
|
5
|
+
var index = require('../index.cjs');
|
|
6
|
+
require('bson');
|
|
7
|
+
require('ioredis');
|
|
8
|
+
require('node:crypto');
|
|
9
|
+
|
|
10
|
+
const CACHE_OPTIONS = Symbol("CACHE_OPTIONS");
|
|
11
|
+
class CacheService {
|
|
12
|
+
constructor(options) {
|
|
13
|
+
this.logger = new common.Logger(CacheService.name);
|
|
14
|
+
this.options = options;
|
|
15
|
+
}
|
|
16
|
+
get instance() {
|
|
17
|
+
return this.cacheMongoose;
|
|
18
|
+
}
|
|
19
|
+
async onApplicationBootstrap() {
|
|
20
|
+
this.cacheMongoose = index.init(mongoose, this.options);
|
|
21
|
+
this.logger.log(`Cache initialized with ${this.options.engine} engine`);
|
|
22
|
+
}
|
|
23
|
+
async onApplicationShutdown() {
|
|
24
|
+
if (this.cacheMongoose) {
|
|
25
|
+
await this.cacheMongoose.close();
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
async clear(customKey) {
|
|
29
|
+
await this.cacheMongoose.clear(customKey);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
34
|
+
var __decorateClass = (decorators, target, key, kind) => {
|
|
35
|
+
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
|
|
36
|
+
for (var i = decorators.length - 1, decorator; i >= 0; i--)
|
|
37
|
+
if (decorator = decorators[i])
|
|
38
|
+
result = (decorator(result)) || result;
|
|
39
|
+
return result;
|
|
40
|
+
};
|
|
41
|
+
exports.CacheModule = class CacheModule {
|
|
42
|
+
static forRoot(options) {
|
|
43
|
+
return {
|
|
44
|
+
module: exports.CacheModule,
|
|
45
|
+
global: options.isGlobal ?? false,
|
|
46
|
+
providers: [
|
|
47
|
+
{ provide: CACHE_OPTIONS, useValue: options },
|
|
48
|
+
{
|
|
49
|
+
provide: CacheService,
|
|
50
|
+
useFactory: (opts) => new CacheService(opts),
|
|
51
|
+
inject: [CACHE_OPTIONS]
|
|
52
|
+
}
|
|
53
|
+
],
|
|
54
|
+
exports: [CacheService]
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
static forRootAsync(options) {
|
|
58
|
+
const asyncProviders = exports.CacheModule.createAsyncProviders(options);
|
|
59
|
+
return {
|
|
60
|
+
module: exports.CacheModule,
|
|
61
|
+
global: options.isGlobal ?? false,
|
|
62
|
+
imports: options.imports ?? [],
|
|
63
|
+
providers: [
|
|
64
|
+
...asyncProviders,
|
|
65
|
+
{
|
|
66
|
+
provide: CacheService,
|
|
67
|
+
useFactory: (opts) => new CacheService(opts),
|
|
68
|
+
inject: [CACHE_OPTIONS]
|
|
69
|
+
}
|
|
70
|
+
],
|
|
71
|
+
exports: [CacheService]
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
static createAsyncProviders(options) {
|
|
75
|
+
if (options.useFactory) {
|
|
76
|
+
return [
|
|
77
|
+
{
|
|
78
|
+
provide: CACHE_OPTIONS,
|
|
79
|
+
useFactory: options.useFactory,
|
|
80
|
+
inject: options.inject ?? []
|
|
81
|
+
}
|
|
82
|
+
];
|
|
83
|
+
}
|
|
84
|
+
if (options.useClass) {
|
|
85
|
+
return [
|
|
86
|
+
{ provide: options.useClass, useClass: options.useClass },
|
|
87
|
+
{
|
|
88
|
+
provide: CACHE_OPTIONS,
|
|
89
|
+
useFactory: (factory) => factory.createCacheOptions(),
|
|
90
|
+
inject: [options.useClass]
|
|
91
|
+
}
|
|
92
|
+
];
|
|
93
|
+
}
|
|
94
|
+
if (options.useExisting) {
|
|
95
|
+
return [
|
|
96
|
+
{
|
|
97
|
+
provide: CACHE_OPTIONS,
|
|
98
|
+
useFactory: (factory) => factory.createCacheOptions(),
|
|
99
|
+
inject: [options.useExisting]
|
|
100
|
+
}
|
|
101
|
+
];
|
|
102
|
+
}
|
|
103
|
+
return [];
|
|
104
|
+
}
|
|
105
|
+
};
|
|
106
|
+
exports.CacheModule = __decorateClass([
|
|
107
|
+
common.Module({})
|
|
108
|
+
], exports.CacheModule);
|
|
109
|
+
|
|
110
|
+
exports.CACHE_OPTIONS = CACHE_OPTIONS;
|
|
111
|
+
exports.CacheService = CacheService;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { ModuleMetadata, InjectionToken, OptionalFactoryDependency, Type, DynamicModule, OnApplicationBootstrap, OnApplicationShutdown } from '@nestjs/common';
|
|
2
|
+
import CacheMongoose, { CacheOptions } from '../index.cjs';
|
|
3
|
+
import 'mongoose';
|
|
4
|
+
import 'ioredis';
|
|
5
|
+
|
|
6
|
+
type CacheModuleOptions = CacheOptions;
|
|
7
|
+
interface CacheOptionsFactory {
|
|
8
|
+
createCacheOptions(): CacheModuleOptions | Promise<CacheModuleOptions>;
|
|
9
|
+
}
|
|
10
|
+
interface CacheModuleAsyncOptions extends Pick<ModuleMetadata, 'imports'> {
|
|
11
|
+
isGlobal?: boolean;
|
|
12
|
+
inject?: (InjectionToken | OptionalFactoryDependency)[];
|
|
13
|
+
useClass?: Type<CacheOptionsFactory>;
|
|
14
|
+
useExisting?: Type<CacheOptionsFactory>;
|
|
15
|
+
useFactory?: (...args: any[]) => CacheModuleOptions | Promise<CacheModuleOptions>;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
declare class CacheModule {
|
|
19
|
+
static forRoot(options: CacheModuleOptions & {
|
|
20
|
+
isGlobal?: boolean;
|
|
21
|
+
}): DynamicModule;
|
|
22
|
+
static forRootAsync(options: CacheModuleAsyncOptions): DynamicModule;
|
|
23
|
+
private static createAsyncProviders;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
declare const CACHE_OPTIONS: unique symbol;
|
|
27
|
+
declare class CacheService implements OnApplicationBootstrap, OnApplicationShutdown {
|
|
28
|
+
private readonly logger;
|
|
29
|
+
private readonly options;
|
|
30
|
+
private cacheMongoose;
|
|
31
|
+
constructor(options: CacheModuleOptions);
|
|
32
|
+
get instance(): CacheMongoose;
|
|
33
|
+
onApplicationBootstrap(): Promise<void>;
|
|
34
|
+
onApplicationShutdown(): Promise<void>;
|
|
35
|
+
clear(customKey?: string): Promise<void>;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export { CACHE_OPTIONS, CacheModule, CacheService };
|
|
39
|
+
export type { CacheModuleAsyncOptions, CacheModuleOptions, CacheOptionsFactory };
|
|
40
|
+
//# sourceMappingURL=index.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.cts","sources":["../../src/nest/interfaces.ts","../../src/nest/cache.module.ts","../../src/nest/cache.service.ts"],"mappings":";;;;;AAGM,KAAM,kBAAkB,GAAG,YAAY;AAEvC,UAAW,mBAAmB;0BACZ,kBAAkB,GAAG,OAAO,CAAC,kBAAkB;;AAGjE,UAAW,uBAAwB,SAAQ,IAAI,CAAC,cAAc;;cAExD,cAAc,GAAG,yBAAyB;eACzC,IAAI,CAAC,mBAAmB;kBACrB,IAAI,CAAC,mBAAmB;qCAEL,kBAAkB,GAAG,OAAO,CAAC,kBAAkB;;;ACRlF,cACa,WAAW;4BACE,kBAAkB;;QAA4B,aAAa;iCAgBtD,uBAAuB,GAAG,aAAa;;;;AClBtE,cAAa,aAAa;AAE1B,cAAa,YAAa,YAAW,sBAAsB,EAAE,qBAAqB;;;;yBAK3D,kBAAkB;oBAIvB,aAAa;8BAIG,OAAO;6BAKR,OAAO;+BAML,OAAO","names":[]}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { ModuleMetadata, InjectionToken, OptionalFactoryDependency, Type, DynamicModule, OnApplicationBootstrap, OnApplicationShutdown } from '@nestjs/common';
|
|
2
|
+
import CacheMongoose, { CacheOptions } from '../index.mjs';
|
|
3
|
+
import 'mongoose';
|
|
4
|
+
import 'ioredis';
|
|
5
|
+
|
|
6
|
+
type CacheModuleOptions = CacheOptions;
|
|
7
|
+
interface CacheOptionsFactory {
|
|
8
|
+
createCacheOptions(): CacheModuleOptions | Promise<CacheModuleOptions>;
|
|
9
|
+
}
|
|
10
|
+
interface CacheModuleAsyncOptions extends Pick<ModuleMetadata, 'imports'> {
|
|
11
|
+
isGlobal?: boolean;
|
|
12
|
+
inject?: (InjectionToken | OptionalFactoryDependency)[];
|
|
13
|
+
useClass?: Type<CacheOptionsFactory>;
|
|
14
|
+
useExisting?: Type<CacheOptionsFactory>;
|
|
15
|
+
useFactory?: (...args: any[]) => CacheModuleOptions | Promise<CacheModuleOptions>;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
declare class CacheModule {
|
|
19
|
+
static forRoot(options: CacheModuleOptions & {
|
|
20
|
+
isGlobal?: boolean;
|
|
21
|
+
}): DynamicModule;
|
|
22
|
+
static forRootAsync(options: CacheModuleAsyncOptions): DynamicModule;
|
|
23
|
+
private static createAsyncProviders;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
declare const CACHE_OPTIONS: unique symbol;
|
|
27
|
+
declare class CacheService implements OnApplicationBootstrap, OnApplicationShutdown {
|
|
28
|
+
private readonly logger;
|
|
29
|
+
private readonly options;
|
|
30
|
+
private cacheMongoose;
|
|
31
|
+
constructor(options: CacheModuleOptions);
|
|
32
|
+
get instance(): CacheMongoose;
|
|
33
|
+
onApplicationBootstrap(): Promise<void>;
|
|
34
|
+
onApplicationShutdown(): Promise<void>;
|
|
35
|
+
clear(customKey?: string): Promise<void>;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export { CACHE_OPTIONS, CacheModule, CacheService };
|
|
39
|
+
export type { CacheModuleAsyncOptions, CacheModuleOptions, CacheOptionsFactory };
|
|
40
|
+
//# sourceMappingURL=index.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.mts","sources":["../../src/nest/interfaces.ts","../../src/nest/cache.module.ts","../../src/nest/cache.service.ts"],"mappings":";;;;;AAGM,KAAM,kBAAkB,GAAG,YAAY;AAEvC,UAAW,mBAAmB;0BACZ,kBAAkB,GAAG,OAAO,CAAC,kBAAkB;;AAGjE,UAAW,uBAAwB,SAAQ,IAAI,CAAC,cAAc;;cAExD,cAAc,GAAG,yBAAyB;eACzC,IAAI,CAAC,mBAAmB;kBACrB,IAAI,CAAC,mBAAmB;qCAEL,kBAAkB,GAAG,OAAO,CAAC,kBAAkB;;;ACRlF,cACa,WAAW;4BACE,kBAAkB;;QAA4B,aAAa;iCAgBtD,uBAAuB,GAAG,aAAa;;;;AClBtE,cAAa,aAAa;AAE1B,cAAa,YAAa,YAAW,sBAAsB,EAAE,qBAAqB;;;;yBAK3D,kBAAkB;oBAIvB,aAAa;8BAIG,OAAO;6BAKR,OAAO;+BAML,OAAO","names":[]}
|