@tsed/platform-cache 7.2.3 → 7.3.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/lib/cjs/interceptors/PlatformCacheInterceptor.js +1 -1
- package/lib/cjs/interceptors/PlatformCacheInterceptor.js.map +1 -1
- package/lib/cjs/interfaces/PlatformCacheOptions.js.map +1 -1
- package/lib/cjs/interfaces/interfaces.js.map +1 -1
- package/lib/cjs/services/PlatformCache.js +19 -8
- package/lib/cjs/services/PlatformCache.js.map +1 -1
- package/lib/esm/interceptors/PlatformCacheInterceptor.js +1 -1
- package/lib/esm/interceptors/PlatformCacheInterceptor.js.map +1 -1
- package/lib/esm/interfaces/PlatformCacheOptions.js.map +1 -1
- package/lib/esm/interfaces/interfaces.js.map +1 -1
- package/lib/esm/services/PlatformCache.js +20 -9
- package/lib/esm/services/PlatformCache.js.map +1 -1
- package/lib/types/interceptors/PlatformCacheInterceptor.d.ts +1 -1
- package/lib/types/interfaces/PlatformCacheOptions.d.ts +2 -2
- package/lib/types/interfaces/interfaces.d.ts +11 -6
- package/lib/types/services/PlatformCache.d.ts +11 -9
- package/package.json +10 -11
|
@@ -40,7 +40,7 @@ let PlatformCacheInterceptor = class PlatformCacheInterceptor {
|
|
|
40
40
|
await this.addKeyToQueue(key);
|
|
41
41
|
const currentTTL = await this.cache.ttl(key);
|
|
42
42
|
const calculatedTTL = this.cache.calculateTTL(currentTTL, ttl);
|
|
43
|
-
if (currentTTL < calculatedTTL - refreshThreshold) {
|
|
43
|
+
if (currentTTL === undefined || currentTTL < calculatedTTL - refreshThreshold) {
|
|
44
44
|
await next();
|
|
45
45
|
}
|
|
46
46
|
await this.deleteKeyFromQueue(key);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PlatformCacheInterceptor.js","sourceRoot":"","sources":["../../../src/interceptors/PlatformCacheInterceptor.ts"],"names":[],"mappings":";;;;AAAA,qCAA4D;AAC5D,iCAA8H;AAC9H,mDAAyD;AACzD,yCAAoC;AACpC,yCAA6C;AAC7C,+BAAqD;AAGrD,6DAAwD;AAExD,MAAM,YAAY,GAAG,CAAC,OAAgC,EAAE,EAAE;IACxD,OAAO,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC;SAC3B,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,gBAAgB,EAAE,cAAc,EAAE,eAAe,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;SACrF,MAAM,CAAC,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE;QAChC,OAAO;YACL,GAAG,OAAO;YACV,CAAC,GAAG,CAAC,EAAE,KAAK;SACb,CAAC;IACJ,CAAC,EAAE,EAAE,CAAC,CAAC;AACX,CAAC,CAAC;AAEF;;GAEG;AAEH,IAAa,wBAAwB,GAArC,MAAa,wBAAwB;IAEzB,KAAK,CAAgB;IAGrB,MAAM,CAAS;IAEzB,KAAK,CAAC,SAAS,CAAC,OAAsD,EAAE,IAAqB;QAC3F,IAAI,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,EAAE;YACzB,OAAO,IAAI,EAAE,CAAC;SACf;QAED,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE;YAC7B,OAAO,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;SACxC;QAED,OAAO,IAAI,CAAC,aAAa,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IAC3C,CAAC;IAED,KAAK,CAAC,sBAAsB,CAAC,GAAW,EAAE,EAAC,gBAAgB,EAAE,GAAG,EAAwC,EAAE,IAAc;QACtH,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC;QAE9C,IAAI,gBAAgB,IAAI,CAAC,OAAO,EAAE;YAChC,MAAM,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC;YAE9B,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YAC7C,MAAM,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC;YAE/D,IAAI,UAAU,GAAG,aAAa,GAAG,gBAAgB,EAAE;gBACjD,MAAM,IAAI,EAAE,CAAC;aACd;YAED,MAAM,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,CAAC;SACpC;IACH,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,OAAsD,EAAE,IAAqB;QAC7F,MAAM,EAAC,IAAI,EAAE,GAAG,EAAE,cAAc,EAAE,gBAAgB,EAAE,OAAO,EAAE,IAAI,EAAC,GAAG,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;QAC9F,MAAM,GAAG,GAAG,CAAC,IAAA,aAAM,EAAC,OAAO,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAE7E,MAAM,GAAG,GAAG,CAAC,MAAW,EAAE,EAAE;YAC1B,MAAM,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;YAC3D,MAAM,IAAI,GAAG,IAAA,uBAAS,EAAC,MAAM,EAAE,EAAC,IAAI,EAAE,cAAc,EAAC,CAAC,CAAC;YACvD,IAAI,CAAC,KAAK,CAAC,eAAe,CAAC,GAAG,EAAE,IAAI,EAAE,EAAC,IAAI,EAAE,GAAG,EAAE,aAAa,EAAC,CAAC,CAAC;QACpE,CAAC,CAAC;QAEF,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC;QAE3D,IAAI,CAAC,YAAY,EAAE;YACjB,MAAM,MAAM,GAAG,MAAM,IAAI,EAAE,CAAC;YAE5B,GAAG,CAAC,MAAM,CAAC,CAAC;YAEZ,OAAO,MAAM,CAAC;SACf;QAED,IAAI,CAAC,sBAAsB,CAAC,GAAG,EAAE,EAAC,gBAAgB,EAAE,GAAG,EAAC,EAAE,KAAK,IAAI,EAAE;YACnE,MAAM,MAAM,GAAG,MAAM,IAAI,EAAE,CAAC;YAC5B,MAAM,GAAG,CAAC,MAAM,CAAC,CAAC;QACpB,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,EAAE,CACd,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC;YAChB,KAAK,EAAE,aAAa;YACpB,MAAM,EAAE,aAAa;YACrB,aAAa,EAAE,GAAG;YAClB,UAAU,EAAE,IAAA,aAAM,EAAC,OAAO,CAAC,MAAM,CAAC;YAClC,YAAY,EAAE,OAAO,CAAC,WAAW;YACjC,iBAAiB,EAAE,EAAE,CAAC,OAAO;YAC7B,KAAK,EAAE,EAAE,CAAC,KAAK;SAChB,CAAC,CACH,CAAC;QAEF,MAAM,EAAC,IAAI,EAAC,GAAG,YAAY,CAAC;QAE5B,OAAO,IAAA,yBAAW,EAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,EAAC,cAAc,EAAE,IAAI,EAAC,CAAC,CAAC;IAC/D,CAAC;IAED,KAAK,CAAC,aAAa,CAAC,OAAsD,EAAE,IAAqB;QAC/F,MAAM,IAAI,GAAgB,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QAChE,MAAM,EAAC,OAAO,EAAE,QAAQ,EAAC,GAAG,IAAI,CAAC;QAEjC,IAAI,OAAO,CAAC,MAAM,KAAK,KAAK,EAAE;YAC5B,OAAO,IAAI,EAAE,CAAC;SACf;QAED,MAAM,EAAC,GAAG,EAAE,IAAI,EAAE,OAAO,EAAC,GAAG,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;QACtD,MAAM,GAAG,GAAG,CAAC,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAE7D,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC;QAE3D,IAAI,YAAY,IAAI,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,KAAK,UAAU,CAAC,EAAE;YAClE,OAAO,IAAI,CAAC,YAAY,CAAC,YAAY,EAAE,IAAI,CAAC,CAAC;SAC9C;QAED,MAAM,MAAM,GAAG,MAAM,IAAI,EAAE,CAAC;QAE5B,MAAM,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QAE3D,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC;YACvB,eAAe,EAAE,WAAW,aAAa,EAAE;SAC5C,CAAC,CAAC;QAEH,iDAAiD;QACjD,QAAQ,CAAC,KAAK,CAAC,KAAK,IAAI,EAAE;YACxB,IAAI,CAAC,KAAK,CAAC,eAAe,CAAC,GAAG,EAAE,QAAQ,CAAC,OAAO,EAAE,EAAE;gBAClD,GAAG,EAAE,aAAa;gBAClB,IAAI;gBACJ,OAAO,EAAE,YAAY,CAAC,QAAQ,CAAC,UAAU,EAAE,CAAC;aAC7C,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,OAAO,MAAM,CAAC;IAChB,CAAC;IAES,OAAO,CAAC,OAA0D;QAC1E,OAAO,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE;YACvC,IAAI,GAAG,YAAY,cAAS,IAAI,GAAG,YAAY,sBAAe,IAAI,GAAG,YAAY,qBAAc,EAAE;gBAC/F,OAAO,IAAI,CAAC;aACb;YAED,IAAI,IAAA,cAAO,EAAC,GAAG,CAAC,EAAE;gBAChB,OAAO,IAAI,CAAC,MAAM,CAAC,IAAA,uBAAS,EAAC,GAAG,CAAC,CAAC,CAAC;aACpC;YAED,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAC1B,CAAC,EAAE,EAAE,CAAC,CAAC;IACT,CAAC;IAES,UAAU,CAAC,OAAsD;QACzE,MAAM,EAAC,GAAG,EAAE,IAAI,EAAE,cAAc,EAAE,GAAG,EAAE,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,kBAAkB,EAAE,EAAE,gBAAgB,EAAC,GAAG,OAAO,CAAC,OAAO,IAAI,EAAE,CAAC;QAEtH,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QACnC,MAAM,OAAO,GAAG,IAAA,eAAQ,EAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAE1C,OAAO,EAAC,gBAAgB,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,cAAc,EAAE,OAAO,EAAC,CAAC;IACtE,CAAC;IAES,UAAU,CAAC,EAAC,MAAM,EAAE,WAAW,EAAgD;QACvF,OAAO,YAAK,CAAC,UAAU,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC,GAAG,CAAC,wBAAe,CAAC,CAAC;IACpE,CAAC;IAES,KAAK,CAAC,aAAa,CAAC,GAAW;QACvC,OAAO,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,WAAW,GAAG,EAAE,CAAC,CAAC,CAAC;IACpD,CAAC;IAES,KAAK,CAAC,aAAa,CAAC,GAAW;QACvC,MAAM,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,WAAW,GAAG,EAAE,EAAE,IAAI,EAAE,EAAC,GAAG,EAAE,GAAG,EAAC,CAAC,CAAC;IAC3D,CAAC;IAES,KAAK,CAAC,kBAAkB,CAAC,GAAW;QAC5C,MAAM,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,WAAW,GAAG,EAAE,CAAC,CAAC;IACzC,CAAC;IAES,YAAY,CAAC,YAAkC,EAAE,IAAiB;QAC1E,MAAM,EAAC,OAAO,EAAE,GAAG,EAAC,GAAG,YAAY,CAAC;QACpC,MAAM,EAAC,OAAO,EAAE,QAAQ,EAAC,GAAG,IAAI,CAAC;QAEjC,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;QAEjD,IAAI,WAAW,IAAI,OAAO,CAAC,IAAI,KAAK,WAAW,EAAE;YAC/C,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YAEzD,OAAO,SAAS,CAAC;SAClB;QAED,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;QAE3C,IAAI,CAAC,QAAQ;aACV,UAAU,CAAC;YACV,GAAG,OAAO;YACV,UAAU,EAAE,MAAM;YAClB,eAAe,EAAE,WAAW,GAAG,EAAE;SAClC,CAAC;aACD,IAAI,CAAC,IAAI,CAAC,CAAC;QAEd,OAAO,IAAI,CAAC;IACd,CAAC;CACF,CAAA;AA9KC;IADC,IAAA,WAAM,GAAE;sCACQ,6BAAa;uDAAC;AAG/B;IADC,IAAA,WAAM,GAAE;sCACS,eAAM;wDAAC;AALd,wBAAwB;IADpC,IAAA,gBAAW,GAAE;GACD,wBAAwB,CAgLpC;AAhLY,4DAAwB","sourcesContent":["import {isClass, isString, nameOf, Store} from \"@tsed/core\";\nimport {BaseContext, DIContext, Inject, Interceptor, InterceptorContext, InterceptorMethods, InterceptorNext} from \"@tsed/di\";\nimport {deserialize, serialize} from \"@tsed/json-mapper\";\nimport {Logger} from \"@tsed/logger\";\nimport {JsonEntityStore} from \"@tsed/schema\";\nimport {IncomingMessage, ServerResponse} from \"http\";\nimport {PlatformCachedObject} from \"../interfaces/PlatformCachedObject\";\nimport {PlatformCacheOptions} from \"../interfaces/PlatformCacheOptions\";\nimport {PlatformCache} from \"../services/PlatformCache\";\n\nconst cleanHeaders = (headers: Record<string, unknown>) => {\n return Object.entries(headers)\n .filter(([key]) => ![\"content-length\", \"x-request-id\", \"cache-control\"].includes(key))\n .reduce((headers, [key, value]) => {\n return {\n ...headers,\n [key]: value\n };\n }, {});\n};\n\n/**\n * @platform\n */\n@Interceptor()\nexport class PlatformCacheInterceptor implements InterceptorMethods {\n @Inject()\n protected cache: PlatformCache;\n\n @Inject()\n protected logger: Logger;\n\n async intercept(context: InterceptorContext<any, PlatformCacheOptions>, next: InterceptorNext) {\n if (this.cache.disabled()) {\n return next();\n }\n\n if (!this.isEndpoint(context)) {\n return this.cacheMethod(context, next);\n }\n\n return this.cacheResponse(context, next);\n }\n\n async canRefreshInBackground(key: string, {refreshThreshold, ttl}: {refreshThreshold?: number; ttl: any}, next: Function) {\n const inQueue = await this.hasKeyInQueue(key);\n\n if (refreshThreshold && !inQueue) {\n await this.addKeyToQueue(key);\n\n const currentTTL = await this.cache.ttl(key);\n const calculatedTTL = this.cache.calculateTTL(currentTTL, ttl);\n\n if (currentTTL < calculatedTTL - refreshThreshold) {\n await next();\n }\n\n await this.deleteKeyFromQueue(key);\n }\n }\n\n async cacheMethod(context: InterceptorContext<any, PlatformCacheOptions>, next: InterceptorNext) {\n const {type, ttl, collectionType, refreshThreshold, keyArgs, args} = this.getOptions(context);\n const key = [nameOf(context.target), context.propertyKey, keyArgs].join(\":\");\n\n const set = (result: any) => {\n const calculatedTTL = this.cache.calculateTTL(result, ttl);\n const data = serialize(result, {type, collectionType});\n this.cache.setCachedObject(key, data, {args, ttl: calculatedTTL});\n };\n\n const cachedObject = await this.cache.getCachedObject(key);\n\n if (!cachedObject) {\n const result = await next();\n\n set(result);\n\n return result;\n }\n\n this.canRefreshInBackground(key, {refreshThreshold, ttl}, async () => {\n const result = await next();\n await set(result);\n }).catch((er) =>\n this.logger.error({\n event: \"CACHE_ERROR\",\n method: \"cacheMethod\",\n concerned_key: key,\n class_name: nameOf(context.target),\n property_key: context.propertyKey,\n error_description: er.message,\n stack: er.stack\n })\n );\n\n const {data} = cachedObject;\n\n return deserialize(JSON.parse(data), {collectionType, type});\n }\n\n async cacheResponse(context: InterceptorContext<any, PlatformCacheOptions>, next: InterceptorNext) {\n const $ctx: BaseContext = context.args[context.args.length - 1];\n const {request, response} = $ctx;\n\n if (request.method !== \"GET\") {\n return next();\n }\n\n const {ttl, args, keyArgs} = this.getOptions(context);\n const key = [request.method, request.url, keyArgs].join(\":\");\n\n const cachedObject = await this.cache.getCachedObject(key);\n\n if (cachedObject && !(request.get(\"cache-control\") === \"no-cache\")) {\n return this.sendResponse(cachedObject, $ctx);\n }\n\n const result = await next();\n\n const calculatedTTL = this.cache.calculateTTL(result, ttl);\n\n $ctx.response.setHeaders({\n \"cache-control\": `max-age=${calculatedTTL}`\n });\n\n // cache final response with his headers and body\n response.onEnd(async () => {\n this.cache.setCachedObject(key, response.getBody(), {\n ttl: calculatedTTL,\n args,\n headers: cleanHeaders(response.getHeaders())\n });\n });\n\n return result;\n }\n\n protected getArgs(context: InterceptorContext<unknown, PlatformCacheOptions>) {\n return context.args.reduce((args, arg) => {\n if (arg instanceof DIContext || arg instanceof IncomingMessage || arg instanceof ServerResponse) {\n return args;\n }\n\n if (isClass(arg)) {\n return args.concat(serialize(arg));\n }\n\n return args.concat(arg);\n }, []);\n }\n\n protected getOptions(context: InterceptorContext<any, PlatformCacheOptions>) {\n const {ttl, type, collectionType, key: k = this.cache.defaultKeyResolver(), refreshThreshold} = context.options || {};\n\n const args = this.getArgs(context);\n const keyArgs = isString(k) ? k : k(args);\n\n return {refreshThreshold, ttl, type, args, collectionType, keyArgs};\n }\n\n protected isEndpoint({target, propertyKey}: InterceptorContext<any, PlatformCacheOptions>) {\n return Store.fromMethod(target, propertyKey).has(JsonEntityStore);\n }\n\n protected async hasKeyInQueue(key: string) {\n return !!(await this.cache.get(`$$queue:${key}`));\n }\n\n protected async addKeyToQueue(key: string) {\n await this.cache.set(`$$queue:${key}`, true, {ttl: 120});\n }\n\n protected async deleteKeyFromQueue(key: string) {\n await this.cache.del(`$$queue:${key}`);\n }\n\n protected sendResponse(cachedObject: PlatformCachedObject, $ctx: BaseContext) {\n const {headers, ttl} = cachedObject;\n const {request, response} = $ctx;\n\n const requestEtag = request.get(\"if-none-match\");\n\n if (requestEtag && headers.etag === requestEtag) {\n response.status(304).setHeaders(headers).body(undefined);\n\n return undefined;\n }\n\n const data = JSON.parse(cachedObject.data);\n\n $ctx.response\n .setHeaders({\n ...headers,\n \"x-cached\": \"true\",\n \"cache-control\": `max-age=${ttl}`\n })\n .body(data);\n\n return data;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"PlatformCacheInterceptor.js","sourceRoot":"","sources":["../../../src/interceptors/PlatformCacheInterceptor.ts"],"names":[],"mappings":"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","sourcesContent":["import {isClass, isString, nameOf, Store} from \"@tsed/core\";\nimport {BaseContext, DIContext, Inject, Interceptor, InterceptorContext, InterceptorMethods, InterceptorNext} from \"@tsed/di\";\nimport {deserialize, serialize} from \"@tsed/json-mapper\";\nimport {Logger} from \"@tsed/logger\";\nimport {JsonEntityStore} from \"@tsed/schema\";\nimport {IncomingMessage, ServerResponse} from \"http\";\nimport {PlatformCachedObject} from \"../interfaces/PlatformCachedObject\";\nimport {PlatformCacheOptions} from \"../interfaces/PlatformCacheOptions\";\nimport {PlatformCache} from \"../services/PlatformCache\";\n\nconst cleanHeaders = (headers: Record<string, unknown>) => {\n return Object.entries(headers)\n .filter(([key]) => ![\"content-length\", \"x-request-id\", \"cache-control\"].includes(key))\n .reduce((headers, [key, value]) => {\n return {\n ...headers,\n [key]: value\n };\n }, {});\n};\n\n/**\n * @platform\n */\n@Interceptor()\nexport class PlatformCacheInterceptor implements InterceptorMethods {\n @Inject()\n protected cache: PlatformCache;\n\n @Inject()\n protected logger: Logger;\n\n async intercept(context: InterceptorContext<any, PlatformCacheOptions>, next: InterceptorNext) {\n if (this.cache.disabled()) {\n return next();\n }\n\n if (!this.isEndpoint(context)) {\n return this.cacheMethod(context, next);\n }\n\n return this.cacheResponse(context, next);\n }\n\n async canRefreshInBackground(key: string, {refreshThreshold, ttl}: {refreshThreshold?: number; ttl: any}, next: Function) {\n const inQueue = await this.hasKeyInQueue(key);\n\n if (refreshThreshold && !inQueue) {\n await this.addKeyToQueue(key);\n\n const currentTTL = await this.cache.ttl(key);\n const calculatedTTL = this.cache.calculateTTL(currentTTL, ttl);\n\n if (currentTTL === undefined || currentTTL < calculatedTTL - refreshThreshold) {\n await next();\n }\n\n await this.deleteKeyFromQueue(key);\n }\n }\n\n async cacheMethod(context: InterceptorContext<any, PlatformCacheOptions>, next: InterceptorNext) {\n const {type, ttl, collectionType, refreshThreshold, keyArgs, args} = this.getOptions(context);\n const key = [nameOf(context.target), context.propertyKey, keyArgs].join(\":\");\n\n const set = (result: any) => {\n const calculatedTTL = this.cache.calculateTTL(result, ttl);\n const data = serialize(result, {type, collectionType});\n this.cache.setCachedObject(key, data, {args, ttl: calculatedTTL});\n };\n\n const cachedObject = await this.cache.getCachedObject(key);\n\n if (!cachedObject) {\n const result = await next();\n\n set(result);\n\n return result;\n }\n\n this.canRefreshInBackground(key, {refreshThreshold, ttl}, async () => {\n const result = await next();\n await set(result);\n }).catch((er) =>\n this.logger.error({\n event: \"CACHE_ERROR\",\n method: \"cacheMethod\",\n concerned_key: key,\n class_name: nameOf(context.target),\n property_key: context.propertyKey,\n error_description: er.message,\n stack: er.stack\n })\n );\n\n const {data} = cachedObject;\n\n return deserialize(JSON.parse(data), {collectionType, type});\n }\n\n async cacheResponse(context: InterceptorContext<any, PlatformCacheOptions>, next: InterceptorNext) {\n const $ctx: BaseContext = context.args[context.args.length - 1];\n const {request, response} = $ctx;\n\n if (request.method !== \"GET\") {\n return next();\n }\n\n const {ttl, args, keyArgs} = this.getOptions(context);\n const key = [request.method, request.url, keyArgs].join(\":\");\n\n const cachedObject = await this.cache.getCachedObject(key);\n\n if (cachedObject && !(request.get(\"cache-control\") === \"no-cache\")) {\n return this.sendResponse(cachedObject, $ctx);\n }\n\n const result = await next();\n\n const calculatedTTL = this.cache.calculateTTL(result, ttl);\n\n $ctx.response.setHeaders({\n \"cache-control\": `max-age=${calculatedTTL}`\n });\n\n // cache final response with his headers and body\n response.onEnd(async () => {\n this.cache.setCachedObject(key, response.getBody(), {\n ttl: calculatedTTL,\n args,\n headers: cleanHeaders(response.getHeaders())\n });\n });\n\n return result;\n }\n\n protected getArgs(context: InterceptorContext<unknown, PlatformCacheOptions>) {\n return context.args.reduce((args, arg) => {\n if (arg instanceof DIContext || arg instanceof IncomingMessage || arg instanceof ServerResponse) {\n return args;\n }\n\n if (isClass(arg)) {\n return args.concat(serialize(arg));\n }\n\n return args.concat(arg);\n }, []);\n }\n\n protected getOptions(context: InterceptorContext<any, PlatformCacheOptions>) {\n const {ttl, type, collectionType, key: k = this.cache.defaultKeyResolver(), refreshThreshold} = context.options || {};\n\n const args = this.getArgs(context);\n const keyArgs = isString(k) ? k : k(args);\n\n return {refreshThreshold, ttl, type, args, collectionType, keyArgs};\n }\n\n protected isEndpoint({target, propertyKey}: InterceptorContext<any, PlatformCacheOptions>) {\n return Store.fromMethod(target, propertyKey).has(JsonEntityStore);\n }\n\n protected async hasKeyInQueue(key: string) {\n return !!(await this.cache.get(`$$queue:${key}`));\n }\n\n protected async addKeyToQueue(key: string) {\n await this.cache.set(`$$queue:${key}`, true, {ttl: 120});\n }\n\n protected async deleteKeyFromQueue(key: string) {\n await this.cache.del(`$$queue:${key}`);\n }\n\n protected sendResponse(cachedObject: PlatformCachedObject, $ctx: BaseContext) {\n const {headers, ttl} = cachedObject;\n const {request, response} = $ctx;\n\n const requestEtag = request.get(\"if-none-match\");\n\n if (requestEtag && headers.etag === requestEtag) {\n response.status(304).setHeaders(headers).body(undefined);\n\n return undefined;\n }\n\n const data = JSON.parse(cachedObject.data);\n\n $ctx.response\n .setHeaders({\n ...headers,\n \"x-cached\": \"true\",\n \"cache-control\": `max-age=${ttl}`\n })\n .body(data);\n\n return data;\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PlatformCacheOptions.js","sourceRoot":"","sources":["../../../src/interfaces/PlatformCacheOptions.ts"],"names":[],"mappings":"","sourcesContent":["import {MetadataTypes} from \"@tsed/core\";\nimport {BaseContext} from \"@tsed/di\";\nimport type {
|
|
1
|
+
{"version":3,"file":"PlatformCacheOptions.js","sourceRoot":"","sources":["../../../src/interfaces/PlatformCacheOptions.ts"],"names":[],"mappings":"","sourcesContent":["import {MetadataTypes} from \"@tsed/core\";\nimport {BaseContext} from \"@tsed/di\";\nimport type {Ttl} from \"../services/PlatformCache\";\n\nexport interface PlatformCacheOptions extends MetadataTypes {\n ttl?: Ttl;\n key?: string | ((args: any[], ctx?: BaseContext) => string);\n refreshThreshold?: number;\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"interfaces.js","sourceRoot":"","sources":["../../../src/interfaces/interfaces.ts"],"names":[],"mappings":"","sourcesContent":["import type {BaseContext} from \"@tsed/di\";\nimport type {Cache,
|
|
1
|
+
{"version":3,"file":"interfaces.js","sourceRoot":"","sources":["../../../src/interfaces/interfaces.ts"],"names":[],"mappings":"","sourcesContent":["import type {BaseContext} from \"@tsed/di\";\nimport type {Cache, CachingConfig, Store} from \"cache-manager\";\nimport {FactoryStore} from \"cache-manager/dist/caching\";\nimport type {CacheManager} from \"../services/PlatformCache\";\n\n/**\n * @deprecated Since 2022-11. Use FactoryStore instead.\n */\nexport type PlatformCacheLegacyStoreFactory = {\n create(...args: any[]): Promise<Store | any> | Store | any;\n};\n\nexport type PlatformCacheSettings<Config extends object = any, S extends Store = any> = CachingConfig<Config> & {\n caches?: Cache[];\n store?: \"memory\" | Store | PlatformCacheLegacyStoreFactory | FactoryStore<S, Config>;\n max?: number;\n keyResolver?: (args: any[], ctx: BaseContext) => string;\n\n /**\n * You may pass in any other arguments these will be passed on to the `create` method of your store,\n * otherwise they will be ignored.\n */\n [key: string]: any;\n};\n\ndeclare global {\n // eslint-disable-next-line @typescript-eslint/no-namespace\n namespace TsED {\n interface Configuration {\n cache?: PlatformCacheSettings | false;\n }\n }\n}\n\nexport interface OnCreateCacheManager {\n $onCreateCacheManager(cache: CacheManager): void | Promise<void>;\n}\n"]}
|
|
@@ -45,17 +45,18 @@ let PlatformCache = class PlatformCache {
|
|
|
45
45
|
return this.cache.store.ttl(key);
|
|
46
46
|
}
|
|
47
47
|
}
|
|
48
|
-
wrap(key, fetch,
|
|
48
|
+
wrap(key, fetch, ttl) {
|
|
49
49
|
if (!this.cache) {
|
|
50
50
|
return fetch();
|
|
51
51
|
}
|
|
52
|
-
return this.cache?.wrap(key, fetch,
|
|
52
|
+
return this.cache?.wrap(key, fetch, ttl);
|
|
53
53
|
}
|
|
54
54
|
async get(key, options = {}) {
|
|
55
55
|
return (0, json_mapper_1.deserialize)(this.cache?.get(key), options);
|
|
56
56
|
}
|
|
57
57
|
async set(key, value, options) {
|
|
58
|
-
|
|
58
|
+
await this.cache?.set(key, value, options?.ttl);
|
|
59
|
+
return;
|
|
59
60
|
}
|
|
60
61
|
async getCachedObject(key) {
|
|
61
62
|
try {
|
|
@@ -112,15 +113,25 @@ let PlatformCache = class PlatformCache {
|
|
|
112
113
|
async createCacheManager(settings) {
|
|
113
114
|
const { caches, store = "memory", ttl, ...props } = settings;
|
|
114
115
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
115
|
-
const {
|
|
116
|
+
const { multiCaching, caching } = await Promise.resolve().then(() => tslib_1.__importStar(require("cache-manager")));
|
|
116
117
|
return caches?.length
|
|
117
|
-
?
|
|
118
|
-
:
|
|
118
|
+
? multiCaching(caches)
|
|
119
|
+
: caching(await this.mapStore(store), {
|
|
119
120
|
...props,
|
|
120
|
-
ttl
|
|
121
|
-
store: (0, core_1.isFunction)(store) ? await store() : store
|
|
121
|
+
ttl
|
|
122
122
|
});
|
|
123
123
|
}
|
|
124
|
+
async mapStore(store) {
|
|
125
|
+
if (!(0, core_1.isString)(store)) {
|
|
126
|
+
if ("create" in store) {
|
|
127
|
+
store = store.create;
|
|
128
|
+
}
|
|
129
|
+
if ((0, core_1.isFunction)(store)) {
|
|
130
|
+
return await store();
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
return store;
|
|
134
|
+
}
|
|
124
135
|
};
|
|
125
136
|
tslib_1.__decorate([
|
|
126
137
|
(0, di_1.Configuration)(),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PlatformCache.js","sourceRoot":"","sources":["../../../src/services/PlatformCache.ts"],"names":[],"mappings":";;;;AAAA,
|
|
1
|
+
{"version":3,"file":"PlatformCache.js","sourceRoot":"","sources":["../../../src/services/PlatformCache.ts"],"names":[],"mappings":"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","sourcesContent":["import {isClass, isFunction, isString} from \"@tsed/core\";\nimport {Configuration, Inject, InjectorService, Module} from \"@tsed/di\";\nimport {deserialize, JsonDeserializerOptions, serialize} from \"@tsed/json-mapper\";\nimport {Logger} from \"@tsed/logger\";\nimport type {Cache, CachingConfig, MultiCache} from \"cache-manager\";\nimport {PlatformCacheSettings} from \"../interfaces/interfaces\";\nimport {PlatformCachedObject} from \"../interfaces/PlatformCachedObject\";\n\nconst defaultKeyResolver = (args: any[]) => {\n return args.map((arg: any) => (isClass(arg) ? JSON.stringify(serialize(arg)) : arg)).join(\":\");\n};\n\nexport type CacheManager = Cache | MultiCache;\nexport type Ttl = number | ((result: any) => number);\n\n/**\n * @platform\n */\n@Module()\nexport class PlatformCache {\n @Configuration()\n protected settings: Configuration;\n\n @Inject()\n protected injector: InjectorService;\n\n @Inject()\n protected logger: Logger;\n\n #cache: CacheManager | undefined;\n\n get cache() {\n return this.#cache;\n }\n\n async $onInit() {\n const settings = this.settings.get<PlatformCacheSettings>(\"cache\");\n\n if (settings) {\n this.#cache = await this.createCacheManager(settings);\n\n await this.injector.emit(\"$onCreateCacheManager\", this.#cache);\n }\n }\n\n disabled(): boolean {\n return !this.settings.get<PlatformCacheSettings>(\"cache\");\n }\n\n defaultKeyResolver() {\n return this.settings.get<(args: any[], ctx?: any) => string>(\"cache.keyResolver\", defaultKeyResolver);\n }\n\n defaultTtl() {\n return this.settings.get<Ttl>(\"cache.ttl\");\n }\n\n calculateTTL(result?: any, currentTtl?: Ttl): number {\n const ttl = currentTtl === undefined ? this.defaultTtl() : currentTtl;\n\n return isFunction(ttl) ? ttl(result) : ttl;\n }\n\n async ttl(key: string) {\n if (this.cache && \"store\" in this.cache && this.cache.store.ttl) {\n return this.cache.store.ttl(key);\n }\n }\n\n wrap<T>(key: string, fetch: () => Promise<T>, ttl?: number): Promise<T> {\n if (!this.cache) {\n return fetch();\n }\n\n return this.cache?.wrap<T>(key, fetch, ttl);\n }\n\n async get<T>(key: string, options: JsonDeserializerOptions = {}): Promise<T | undefined> {\n return deserialize(this.cache?.get<T>(key), options);\n }\n\n async set<T>(key: string, value: any, options?: CachingConfig<T>): Promise<T | undefined> {\n await this.cache?.set(key, value, options?.ttl);\n return;\n }\n\n async getCachedObject(key: string) {\n try {\n return await this.get<PlatformCachedObject>(key);\n } catch (er) {\n this.logger.error({\n event: \"CACHE_ERROR\",\n method: \"getCachedObject\",\n error: er\n });\n }\n }\n\n async setCachedObject(key: string, data: any, opts: {ttl: number} & Record<string, any>) {\n try {\n await this.set<PlatformCachedObject>(\n key,\n {\n ...opts,\n data: JSON.stringify(data)\n },\n {\n ttl: opts.ttl\n }\n );\n } catch (er) {\n this.logger.error({\n event: \"CACHE_ERROR\",\n method: \"setCachedObject\",\n error: er\n });\n }\n }\n\n async del(key: string): Promise<void> {\n await this.cache?.del(key);\n }\n\n async reset(): Promise<void> {\n // @ts-ignore\n await this.cache?.reset();\n }\n\n async keys(...args: any[]): Promise<string[]> {\n if (this.cache && \"store\" in this.cache && this.cache.store.keys) {\n return this.cache.store.keys(...args);\n }\n\n // istanbul ignore next\n return [];\n }\n\n async getMatchingKeys(patterns: string): Promise<string[]> {\n const [keys, {default: micromatch}] = await Promise.all([this.keys(), import(\"micromatch\")]);\n\n return micromatch(keys, patterns);\n }\n\n async deleteMatchingKeys(patterns: string): Promise<string[]> {\n const keys = await this.getMatchingKeys(patterns);\n\n await Promise.all(keys.map((key: string) => this.del(key)));\n\n return keys;\n }\n\n protected async createCacheManager(settings: PlatformCacheSettings) {\n const {caches, store = \"memory\", ttl, ...props} = settings;\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const {multiCaching, caching} = await import(\"cache-manager\");\n\n return caches?.length\n ? multiCaching(caches)\n : caching(await this.mapStore(store), {\n ...props,\n ttl\n });\n }\n\n private async mapStore(store: string | Function | {create: Function}) {\n if (!isString(store)) {\n if (\"create\" in store) {\n store = store.create;\n }\n\n if (isFunction(store)) {\n return await store();\n }\n }\n\n return store;\n }\n}\n"]}
|
|
@@ -37,7 +37,7 @@ let PlatformCacheInterceptor = class PlatformCacheInterceptor {
|
|
|
37
37
|
await this.addKeyToQueue(key);
|
|
38
38
|
const currentTTL = await this.cache.ttl(key);
|
|
39
39
|
const calculatedTTL = this.cache.calculateTTL(currentTTL, ttl);
|
|
40
|
-
if (currentTTL < calculatedTTL - refreshThreshold) {
|
|
40
|
+
if (currentTTL === undefined || currentTTL < calculatedTTL - refreshThreshold) {
|
|
41
41
|
await next();
|
|
42
42
|
}
|
|
43
43
|
await this.deleteKeyFromQueue(key);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PlatformCacheInterceptor.js","sourceRoot":"","sources":["../../../src/interceptors/PlatformCacheInterceptor.ts"],"names":[],"mappings":";AAAA,OAAO,EAAC,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAC,MAAM,YAAY,CAAC;AAC5D,OAAO,EAAc,SAAS,EAAE,MAAM,EAAE,WAAW,EAA0D,MAAM,UAAU,CAAC;AAC9H,OAAO,EAAC,WAAW,EAAE,SAAS,EAAC,MAAM,mBAAmB,CAAC;AACzD,OAAO,EAAC,MAAM,EAAC,MAAM,cAAc,CAAC;AACpC,OAAO,EAAC,eAAe,EAAC,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAC,eAAe,EAAE,cAAc,EAAC,MAAM,MAAM,CAAC;AAGrD,OAAO,EAAC,aAAa,EAAC,MAAM,2BAA2B,CAAC;AAExD,MAAM,YAAY,GAAG,CAAC,OAAgC,EAAE,EAAE;IACxD,OAAO,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC;SAC3B,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,gBAAgB,EAAE,cAAc,EAAE,eAAe,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;SACrF,MAAM,CAAC,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE;QAChC,OAAO;YACL,GAAG,OAAO;YACV,CAAC,GAAG,CAAC,EAAE,KAAK;SACb,CAAC;IACJ,CAAC,EAAE,EAAE,CAAC,CAAC;AACX,CAAC,CAAC;AAEF;;GAEG;AAEH,IAAa,wBAAwB,GAArC,MAAa,wBAAwB;IAEzB,KAAK,CAAgB;IAGrB,MAAM,CAAS;IAEzB,KAAK,CAAC,SAAS,CAAC,OAAsD,EAAE,IAAqB;QAC3F,IAAI,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,EAAE;YACzB,OAAO,IAAI,EAAE,CAAC;SACf;QAED,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE;YAC7B,OAAO,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;SACxC;QAED,OAAO,IAAI,CAAC,aAAa,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IAC3C,CAAC;IAED,KAAK,CAAC,sBAAsB,CAAC,GAAW,EAAE,EAAC,gBAAgB,EAAE,GAAG,EAAwC,EAAE,IAAc;QACtH,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC;QAE9C,IAAI,gBAAgB,IAAI,CAAC,OAAO,EAAE;YAChC,MAAM,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC;YAE9B,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YAC7C,MAAM,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC;YAE/D,IAAI,UAAU,GAAG,aAAa,GAAG,gBAAgB,EAAE;gBACjD,MAAM,IAAI,EAAE,CAAC;aACd;YAED,MAAM,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,CAAC;SACpC;IACH,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,OAAsD,EAAE,IAAqB;QAC7F,MAAM,EAAC,IAAI,EAAE,GAAG,EAAE,cAAc,EAAE,gBAAgB,EAAE,OAAO,EAAE,IAAI,EAAC,GAAG,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;QAC9F,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAE7E,MAAM,GAAG,GAAG,CAAC,MAAW,EAAE,EAAE;YAC1B,MAAM,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;YAC3D,MAAM,IAAI,GAAG,SAAS,CAAC,MAAM,EAAE,EAAC,IAAI,EAAE,cAAc,EAAC,CAAC,CAAC;YACvD,IAAI,CAAC,KAAK,CAAC,eAAe,CAAC,GAAG,EAAE,IAAI,EAAE,EAAC,IAAI,EAAE,GAAG,EAAE,aAAa,EAAC,CAAC,CAAC;QACpE,CAAC,CAAC;QAEF,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC;QAE3D,IAAI,CAAC,YAAY,EAAE;YACjB,MAAM,MAAM,GAAG,MAAM,IAAI,EAAE,CAAC;YAE5B,GAAG,CAAC,MAAM,CAAC,CAAC;YAEZ,OAAO,MAAM,CAAC;SACf;QAED,IAAI,CAAC,sBAAsB,CAAC,GAAG,EAAE,EAAC,gBAAgB,EAAE,GAAG,EAAC,EAAE,KAAK,IAAI,EAAE;YACnE,MAAM,MAAM,GAAG,MAAM,IAAI,EAAE,CAAC;YAC5B,MAAM,GAAG,CAAC,MAAM,CAAC,CAAC;QACpB,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,EAAE,CACd,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC;YAChB,KAAK,EAAE,aAAa;YACpB,MAAM,EAAE,aAAa;YACrB,aAAa,EAAE,GAAG;YAClB,UAAU,EAAE,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC;YAClC,YAAY,EAAE,OAAO,CAAC,WAAW;YACjC,iBAAiB,EAAE,EAAE,CAAC,OAAO;YAC7B,KAAK,EAAE,EAAE,CAAC,KAAK;SAChB,CAAC,CACH,CAAC;QAEF,MAAM,EAAC,IAAI,EAAC,GAAG,YAAY,CAAC;QAE5B,OAAO,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,EAAC,cAAc,EAAE,IAAI,EAAC,CAAC,CAAC;IAC/D,CAAC;IAED,KAAK,CAAC,aAAa,CAAC,OAAsD,EAAE,IAAqB;QAC/F,MAAM,IAAI,GAAgB,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QAChE,MAAM,EAAC,OAAO,EAAE,QAAQ,EAAC,GAAG,IAAI,CAAC;QAEjC,IAAI,OAAO,CAAC,MAAM,KAAK,KAAK,EAAE;YAC5B,OAAO,IAAI,EAAE,CAAC;SACf;QAED,MAAM,EAAC,GAAG,EAAE,IAAI,EAAE,OAAO,EAAC,GAAG,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;QACtD,MAAM,GAAG,GAAG,CAAC,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAE7D,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC;QAE3D,IAAI,YAAY,IAAI,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,KAAK,UAAU,CAAC,EAAE;YAClE,OAAO,IAAI,CAAC,YAAY,CAAC,YAAY,EAAE,IAAI,CAAC,CAAC;SAC9C;QAED,MAAM,MAAM,GAAG,MAAM,IAAI,EAAE,CAAC;QAE5B,MAAM,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QAE3D,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC;YACvB,eAAe,EAAE,WAAW,aAAa,EAAE;SAC5C,CAAC,CAAC;QAEH,iDAAiD;QACjD,QAAQ,CAAC,KAAK,CAAC,KAAK,IAAI,EAAE;YACxB,IAAI,CAAC,KAAK,CAAC,eAAe,CAAC,GAAG,EAAE,QAAQ,CAAC,OAAO,EAAE,EAAE;gBAClD,GAAG,EAAE,aAAa;gBAClB,IAAI;gBACJ,OAAO,EAAE,YAAY,CAAC,QAAQ,CAAC,UAAU,EAAE,CAAC;aAC7C,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,OAAO,MAAM,CAAC;IAChB,CAAC;IAES,OAAO,CAAC,OAA0D;QAC1E,OAAO,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE;YACvC,IAAI,GAAG,YAAY,SAAS,IAAI,GAAG,YAAY,eAAe,IAAI,GAAG,YAAY,cAAc,EAAE;gBAC/F,OAAO,IAAI,CAAC;aACb;YAED,IAAI,OAAO,CAAC,GAAG,CAAC,EAAE;gBAChB,OAAO,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC;aACpC;YAED,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAC1B,CAAC,EAAE,EAAE,CAAC,CAAC;IACT,CAAC;IAES,UAAU,CAAC,OAAsD;QACzE,MAAM,EAAC,GAAG,EAAE,IAAI,EAAE,cAAc,EAAE,GAAG,EAAE,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,kBAAkB,EAAE,EAAE,gBAAgB,EAAC,GAAG,OAAO,CAAC,OAAO,IAAI,EAAE,CAAC;QAEtH,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QACnC,MAAM,OAAO,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAE1C,OAAO,EAAC,gBAAgB,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,cAAc,EAAE,OAAO,EAAC,CAAC;IACtE,CAAC;IAES,UAAU,CAAC,EAAC,MAAM,EAAE,WAAW,EAAgD;QACvF,OAAO,KAAK,CAAC,UAAU,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;IACpE,CAAC;IAES,KAAK,CAAC,aAAa,CAAC,GAAW;QACvC,OAAO,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,WAAW,GAAG,EAAE,CAAC,CAAC,CAAC;IACpD,CAAC;IAES,KAAK,CAAC,aAAa,CAAC,GAAW;QACvC,MAAM,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,WAAW,GAAG,EAAE,EAAE,IAAI,EAAE,EAAC,GAAG,EAAE,GAAG,EAAC,CAAC,CAAC;IAC3D,CAAC;IAES,KAAK,CAAC,kBAAkB,CAAC,GAAW;QAC5C,MAAM,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,WAAW,GAAG,EAAE,CAAC,CAAC;IACzC,CAAC;IAES,YAAY,CAAC,YAAkC,EAAE,IAAiB;QAC1E,MAAM,EAAC,OAAO,EAAE,GAAG,EAAC,GAAG,YAAY,CAAC;QACpC,MAAM,EAAC,OAAO,EAAE,QAAQ,EAAC,GAAG,IAAI,CAAC;QAEjC,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;QAEjD,IAAI,WAAW,IAAI,OAAO,CAAC,IAAI,KAAK,WAAW,EAAE;YAC/C,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YAEzD,OAAO,SAAS,CAAC;SAClB;QAED,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;QAE3C,IAAI,CAAC,QAAQ;aACV,UAAU,CAAC;YACV,GAAG,OAAO;YACV,UAAU,EAAE,MAAM;YAClB,eAAe,EAAE,WAAW,GAAG,EAAE;SAClC,CAAC;aACD,IAAI,CAAC,IAAI,CAAC,CAAC;QAEd,OAAO,IAAI,CAAC;IACd,CAAC;CACF,CAAA;AA9KC;IADC,MAAM,EAAE;8BACQ,aAAa;uDAAC;AAG/B;IADC,MAAM,EAAE;8BACS,MAAM;wDAAC;AALd,wBAAwB;IADpC,WAAW,EAAE;GACD,wBAAwB,CAgLpC;SAhLY,wBAAwB","sourcesContent":["import {isClass, isString, nameOf, Store} from \"@tsed/core\";\nimport {BaseContext, DIContext, Inject, Interceptor, InterceptorContext, InterceptorMethods, InterceptorNext} from \"@tsed/di\";\nimport {deserialize, serialize} from \"@tsed/json-mapper\";\nimport {Logger} from \"@tsed/logger\";\nimport {JsonEntityStore} from \"@tsed/schema\";\nimport {IncomingMessage, ServerResponse} from \"http\";\nimport {PlatformCachedObject} from \"../interfaces/PlatformCachedObject\";\nimport {PlatformCacheOptions} from \"../interfaces/PlatformCacheOptions\";\nimport {PlatformCache} from \"../services/PlatformCache\";\n\nconst cleanHeaders = (headers: Record<string, unknown>) => {\n return Object.entries(headers)\n .filter(([key]) => ![\"content-length\", \"x-request-id\", \"cache-control\"].includes(key))\n .reduce((headers, [key, value]) => {\n return {\n ...headers,\n [key]: value\n };\n }, {});\n};\n\n/**\n * @platform\n */\n@Interceptor()\nexport class PlatformCacheInterceptor implements InterceptorMethods {\n @Inject()\n protected cache: PlatformCache;\n\n @Inject()\n protected logger: Logger;\n\n async intercept(context: InterceptorContext<any, PlatformCacheOptions>, next: InterceptorNext) {\n if (this.cache.disabled()) {\n return next();\n }\n\n if (!this.isEndpoint(context)) {\n return this.cacheMethod(context, next);\n }\n\n return this.cacheResponse(context, next);\n }\n\n async canRefreshInBackground(key: string, {refreshThreshold, ttl}: {refreshThreshold?: number; ttl: any}, next: Function) {\n const inQueue = await this.hasKeyInQueue(key);\n\n if (refreshThreshold && !inQueue) {\n await this.addKeyToQueue(key);\n\n const currentTTL = await this.cache.ttl(key);\n const calculatedTTL = this.cache.calculateTTL(currentTTL, ttl);\n\n if (currentTTL < calculatedTTL - refreshThreshold) {\n await next();\n }\n\n await this.deleteKeyFromQueue(key);\n }\n }\n\n async cacheMethod(context: InterceptorContext<any, PlatformCacheOptions>, next: InterceptorNext) {\n const {type, ttl, collectionType, refreshThreshold, keyArgs, args} = this.getOptions(context);\n const key = [nameOf(context.target), context.propertyKey, keyArgs].join(\":\");\n\n const set = (result: any) => {\n const calculatedTTL = this.cache.calculateTTL(result, ttl);\n const data = serialize(result, {type, collectionType});\n this.cache.setCachedObject(key, data, {args, ttl: calculatedTTL});\n };\n\n const cachedObject = await this.cache.getCachedObject(key);\n\n if (!cachedObject) {\n const result = await next();\n\n set(result);\n\n return result;\n }\n\n this.canRefreshInBackground(key, {refreshThreshold, ttl}, async () => {\n const result = await next();\n await set(result);\n }).catch((er) =>\n this.logger.error({\n event: \"CACHE_ERROR\",\n method: \"cacheMethod\",\n concerned_key: key,\n class_name: nameOf(context.target),\n property_key: context.propertyKey,\n error_description: er.message,\n stack: er.stack\n })\n );\n\n const {data} = cachedObject;\n\n return deserialize(JSON.parse(data), {collectionType, type});\n }\n\n async cacheResponse(context: InterceptorContext<any, PlatformCacheOptions>, next: InterceptorNext) {\n const $ctx: BaseContext = context.args[context.args.length - 1];\n const {request, response} = $ctx;\n\n if (request.method !== \"GET\") {\n return next();\n }\n\n const {ttl, args, keyArgs} = this.getOptions(context);\n const key = [request.method, request.url, keyArgs].join(\":\");\n\n const cachedObject = await this.cache.getCachedObject(key);\n\n if (cachedObject && !(request.get(\"cache-control\") === \"no-cache\")) {\n return this.sendResponse(cachedObject, $ctx);\n }\n\n const result = await next();\n\n const calculatedTTL = this.cache.calculateTTL(result, ttl);\n\n $ctx.response.setHeaders({\n \"cache-control\": `max-age=${calculatedTTL}`\n });\n\n // cache final response with his headers and body\n response.onEnd(async () => {\n this.cache.setCachedObject(key, response.getBody(), {\n ttl: calculatedTTL,\n args,\n headers: cleanHeaders(response.getHeaders())\n });\n });\n\n return result;\n }\n\n protected getArgs(context: InterceptorContext<unknown, PlatformCacheOptions>) {\n return context.args.reduce((args, arg) => {\n if (arg instanceof DIContext || arg instanceof IncomingMessage || arg instanceof ServerResponse) {\n return args;\n }\n\n if (isClass(arg)) {\n return args.concat(serialize(arg));\n }\n\n return args.concat(arg);\n }, []);\n }\n\n protected getOptions(context: InterceptorContext<any, PlatformCacheOptions>) {\n const {ttl, type, collectionType, key: k = this.cache.defaultKeyResolver(), refreshThreshold} = context.options || {};\n\n const args = this.getArgs(context);\n const keyArgs = isString(k) ? k : k(args);\n\n return {refreshThreshold, ttl, type, args, collectionType, keyArgs};\n }\n\n protected isEndpoint({target, propertyKey}: InterceptorContext<any, PlatformCacheOptions>) {\n return Store.fromMethod(target, propertyKey).has(JsonEntityStore);\n }\n\n protected async hasKeyInQueue(key: string) {\n return !!(await this.cache.get(`$$queue:${key}`));\n }\n\n protected async addKeyToQueue(key: string) {\n await this.cache.set(`$$queue:${key}`, true, {ttl: 120});\n }\n\n protected async deleteKeyFromQueue(key: string) {\n await this.cache.del(`$$queue:${key}`);\n }\n\n protected sendResponse(cachedObject: PlatformCachedObject, $ctx: BaseContext) {\n const {headers, ttl} = cachedObject;\n const {request, response} = $ctx;\n\n const requestEtag = request.get(\"if-none-match\");\n\n if (requestEtag && headers.etag === requestEtag) {\n response.status(304).setHeaders(headers).body(undefined);\n\n return undefined;\n }\n\n const data = JSON.parse(cachedObject.data);\n\n $ctx.response\n .setHeaders({\n ...headers,\n \"x-cached\": \"true\",\n \"cache-control\": `max-age=${ttl}`\n })\n .body(data);\n\n return data;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"PlatformCacheInterceptor.js","sourceRoot":"","sources":["../../../src/interceptors/PlatformCacheInterceptor.ts"],"names":[],"mappings":"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","sourcesContent":["import {isClass, isString, nameOf, Store} from \"@tsed/core\";\nimport {BaseContext, DIContext, Inject, Interceptor, InterceptorContext, InterceptorMethods, InterceptorNext} from \"@tsed/di\";\nimport {deserialize, serialize} from \"@tsed/json-mapper\";\nimport {Logger} from \"@tsed/logger\";\nimport {JsonEntityStore} from \"@tsed/schema\";\nimport {IncomingMessage, ServerResponse} from \"http\";\nimport {PlatformCachedObject} from \"../interfaces/PlatformCachedObject\";\nimport {PlatformCacheOptions} from \"../interfaces/PlatformCacheOptions\";\nimport {PlatformCache} from \"../services/PlatformCache\";\n\nconst cleanHeaders = (headers: Record<string, unknown>) => {\n return Object.entries(headers)\n .filter(([key]) => ![\"content-length\", \"x-request-id\", \"cache-control\"].includes(key))\n .reduce((headers, [key, value]) => {\n return {\n ...headers,\n [key]: value\n };\n }, {});\n};\n\n/**\n * @platform\n */\n@Interceptor()\nexport class PlatformCacheInterceptor implements InterceptorMethods {\n @Inject()\n protected cache: PlatformCache;\n\n @Inject()\n protected logger: Logger;\n\n async intercept(context: InterceptorContext<any, PlatformCacheOptions>, next: InterceptorNext) {\n if (this.cache.disabled()) {\n return next();\n }\n\n if (!this.isEndpoint(context)) {\n return this.cacheMethod(context, next);\n }\n\n return this.cacheResponse(context, next);\n }\n\n async canRefreshInBackground(key: string, {refreshThreshold, ttl}: {refreshThreshold?: number; ttl: any}, next: Function) {\n const inQueue = await this.hasKeyInQueue(key);\n\n if (refreshThreshold && !inQueue) {\n await this.addKeyToQueue(key);\n\n const currentTTL = await this.cache.ttl(key);\n const calculatedTTL = this.cache.calculateTTL(currentTTL, ttl);\n\n if (currentTTL === undefined || currentTTL < calculatedTTL - refreshThreshold) {\n await next();\n }\n\n await this.deleteKeyFromQueue(key);\n }\n }\n\n async cacheMethod(context: InterceptorContext<any, PlatformCacheOptions>, next: InterceptorNext) {\n const {type, ttl, collectionType, refreshThreshold, keyArgs, args} = this.getOptions(context);\n const key = [nameOf(context.target), context.propertyKey, keyArgs].join(\":\");\n\n const set = (result: any) => {\n const calculatedTTL = this.cache.calculateTTL(result, ttl);\n const data = serialize(result, {type, collectionType});\n this.cache.setCachedObject(key, data, {args, ttl: calculatedTTL});\n };\n\n const cachedObject = await this.cache.getCachedObject(key);\n\n if (!cachedObject) {\n const result = await next();\n\n set(result);\n\n return result;\n }\n\n this.canRefreshInBackground(key, {refreshThreshold, ttl}, async () => {\n const result = await next();\n await set(result);\n }).catch((er) =>\n this.logger.error({\n event: \"CACHE_ERROR\",\n method: \"cacheMethod\",\n concerned_key: key,\n class_name: nameOf(context.target),\n property_key: context.propertyKey,\n error_description: er.message,\n stack: er.stack\n })\n );\n\n const {data} = cachedObject;\n\n return deserialize(JSON.parse(data), {collectionType, type});\n }\n\n async cacheResponse(context: InterceptorContext<any, PlatformCacheOptions>, next: InterceptorNext) {\n const $ctx: BaseContext = context.args[context.args.length - 1];\n const {request, response} = $ctx;\n\n if (request.method !== \"GET\") {\n return next();\n }\n\n const {ttl, args, keyArgs} = this.getOptions(context);\n const key = [request.method, request.url, keyArgs].join(\":\");\n\n const cachedObject = await this.cache.getCachedObject(key);\n\n if (cachedObject && !(request.get(\"cache-control\") === \"no-cache\")) {\n return this.sendResponse(cachedObject, $ctx);\n }\n\n const result = await next();\n\n const calculatedTTL = this.cache.calculateTTL(result, ttl);\n\n $ctx.response.setHeaders({\n \"cache-control\": `max-age=${calculatedTTL}`\n });\n\n // cache final response with his headers and body\n response.onEnd(async () => {\n this.cache.setCachedObject(key, response.getBody(), {\n ttl: calculatedTTL,\n args,\n headers: cleanHeaders(response.getHeaders())\n });\n });\n\n return result;\n }\n\n protected getArgs(context: InterceptorContext<unknown, PlatformCacheOptions>) {\n return context.args.reduce((args, arg) => {\n if (arg instanceof DIContext || arg instanceof IncomingMessage || arg instanceof ServerResponse) {\n return args;\n }\n\n if (isClass(arg)) {\n return args.concat(serialize(arg));\n }\n\n return args.concat(arg);\n }, []);\n }\n\n protected getOptions(context: InterceptorContext<any, PlatformCacheOptions>) {\n const {ttl, type, collectionType, key: k = this.cache.defaultKeyResolver(), refreshThreshold} = context.options || {};\n\n const args = this.getArgs(context);\n const keyArgs = isString(k) ? k : k(args);\n\n return {refreshThreshold, ttl, type, args, collectionType, keyArgs};\n }\n\n protected isEndpoint({target, propertyKey}: InterceptorContext<any, PlatformCacheOptions>) {\n return Store.fromMethod(target, propertyKey).has(JsonEntityStore);\n }\n\n protected async hasKeyInQueue(key: string) {\n return !!(await this.cache.get(`$$queue:${key}`));\n }\n\n protected async addKeyToQueue(key: string) {\n await this.cache.set(`$$queue:${key}`, true, {ttl: 120});\n }\n\n protected async deleteKeyFromQueue(key: string) {\n await this.cache.del(`$$queue:${key}`);\n }\n\n protected sendResponse(cachedObject: PlatformCachedObject, $ctx: BaseContext) {\n const {headers, ttl} = cachedObject;\n const {request, response} = $ctx;\n\n const requestEtag = request.get(\"if-none-match\");\n\n if (requestEtag && headers.etag === requestEtag) {\n response.status(304).setHeaders(headers).body(undefined);\n\n return undefined;\n }\n\n const data = JSON.parse(cachedObject.data);\n\n $ctx.response\n .setHeaders({\n ...headers,\n \"x-cached\": \"true\",\n \"cache-control\": `max-age=${ttl}`\n })\n .body(data);\n\n return data;\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PlatformCacheOptions.js","sourceRoot":"","sources":["../../../src/interfaces/PlatformCacheOptions.ts"],"names":[],"mappings":"","sourcesContent":["import {MetadataTypes} from \"@tsed/core\";\nimport {BaseContext} from \"@tsed/di\";\nimport type {
|
|
1
|
+
{"version":3,"file":"PlatformCacheOptions.js","sourceRoot":"","sources":["../../../src/interfaces/PlatformCacheOptions.ts"],"names":[],"mappings":"","sourcesContent":["import {MetadataTypes} from \"@tsed/core\";\nimport {BaseContext} from \"@tsed/di\";\nimport type {Ttl} from \"../services/PlatformCache\";\n\nexport interface PlatformCacheOptions extends MetadataTypes {\n ttl?: Ttl;\n key?: string | ((args: any[], ctx?: BaseContext) => string);\n refreshThreshold?: number;\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"interfaces.js","sourceRoot":"","sources":["../../../src/interfaces/interfaces.ts"],"names":[],"mappings":"","sourcesContent":["import type {BaseContext} from \"@tsed/di\";\nimport type {Cache,
|
|
1
|
+
{"version":3,"file":"interfaces.js","sourceRoot":"","sources":["../../../src/interfaces/interfaces.ts"],"names":[],"mappings":"","sourcesContent":["import type {BaseContext} from \"@tsed/di\";\nimport type {Cache, CachingConfig, Store} from \"cache-manager\";\nimport {FactoryStore} from \"cache-manager/dist/caching\";\nimport type {CacheManager} from \"../services/PlatformCache\";\n\n/**\n * @deprecated Since 2022-11. Use FactoryStore instead.\n */\nexport type PlatformCacheLegacyStoreFactory = {\n create(...args: any[]): Promise<Store | any> | Store | any;\n};\n\nexport type PlatformCacheSettings<Config extends object = any, S extends Store = any> = CachingConfig<Config> & {\n caches?: Cache[];\n store?: \"memory\" | Store | PlatformCacheLegacyStoreFactory | FactoryStore<S, Config>;\n max?: number;\n keyResolver?: (args: any[], ctx: BaseContext) => string;\n\n /**\n * You may pass in any other arguments these will be passed on to the `create` method of your store,\n * otherwise they will be ignored.\n */\n [key: string]: any;\n};\n\ndeclare global {\n // eslint-disable-next-line @typescript-eslint/no-namespace\n namespace TsED {\n interface Configuration {\n cache?: PlatformCacheSettings | false;\n }\n }\n}\n\nexport interface OnCreateCacheManager {\n $onCreateCacheManager(cache: CacheManager): void | Promise<void>;\n}\n"]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { __decorate, __metadata } from "tslib";
|
|
2
|
-
import { isClass, isFunction } from "@tsed/core";
|
|
2
|
+
import { isClass, isFunction, isString } from "@tsed/core";
|
|
3
3
|
import { Configuration, Inject, InjectorService, Module } from "@tsed/di";
|
|
4
4
|
import { deserialize, serialize } from "@tsed/json-mapper";
|
|
5
5
|
import { Logger } from "@tsed/logger";
|
|
@@ -42,17 +42,18 @@ let PlatformCache = class PlatformCache {
|
|
|
42
42
|
return this.cache.store.ttl(key);
|
|
43
43
|
}
|
|
44
44
|
}
|
|
45
|
-
wrap(key, fetch,
|
|
45
|
+
wrap(key, fetch, ttl) {
|
|
46
46
|
if (!this.cache) {
|
|
47
47
|
return fetch();
|
|
48
48
|
}
|
|
49
|
-
return this.cache?.wrap(key, fetch,
|
|
49
|
+
return this.cache?.wrap(key, fetch, ttl);
|
|
50
50
|
}
|
|
51
51
|
async get(key, options = {}) {
|
|
52
52
|
return deserialize(this.cache?.get(key), options);
|
|
53
53
|
}
|
|
54
54
|
async set(key, value, options) {
|
|
55
|
-
|
|
55
|
+
await this.cache?.set(key, value, options?.ttl);
|
|
56
|
+
return;
|
|
56
57
|
}
|
|
57
58
|
async getCachedObject(key) {
|
|
58
59
|
try {
|
|
@@ -109,15 +110,25 @@ let PlatformCache = class PlatformCache {
|
|
|
109
110
|
async createCacheManager(settings) {
|
|
110
111
|
const { caches, store = "memory", ttl, ...props } = settings;
|
|
111
112
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
112
|
-
const {
|
|
113
|
+
const { multiCaching, caching } = await import("cache-manager");
|
|
113
114
|
return caches?.length
|
|
114
|
-
?
|
|
115
|
-
:
|
|
115
|
+
? multiCaching(caches)
|
|
116
|
+
: caching(await this.mapStore(store), {
|
|
116
117
|
...props,
|
|
117
|
-
ttl
|
|
118
|
-
store: isFunction(store) ? await store() : store
|
|
118
|
+
ttl
|
|
119
119
|
});
|
|
120
120
|
}
|
|
121
|
+
async mapStore(store) {
|
|
122
|
+
if (!isString(store)) {
|
|
123
|
+
if ("create" in store) {
|
|
124
|
+
store = store.create;
|
|
125
|
+
}
|
|
126
|
+
if (isFunction(store)) {
|
|
127
|
+
return await store();
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
return store;
|
|
131
|
+
}
|
|
121
132
|
};
|
|
122
133
|
__decorate([
|
|
123
134
|
Configuration(),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PlatformCache.js","sourceRoot":"","sources":["../../../src/services/PlatformCache.ts"],"names":[],"mappings":";AAAA,OAAO,EAAC,OAAO,EAAE,UAAU,EAAC,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"PlatformCache.js","sourceRoot":"","sources":["../../../src/services/PlatformCache.ts"],"names":[],"mappings":"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","sourcesContent":["import {isClass, isFunction, isString} from \"@tsed/core\";\nimport {Configuration, Inject, InjectorService, Module} from \"@tsed/di\";\nimport {deserialize, JsonDeserializerOptions, serialize} from \"@tsed/json-mapper\";\nimport {Logger} from \"@tsed/logger\";\nimport type {Cache, CachingConfig, MultiCache} from \"cache-manager\";\nimport {PlatformCacheSettings} from \"../interfaces/interfaces\";\nimport {PlatformCachedObject} from \"../interfaces/PlatformCachedObject\";\n\nconst defaultKeyResolver = (args: any[]) => {\n return args.map((arg: any) => (isClass(arg) ? JSON.stringify(serialize(arg)) : arg)).join(\":\");\n};\n\nexport type CacheManager = Cache | MultiCache;\nexport type Ttl = number | ((result: any) => number);\n\n/**\n * @platform\n */\n@Module()\nexport class PlatformCache {\n @Configuration()\n protected settings: Configuration;\n\n @Inject()\n protected injector: InjectorService;\n\n @Inject()\n protected logger: Logger;\n\n #cache: CacheManager | undefined;\n\n get cache() {\n return this.#cache;\n }\n\n async $onInit() {\n const settings = this.settings.get<PlatformCacheSettings>(\"cache\");\n\n if (settings) {\n this.#cache = await this.createCacheManager(settings);\n\n await this.injector.emit(\"$onCreateCacheManager\", this.#cache);\n }\n }\n\n disabled(): boolean {\n return !this.settings.get<PlatformCacheSettings>(\"cache\");\n }\n\n defaultKeyResolver() {\n return this.settings.get<(args: any[], ctx?: any) => string>(\"cache.keyResolver\", defaultKeyResolver);\n }\n\n defaultTtl() {\n return this.settings.get<Ttl>(\"cache.ttl\");\n }\n\n calculateTTL(result?: any, currentTtl?: Ttl): number {\n const ttl = currentTtl === undefined ? this.defaultTtl() : currentTtl;\n\n return isFunction(ttl) ? ttl(result) : ttl;\n }\n\n async ttl(key: string) {\n if (this.cache && \"store\" in this.cache && this.cache.store.ttl) {\n return this.cache.store.ttl(key);\n }\n }\n\n wrap<T>(key: string, fetch: () => Promise<T>, ttl?: number): Promise<T> {\n if (!this.cache) {\n return fetch();\n }\n\n return this.cache?.wrap<T>(key, fetch, ttl);\n }\n\n async get<T>(key: string, options: JsonDeserializerOptions = {}): Promise<T | undefined> {\n return deserialize(this.cache?.get<T>(key), options);\n }\n\n async set<T>(key: string, value: any, options?: CachingConfig<T>): Promise<T | undefined> {\n await this.cache?.set(key, value, options?.ttl);\n return;\n }\n\n async getCachedObject(key: string) {\n try {\n return await this.get<PlatformCachedObject>(key);\n } catch (er) {\n this.logger.error({\n event: \"CACHE_ERROR\",\n method: \"getCachedObject\",\n error: er\n });\n }\n }\n\n async setCachedObject(key: string, data: any, opts: {ttl: number} & Record<string, any>) {\n try {\n await this.set<PlatformCachedObject>(\n key,\n {\n ...opts,\n data: JSON.stringify(data)\n },\n {\n ttl: opts.ttl\n }\n );\n } catch (er) {\n this.logger.error({\n event: \"CACHE_ERROR\",\n method: \"setCachedObject\",\n error: er\n });\n }\n }\n\n async del(key: string): Promise<void> {\n await this.cache?.del(key);\n }\n\n async reset(): Promise<void> {\n // @ts-ignore\n await this.cache?.reset();\n }\n\n async keys(...args: any[]): Promise<string[]> {\n if (this.cache && \"store\" in this.cache && this.cache.store.keys) {\n return this.cache.store.keys(...args);\n }\n\n // istanbul ignore next\n return [];\n }\n\n async getMatchingKeys(patterns: string): Promise<string[]> {\n const [keys, {default: micromatch}] = await Promise.all([this.keys(), import(\"micromatch\")]);\n\n return micromatch(keys, patterns);\n }\n\n async deleteMatchingKeys(patterns: string): Promise<string[]> {\n const keys = await this.getMatchingKeys(patterns);\n\n await Promise.all(keys.map((key: string) => this.del(key)));\n\n return keys;\n }\n\n protected async createCacheManager(settings: PlatformCacheSettings) {\n const {caches, store = \"memory\", ttl, ...props} = settings;\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const {multiCaching, caching} = await import(\"cache-manager\");\n\n return caches?.length\n ? multiCaching(caches)\n : caching(await this.mapStore(store), {\n ...props,\n ttl\n });\n }\n\n private async mapStore(store: string | Function | {create: Function}) {\n if (!isString(store)) {\n if (\"create\" in store) {\n store = store.create;\n }\n\n if (isFunction(store)) {\n return await store();\n }\n }\n\n return store;\n }\n}\n"]}
|
|
@@ -19,7 +19,7 @@ export declare class PlatformCacheInterceptor implements InterceptorMethods {
|
|
|
19
19
|
protected getArgs(context: InterceptorContext<unknown, PlatformCacheOptions>): any;
|
|
20
20
|
protected getOptions(context: InterceptorContext<any, PlatformCacheOptions>): {
|
|
21
21
|
refreshThreshold: number | undefined;
|
|
22
|
-
ttl:
|
|
22
|
+
ttl: import("../services/PlatformCache").Ttl | undefined;
|
|
23
23
|
type: any;
|
|
24
24
|
args: any;
|
|
25
25
|
collectionType: any;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { MetadataTypes } from "@tsed/core";
|
|
2
2
|
import { BaseContext } from "@tsed/di";
|
|
3
|
-
import type {
|
|
3
|
+
import type { Ttl } from "../services/PlatformCache";
|
|
4
4
|
export interface PlatformCacheOptions extends MetadataTypes {
|
|
5
|
-
ttl?:
|
|
5
|
+
ttl?: Ttl;
|
|
6
6
|
key?: string | ((args: any[], ctx?: BaseContext) => string);
|
|
7
7
|
refreshThreshold?: number;
|
|
8
8
|
}
|
|
@@ -1,11 +1,16 @@
|
|
|
1
1
|
import type { BaseContext } from "@tsed/di";
|
|
2
|
-
import type { Cache,
|
|
2
|
+
import type { Cache, CachingConfig, Store } from "cache-manager";
|
|
3
|
+
import { FactoryStore } from "cache-manager/dist/caching";
|
|
3
4
|
import type { CacheManager } from "../services/PlatformCache";
|
|
4
|
-
|
|
5
|
+
/**
|
|
6
|
+
* @deprecated Since 2022-11. Use FactoryStore instead.
|
|
7
|
+
*/
|
|
8
|
+
export declare type PlatformCacheLegacyStoreFactory = {
|
|
9
|
+
create(...args: any[]): Promise<Store | any> | Store | any;
|
|
10
|
+
};
|
|
11
|
+
export declare type PlatformCacheSettings<Config extends object = any, S extends Store = any> = CachingConfig<Config> & {
|
|
5
12
|
caches?: Cache[];
|
|
6
|
-
store?: "memory" |
|
|
7
|
-
create(...args: any[]): Store;
|
|
8
|
-
} | (() => any);
|
|
13
|
+
store?: "memory" | Store | PlatformCacheLegacyStoreFactory | FactoryStore<S, Config>;
|
|
9
14
|
max?: number;
|
|
10
15
|
keyResolver?: (args: any[], ctx: BaseContext) => string;
|
|
11
16
|
/**
|
|
@@ -13,7 +18,7 @@ export interface PlatformCacheSettings extends CacheOptions, CachingConfig {
|
|
|
13
18
|
* otherwise they will be ignored.
|
|
14
19
|
*/
|
|
15
20
|
[key: string]: any;
|
|
16
|
-
}
|
|
21
|
+
};
|
|
17
22
|
declare global {
|
|
18
23
|
namespace TsED {
|
|
19
24
|
interface Configuration {
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { Configuration, InjectorService } from "@tsed/di";
|
|
2
2
|
import { JsonDeserializerOptions } from "@tsed/json-mapper";
|
|
3
|
-
import type { Cache, CachingConfig, MultiCache, TtlFunction } from "cache-manager";
|
|
4
|
-
import { PlatformCachedObject } from "../interfaces/PlatformCachedObject";
|
|
5
|
-
import { PlatformCacheSettings } from "../interfaces/interfaces";
|
|
6
3
|
import { Logger } from "@tsed/logger";
|
|
4
|
+
import type { Cache, CachingConfig, MultiCache } from "cache-manager";
|
|
5
|
+
import { PlatformCacheSettings } from "../interfaces/interfaces";
|
|
6
|
+
import { PlatformCachedObject } from "../interfaces/PlatformCachedObject";
|
|
7
7
|
export declare type CacheManager = Cache | MultiCache;
|
|
8
|
+
export declare type Ttl = number | ((result: any) => number);
|
|
8
9
|
/**
|
|
9
10
|
* @platform
|
|
10
11
|
*/
|
|
@@ -17,12 +18,12 @@ export declare class PlatformCache {
|
|
|
17
18
|
$onInit(): Promise<void>;
|
|
18
19
|
disabled(): boolean;
|
|
19
20
|
defaultKeyResolver(): (args: any[], ctx?: any) => string;
|
|
20
|
-
defaultTtl():
|
|
21
|
-
calculateTTL(result?: any, currentTtl?:
|
|
22
|
-
ttl(key: string): Promise<
|
|
23
|
-
wrap<T>(key: string, fetch: () => Promise<T>,
|
|
21
|
+
defaultTtl(): Ttl;
|
|
22
|
+
calculateTTL(result?: any, currentTtl?: Ttl): number;
|
|
23
|
+
ttl(key: string): Promise<number | undefined>;
|
|
24
|
+
wrap<T>(key: string, fetch: () => Promise<T>, ttl?: number): Promise<T>;
|
|
24
25
|
get<T>(key: string, options?: JsonDeserializerOptions): Promise<T | undefined>;
|
|
25
|
-
set<T>(key: string, value: any, options?: CachingConfig): Promise<T | undefined>;
|
|
26
|
+
set<T>(key: string, value: any, options?: CachingConfig<T>): Promise<T | undefined>;
|
|
26
27
|
getCachedObject(key: string): Promise<PlatformCachedObject | undefined>;
|
|
27
28
|
setCachedObject(key: string, data: any, opts: {
|
|
28
29
|
ttl: number;
|
|
@@ -32,5 +33,6 @@ export declare class PlatformCache {
|
|
|
32
33
|
keys(...args: any[]): Promise<string[]>;
|
|
33
34
|
getMatchingKeys(patterns: string): Promise<string[]>;
|
|
34
35
|
deleteMatchingKeys(patterns: string): Promise<string[]>;
|
|
35
|
-
protected createCacheManager(settings: PlatformCacheSettings): Promise<MultiCache>;
|
|
36
|
+
protected createCacheManager(settings: PlatformCacheSettings): Promise<MultiCache | import("cache-manager").MemoryCache>;
|
|
37
|
+
private mapStore;
|
|
36
38
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tsed/platform-cache",
|
|
3
|
-
"version": "7.
|
|
3
|
+
"version": "7.3.0",
|
|
4
4
|
"description": "Platform cache module for Ts.ED Framework",
|
|
5
5
|
"private": false,
|
|
6
6
|
"source": "./src/index.ts",
|
|
@@ -21,23 +21,22 @@
|
|
|
21
21
|
"barrels": "yarn barrelsby --delete -d ./src -e \"\\.spec\\.ts\" -e \"__mock__\" -e \".benchmark.ts\""
|
|
22
22
|
},
|
|
23
23
|
"dependencies": {
|
|
24
|
-
"
|
|
25
|
-
"cache-manager": "^4.1.0",
|
|
24
|
+
"cache-manager": "^5.1.3",
|
|
26
25
|
"micromatch": "4.0.5",
|
|
27
26
|
"tslib": "2.4.0"
|
|
28
27
|
},
|
|
29
28
|
"devDependencies": {
|
|
30
|
-
"@tsed/core": "7.
|
|
31
|
-
"@tsed/di": "7.
|
|
32
|
-
"@tsed/json-mapper": "7.
|
|
33
|
-
"@tsed/schema": "7.
|
|
29
|
+
"@tsed/core": "7.3.0",
|
|
30
|
+
"@tsed/di": "7.3.0",
|
|
31
|
+
"@tsed/json-mapper": "7.3.0",
|
|
32
|
+
"@tsed/schema": "7.3.0",
|
|
34
33
|
"@types/micromatch": "^4.0.1"
|
|
35
34
|
},
|
|
36
35
|
"peerDependencies": {
|
|
37
|
-
"@tsed/core": "^7.
|
|
38
|
-
"@tsed/di": "^7.
|
|
39
|
-
"@tsed/json-mapper": "^7.
|
|
40
|
-
"@tsed/schema": "^7.
|
|
36
|
+
"@tsed/core": "^7.3.0",
|
|
37
|
+
"@tsed/di": "^7.3.0",
|
|
38
|
+
"@tsed/json-mapper": "^7.3.0",
|
|
39
|
+
"@tsed/schema": "^7.3.0"
|
|
41
40
|
},
|
|
42
41
|
"peerDependenciesMeta": {
|
|
43
42
|
"@tsed/core": {
|