ts-cache-mongoose 1.7.7 → 2.1.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 +88 -66
- package/biome.json +1 -1
- package/dist/index.cjs +140 -93
- package/dist/index.d.cts +48 -11
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +48 -11
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +140 -93
- package/dist/nest/index.cjs +113 -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 +110 -0
- package/package.json +44 -22
- package/src/cache/Cache.ts +5 -5
- package/src/cache/engine/MemoryCacheEngine.ts +4 -4
- package/src/cache/engine/RedisCacheEngine.ts +4 -4
- package/src/extend/aggregate.ts +5 -6
- package/src/extend/query.ts +5 -6
- package/src/index.ts +7 -7
- package/src/key.ts +2 -2
- package/src/ms.ts +66 -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 +4 -4
- package/src/version.ts +1 -2
- package/tests/ms.test.ts +113 -0
- package/tests/nest.test.ts +158 -0
- package/tests/sort-keys.test.ts +80 -0
- package/tsconfig.json +3 -3
|
@@ -0,0 +1,113 @@
|
|
|
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
|
+
logger = new common.Logger(CacheService.name);
|
|
13
|
+
options;
|
|
14
|
+
cacheMongoose;
|
|
15
|
+
constructor(options) {
|
|
16
|
+
this.options = options;
|
|
17
|
+
}
|
|
18
|
+
get instance() {
|
|
19
|
+
return this.cacheMongoose;
|
|
20
|
+
}
|
|
21
|
+
async onApplicationBootstrap() {
|
|
22
|
+
this.cacheMongoose = index.init(mongoose, this.options);
|
|
23
|
+
this.logger.log(`Cache initialized with ${this.options.engine} engine`);
|
|
24
|
+
}
|
|
25
|
+
async onApplicationShutdown() {
|
|
26
|
+
if (this.cacheMongoose) {
|
|
27
|
+
await this.cacheMongoose.close();
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
async clear(customKey) {
|
|
31
|
+
await this.cacheMongoose.clear(customKey);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
36
|
+
var __decorateClass = (decorators, target, key, kind) => {
|
|
37
|
+
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
|
|
38
|
+
for (var i = decorators.length - 1, decorator; i >= 0; i--)
|
|
39
|
+
if (decorator = decorators[i])
|
|
40
|
+
result = (decorator(result)) || result;
|
|
41
|
+
return result;
|
|
42
|
+
};
|
|
43
|
+
exports.CacheModule = class CacheModule {
|
|
44
|
+
static forRoot(options) {
|
|
45
|
+
return {
|
|
46
|
+
module: exports.CacheModule,
|
|
47
|
+
global: options.isGlobal ?? false,
|
|
48
|
+
providers: [
|
|
49
|
+
{ provide: CACHE_OPTIONS, useValue: options },
|
|
50
|
+
{
|
|
51
|
+
provide: CacheService,
|
|
52
|
+
useFactory: (opts) => new CacheService(opts),
|
|
53
|
+
inject: [CACHE_OPTIONS]
|
|
54
|
+
}
|
|
55
|
+
],
|
|
56
|
+
exports: [CacheService]
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
static forRootAsync(options) {
|
|
60
|
+
const asyncProviders = exports.CacheModule.createAsyncProviders(options);
|
|
61
|
+
return {
|
|
62
|
+
module: exports.CacheModule,
|
|
63
|
+
global: options.isGlobal ?? false,
|
|
64
|
+
imports: options.imports ?? [],
|
|
65
|
+
providers: [
|
|
66
|
+
...asyncProviders,
|
|
67
|
+
{
|
|
68
|
+
provide: CacheService,
|
|
69
|
+
useFactory: (opts) => new CacheService(opts),
|
|
70
|
+
inject: [CACHE_OPTIONS]
|
|
71
|
+
}
|
|
72
|
+
],
|
|
73
|
+
exports: [CacheService]
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
static createAsyncProviders(options) {
|
|
77
|
+
if (options.useFactory) {
|
|
78
|
+
return [
|
|
79
|
+
{
|
|
80
|
+
provide: CACHE_OPTIONS,
|
|
81
|
+
useFactory: options.useFactory,
|
|
82
|
+
inject: options.inject ?? []
|
|
83
|
+
}
|
|
84
|
+
];
|
|
85
|
+
}
|
|
86
|
+
if (options.useClass) {
|
|
87
|
+
return [
|
|
88
|
+
{ provide: options.useClass, useClass: options.useClass },
|
|
89
|
+
{
|
|
90
|
+
provide: CACHE_OPTIONS,
|
|
91
|
+
useFactory: (factory) => factory.createCacheOptions(),
|
|
92
|
+
inject: [options.useClass]
|
|
93
|
+
}
|
|
94
|
+
];
|
|
95
|
+
}
|
|
96
|
+
if (options.useExisting) {
|
|
97
|
+
return [
|
|
98
|
+
{
|
|
99
|
+
provide: CACHE_OPTIONS,
|
|
100
|
+
useFactory: (factory) => factory.createCacheOptions(),
|
|
101
|
+
inject: [options.useExisting]
|
|
102
|
+
}
|
|
103
|
+
];
|
|
104
|
+
}
|
|
105
|
+
return [];
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
exports.CacheModule = __decorateClass([
|
|
109
|
+
common.Module({})
|
|
110
|
+
], exports.CacheModule);
|
|
111
|
+
|
|
112
|
+
exports.CACHE_OPTIONS = CACHE_OPTIONS;
|
|
113
|
+
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":[]}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { Logger, Module } from '@nestjs/common';
|
|
2
|
+
import mongoose from 'mongoose';
|
|
3
|
+
import CacheMongoose from '../index.mjs';
|
|
4
|
+
import 'bson';
|
|
5
|
+
import 'ioredis';
|
|
6
|
+
import 'node:crypto';
|
|
7
|
+
|
|
8
|
+
const CACHE_OPTIONS = Symbol("CACHE_OPTIONS");
|
|
9
|
+
class CacheService {
|
|
10
|
+
logger = new Logger(CacheService.name);
|
|
11
|
+
options;
|
|
12
|
+
cacheMongoose;
|
|
13
|
+
constructor(options) {
|
|
14
|
+
this.options = options;
|
|
15
|
+
}
|
|
16
|
+
get instance() {
|
|
17
|
+
return this.cacheMongoose;
|
|
18
|
+
}
|
|
19
|
+
async onApplicationBootstrap() {
|
|
20
|
+
this.cacheMongoose = CacheMongoose.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
|
+
let CacheModule = class {
|
|
42
|
+
static forRoot(options) {
|
|
43
|
+
return {
|
|
44
|
+
module: 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 = CacheModule.createAsyncProviders(options);
|
|
59
|
+
return {
|
|
60
|
+
module: 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
|
+
CacheModule = __decorateClass([
|
|
107
|
+
Module({})
|
|
108
|
+
], CacheModule);
|
|
109
|
+
|
|
110
|
+
export { CACHE_OPTIONS, CacheModule, CacheService };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ts-cache-mongoose",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "2.1.0",
|
|
4
4
|
"description": "Cache plugin for mongoose Queries and Aggregate (in-memory, redis)",
|
|
5
5
|
"author": "ilovepixelart",
|
|
6
6
|
"license": "MIT",
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"aggregate"
|
|
36
36
|
],
|
|
37
37
|
"engines": {
|
|
38
|
-
"node": ">=
|
|
38
|
+
"node": ">=18"
|
|
39
39
|
},
|
|
40
40
|
"files": [
|
|
41
41
|
"dist",
|
|
@@ -47,13 +47,32 @@
|
|
|
47
47
|
],
|
|
48
48
|
"type": "module",
|
|
49
49
|
"exports": {
|
|
50
|
-
"
|
|
51
|
-
"
|
|
52
|
-
|
|
50
|
+
".": {
|
|
51
|
+
"require": {
|
|
52
|
+
"types": "./dist/index.d.cts",
|
|
53
|
+
"default": "./dist/index.cjs"
|
|
54
|
+
},
|
|
55
|
+
"import": {
|
|
56
|
+
"types": "./dist/index.d.mts",
|
|
57
|
+
"default": "./dist/index.mjs"
|
|
58
|
+
}
|
|
53
59
|
},
|
|
54
|
-
"
|
|
55
|
-
"
|
|
56
|
-
|
|
60
|
+
"./nest": {
|
|
61
|
+
"require": {
|
|
62
|
+
"types": "./dist/nest/index.d.cts",
|
|
63
|
+
"default": "./dist/nest/index.cjs"
|
|
64
|
+
},
|
|
65
|
+
"import": {
|
|
66
|
+
"types": "./dist/nest/index.d.mts",
|
|
67
|
+
"default": "./dist/nest/index.mjs"
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
},
|
|
71
|
+
"typesVersions": {
|
|
72
|
+
"*": {
|
|
73
|
+
"nest": [
|
|
74
|
+
"./dist/nest/index.d.cts"
|
|
75
|
+
]
|
|
57
76
|
}
|
|
58
77
|
},
|
|
59
78
|
"main": "./dist/index.cjs",
|
|
@@ -71,31 +90,33 @@
|
|
|
71
90
|
"release": "npm install && npm run biome && npm run type:check && npm run build && np --no-publish"
|
|
72
91
|
},
|
|
73
92
|
"dependencies": {
|
|
74
|
-
"
|
|
75
|
-
"@types/semver": "7.7.1",
|
|
76
|
-
"ioredis": "5.9.3",
|
|
77
|
-
"ms": "2.1.3",
|
|
78
|
-
"semver": "7.7.4",
|
|
79
|
-
"sort-keys": "4.2.0"
|
|
93
|
+
"ioredis": "5.10.0"
|
|
80
94
|
},
|
|
81
95
|
"devDependencies": {
|
|
82
|
-
"@biomejs/biome": "2.4.
|
|
83
|
-
"@
|
|
84
|
-
"@
|
|
96
|
+
"@biomejs/biome": "2.4.7",
|
|
97
|
+
"@nestjs/common": "11.1.16",
|
|
98
|
+
"@types/node": "25.5.0",
|
|
99
|
+
"@vitest/coverage-v8": "4.1.0",
|
|
85
100
|
"bson": "7.2.0",
|
|
86
101
|
"mongodb-memory-server": "11.0.1",
|
|
87
|
-
"mongoose": "9.
|
|
102
|
+
"mongoose": "9.3.0",
|
|
103
|
+
"np": "11.0.2",
|
|
88
104
|
"open-cli": "8.0.0",
|
|
89
|
-
"pkgroll": "2.
|
|
105
|
+
"pkgroll": "2.27.0",
|
|
90
106
|
"simple-git-hooks": "2.13.1",
|
|
91
107
|
"typescript": "5.9.3",
|
|
92
|
-
"vitest": "4.0
|
|
93
|
-
"np": "11.0.2"
|
|
108
|
+
"vitest": "4.1.0"
|
|
94
109
|
},
|
|
95
110
|
"peerDependencies": {
|
|
111
|
+
"@nestjs/common": ">=9.0.0",
|
|
96
112
|
"bson": ">=4.7.2 < 8",
|
|
97
113
|
"mongoose": ">=6.6.0 < 10"
|
|
98
114
|
},
|
|
115
|
+
"peerDependenciesMeta": {
|
|
116
|
+
"@nestjs/common": {
|
|
117
|
+
"optional": true
|
|
118
|
+
}
|
|
119
|
+
},
|
|
99
120
|
"simple-git-hooks": {
|
|
100
121
|
"pre-commit": "npm run type:check",
|
|
101
122
|
"pre-push": "npm run biome:fix"
|
|
@@ -104,6 +125,7 @@
|
|
|
104
125
|
"publish": false
|
|
105
126
|
},
|
|
106
127
|
"overrides": {
|
|
107
|
-
"
|
|
128
|
+
"tmp": "0.2.5",
|
|
129
|
+
"file-type": "21.3.2"
|
|
108
130
|
}
|
|
109
131
|
}
|
package/src/cache/Cache.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import ms from 'ms'
|
|
1
|
+
import { ms } from '../ms'
|
|
2
2
|
import { MemoryCacheEngine } from './engine/MemoryCacheEngine'
|
|
3
3
|
import { RedisCacheEngine } from './engine/RedisCacheEngine'
|
|
4
4
|
|
|
5
|
-
import type { CacheData, CacheEngine, CacheOptions,
|
|
5
|
+
import type { CacheData, CacheEngine, CacheOptions, Duration } from '../types'
|
|
6
6
|
|
|
7
7
|
export class Cache {
|
|
8
8
|
readonly #engine!: CacheEngine
|
|
@@ -21,7 +21,7 @@ export class Cache {
|
|
|
21
21
|
|
|
22
22
|
cacheOptions.defaultTTL ??= '1 minute'
|
|
23
23
|
|
|
24
|
-
this.#defaultTTL =
|
|
24
|
+
this.#defaultTTL = ms(cacheOptions.defaultTTL)
|
|
25
25
|
|
|
26
26
|
if (cacheOptions.engine === 'redis' && cacheOptions.engineOptions) {
|
|
27
27
|
this.#engine = new RedisCacheEngine(cacheOptions.engineOptions)
|
|
@@ -43,8 +43,8 @@ export class Cache {
|
|
|
43
43
|
return cacheEntry
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
-
async set(key: string, value: CacheData, ttl:
|
|
47
|
-
const givenTTL =
|
|
46
|
+
async set(key: string, value: CacheData, ttl: Duration | null): Promise<void> {
|
|
47
|
+
const givenTTL = ttl == null ? null : ms(ttl)
|
|
48
48
|
const actualTTL = givenTTL ?? this.#defaultTTL
|
|
49
49
|
await this.#engine.set(key, value, actualTTL)
|
|
50
50
|
if (this.#debug) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import ms from 'ms'
|
|
1
|
+
import { ms } from '../../ms'
|
|
2
2
|
|
|
3
|
-
import type { CacheData, CacheEngine,
|
|
3
|
+
import type { CacheData, CacheEngine, Duration } from '../../types'
|
|
4
4
|
|
|
5
5
|
export class MemoryCacheEngine implements CacheEngine {
|
|
6
6
|
readonly #cache: Map<string, { value: CacheData; expiresAt: number } | undefined>
|
|
@@ -18,8 +18,8 @@ export class MemoryCacheEngine implements CacheEngine {
|
|
|
18
18
|
return item.value
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
set(key: string, value: CacheData, ttl?:
|
|
22
|
-
const givenTTL =
|
|
21
|
+
set(key: string, value: CacheData, ttl?: Duration): void {
|
|
22
|
+
const givenTTL = ttl == null ? undefined : ms(ttl)
|
|
23
23
|
const actualTTL = givenTTL ?? Number.POSITIVE_INFINITY
|
|
24
24
|
this.#cache.set(key, {
|
|
25
25
|
value,
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { EJSON } from 'bson'
|
|
2
2
|
import IORedis from 'ioredis'
|
|
3
|
-
import ms from 'ms'
|
|
3
|
+
import { ms } from '../../ms'
|
|
4
4
|
import { convertToObject } from '../../version'
|
|
5
5
|
|
|
6
6
|
import type { Redis, RedisOptions } from 'ioredis'
|
|
7
|
-
import type { CacheData, CacheEngine,
|
|
7
|
+
import type { CacheData, CacheEngine, Duration } from '../../types'
|
|
8
8
|
|
|
9
9
|
export class RedisCacheEngine implements CacheEngine {
|
|
10
10
|
readonly #client: Redis
|
|
@@ -27,9 +27,9 @@ export class RedisCacheEngine implements CacheEngine {
|
|
|
27
27
|
}
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
async set(key: string, value: CacheData, ttl?:
|
|
30
|
+
async set(key: string, value: CacheData, ttl?: Duration): Promise<void> {
|
|
31
31
|
try {
|
|
32
|
-
const givenTTL =
|
|
32
|
+
const givenTTL = ttl == null ? undefined : ms(ttl)
|
|
33
33
|
const actualTTL = givenTTL ?? Number.POSITIVE_INFINITY
|
|
34
34
|
const serializedValue = EJSON.stringify(convertToObject(value))
|
|
35
35
|
await this.#client.setex(key, Math.ceil(actualTTL / 1000), serializedValue)
|
package/src/extend/aggregate.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { getKey } from '../key'
|
|
|
2
2
|
|
|
3
3
|
import type { Mongoose } from 'mongoose'
|
|
4
4
|
import type { Cache } from '../cache/Cache'
|
|
5
|
-
import type {
|
|
5
|
+
import type { Duration } from '../types'
|
|
6
6
|
|
|
7
7
|
export function extendAggregate(mongoose: Mongoose, cache: Cache): void {
|
|
8
8
|
const mongooseExec = mongoose.Aggregate.prototype.exec
|
|
@@ -15,24 +15,23 @@ export function extendAggregate(mongoose: Mongoose, cache: Cache): void {
|
|
|
15
15
|
})
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
-
mongoose.Aggregate.prototype.
|
|
18
|
+
mongoose.Aggregate.prototype.getDuration = function (): Duration | null {
|
|
19
19
|
return this._ttl
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
-
mongoose.Aggregate.prototype.cache = function (ttl?:
|
|
22
|
+
mongoose.Aggregate.prototype.cache = function (ttl?: Duration, customKey?: string) {
|
|
23
23
|
this._ttl = ttl ?? null
|
|
24
24
|
this._key = customKey ?? null
|
|
25
25
|
return this
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
mongoose.Aggregate.prototype.exec = async function (...args: []) {
|
|
29
|
-
|
|
30
|
-
if (!Object.prototype.hasOwnProperty.call(this, '_ttl')) {
|
|
29
|
+
if (!Object.hasOwn(this, '_ttl')) {
|
|
31
30
|
return mongooseExec.apply(this, args)
|
|
32
31
|
}
|
|
33
32
|
|
|
34
33
|
const key = this.getCacheKey()
|
|
35
|
-
const ttl = this.
|
|
34
|
+
const ttl = this.getDuration()
|
|
36
35
|
|
|
37
36
|
const resultCache = await cache.get(key).catch((err: unknown) => {
|
|
38
37
|
console.error(err)
|
package/src/extend/query.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { getKey } from '../key'
|
|
|
2
2
|
|
|
3
3
|
import type { Mongoose } from 'mongoose'
|
|
4
4
|
import type { Cache } from '../cache/Cache'
|
|
5
|
-
import type {
|
|
5
|
+
import type { Duration } from '../types'
|
|
6
6
|
|
|
7
7
|
export function extendQuery(mongoose: Mongoose, cache: Cache): void {
|
|
8
8
|
const mongooseExec = mongoose.Query.prototype.exec
|
|
@@ -29,24 +29,23 @@ export function extendQuery(mongoose: Mongoose, cache: Cache): void {
|
|
|
29
29
|
})
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
-
mongoose.Query.prototype.
|
|
32
|
+
mongoose.Query.prototype.getDuration = function (): Duration | null {
|
|
33
33
|
return this._ttl
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
-
mongoose.Query.prototype.cache = function (ttl?:
|
|
36
|
+
mongoose.Query.prototype.cache = function (ttl?: Duration, customKey?: string) {
|
|
37
37
|
this._ttl = ttl ?? null
|
|
38
38
|
this._key = customKey ?? null
|
|
39
39
|
return this
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
mongoose.Query.prototype.exec = async function (...args: []) {
|
|
43
|
-
|
|
44
|
-
if (!Object.prototype.hasOwnProperty.call(this, '_ttl')) {
|
|
43
|
+
if (!Object.hasOwn(this, '_ttl')) {
|
|
45
44
|
return mongooseExec.apply(this, args)
|
|
46
45
|
}
|
|
47
46
|
|
|
48
47
|
const key = this.getCacheKey()
|
|
49
|
-
const ttl = this.
|
|
48
|
+
const ttl = this.getDuration()
|
|
50
49
|
const mongooseOptions = this.mongooseOptions()
|
|
51
50
|
|
|
52
51
|
const isCount = this.op?.includes('count') ?? false
|
package/src/index.ts
CHANGED
|
@@ -3,17 +3,17 @@ import { extendAggregate } from './extend/aggregate'
|
|
|
3
3
|
import { extendQuery } from './extend/query'
|
|
4
4
|
|
|
5
5
|
import type { Mongoose } from 'mongoose'
|
|
6
|
-
import type { CacheOptions,
|
|
6
|
+
import type { CacheOptions, Duration } from './types'
|
|
7
7
|
|
|
8
8
|
export * from './types'
|
|
9
9
|
|
|
10
10
|
declare module 'mongoose' {
|
|
11
11
|
interface Query<ResultType, DocType, THelpers, RawDocType> {
|
|
12
|
-
cache: (this: Query<ResultType, DocType, THelpers, RawDocType>, ttl?:
|
|
12
|
+
cache: (this: Query<ResultType, DocType, THelpers, RawDocType>, ttl?: Duration, customKey?: string) => this
|
|
13
13
|
_key: string | null
|
|
14
14
|
getCacheKey: (this: Query<ResultType, DocType, THelpers, RawDocType>) => string
|
|
15
|
-
_ttl:
|
|
16
|
-
|
|
15
|
+
_ttl: Duration | null
|
|
16
|
+
getDuration: (this: Query<ResultType, DocType, THelpers, RawDocType>) => Duration | null
|
|
17
17
|
op?: string
|
|
18
18
|
_path?: unknown
|
|
19
19
|
_fields?: unknown
|
|
@@ -22,11 +22,11 @@ declare module 'mongoose' {
|
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
interface Aggregate<ResultType> {
|
|
25
|
-
cache: (this: Aggregate<ResultType>, ttl?:
|
|
25
|
+
cache: (this: Aggregate<ResultType>, ttl?: Duration, customKey?: string) => this
|
|
26
26
|
_key: string | null
|
|
27
27
|
getCacheKey: (this: Aggregate<ResultType>) => string
|
|
28
|
-
_ttl:
|
|
29
|
-
|
|
28
|
+
_ttl: Duration | null
|
|
29
|
+
getDuration: (this: Aggregate<ResultType>) => Duration | null
|
|
30
30
|
}
|
|
31
31
|
}
|
|
32
32
|
|
package/src/key.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { createHash } from 'node:crypto'
|
|
2
|
-
import sortKeys from 'sort-keys'
|
|
2
|
+
import { sortKeys } from './sort-keys'
|
|
3
3
|
|
|
4
4
|
export function getKey(data: Record<string, unknown>[] | Record<string, unknown>): string {
|
|
5
|
-
const sortedObj = sortKeys(data
|
|
5
|
+
const sortedObj = sortKeys(data)
|
|
6
6
|
const sortedStr = JSON.stringify(sortedObj, (_, val: unknown) => {
|
|
7
7
|
return val instanceof RegExp ? String(val) : val
|
|
8
8
|
})
|