cds-caching 0.3.0 → 0.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -460,12 +460,21 @@ Templates support the following properties:
460
460
 
461
461
 
462
462
  ```javascript
463
-
464
- // Store with tags
463
+ // Store with static tag
465
464
  await cache.set("key", "value", {
466
465
  tags: [{ value: "user-123" }]
467
466
  })
468
467
 
468
+ // Store with template tag (will generate a tag like "tenant-global-user-anonymous")
469
+ await cache.set("key", "value", {
470
+ tags: [{ template: "tenant-{tenant}-user-{user}" }]
471
+ })
472
+
473
+ // Store with data-based tag
474
+ await cache.set("key", { id: 123, name: "Product" }, {
475
+ tags: [{ data: "id", prefix: "product-" }]
476
+ })
477
+
469
478
  // Invalidate by tag
470
479
  await cache.deleteByTag('user-123')
471
480
  ```
@@ -796,4 +805,4 @@ Contributions are welcome! Please read our contributing guidelines and submit pu
796
805
 
797
806
  ### License
798
807
 
799
- This project is licensed under the Apache License 2.0 - see the LICENSE file for details.
808
+ This project is licensed under the MIT License - see the LICENSE file for details.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cds-caching",
3
- "version": "0.3.0",
3
+ "version": "0.3.2",
4
4
  "description": "A caching plugin for SAP CAP applications supporting Redis",
5
5
  "repository": {
6
6
  "type": "git",
@@ -21,7 +21,7 @@ class CachingService extends cds.Service {
21
21
  this.options = this.options || {
22
22
  store: null,
23
23
  compression: null,
24
- credentials: { }
24
+ credentials: {}
25
25
  };
26
26
 
27
27
  let store;
@@ -74,6 +74,9 @@ class CachingService extends cds.Service {
74
74
  if (typeof event.data.value === "object") {
75
75
  event.data.value = JSON.stringify(event.data.value);
76
76
  }
77
+
78
+ console.log(event.data);
79
+
77
80
  await this.cache.set(event.data.key, event.data.value, (event.data.ttl || 0))
78
81
  });
79
82
 
@@ -239,7 +242,7 @@ class CachingService extends cds.Service {
239
242
  return cachedValue;
240
243
  }
241
244
  const response = await next();
242
- req.cacheOptions.tags = this.resolveTags(req.cacheOptions.tags, response, req.params);
245
+ req.cacheOptions.tags = this.resolveTags(req.cacheOptions.tags, response, { ...req.params, user: req.user.id, tenant: req.tenant, locale: req.locale, hash: this.createKey(req, { template: '{hash}' }) });
243
246
  await this.set(req.cacheKey, response, req.cacheOptions);
244
247
  return response;
245
248
  case "cds.ql":
@@ -259,7 +262,7 @@ class CachingService extends cds.Service {
259
262
  return this.get(query.cacheKey);
260
263
  }
261
264
  const data = await srv.run(query);
262
- options.tags = this.resolveTags(options.tags, data, query.params);
265
+ options.tags = this.resolveTags(options.tags, data, { ...query.params, hash: this.createKey(query, { template: '{hash}' }) });
263
266
  await this.set(query.cacheKey, data, options);
264
267
  return data;
265
268
  } else {
@@ -393,6 +396,36 @@ class CachingService extends cds.Service {
393
396
  return [tag];
394
397
  }
395
398
 
399
+ // Handle template-based tags
400
+ if (config.template) {
401
+ const createHash = (data) => crypto.createHash('md5').update(JSON.stringify(data)).digest('hex');
402
+
403
+ const hashParts = [
404
+ ...(data ? [data] : []),
405
+ ...(params ? [params] : [])
406
+ ];
407
+
408
+ const contextVars = {
409
+ tenant: params.tenant || 'global',
410
+ user: params.user || 'anonymous',
411
+ locale: params.locale || 'en',
412
+ hash: createHash(hashParts)
413
+ };
414
+
415
+ const value = config.template.replace(
416
+ /\{(tenant|user|locale|hash)\}/g,
417
+ (match, variable) => contextVars[variable]
418
+ );
419
+
420
+ const tag = [
421
+ config.prefix,
422
+ value,
423
+ config.suffix
424
+ ].filter(Boolean).join('');
425
+
426
+ return [tag];
427
+ }
428
+
396
429
  // Handle data-based tags
397
430
  if (config.data && dataArray.length) {
398
431
  return dataArray.flatMap(item => {
package/srv/util.js CHANGED
@@ -1,5 +1,20 @@
1
1
  const cds = require("@sap/cds")
2
2
 
3
+ const extractCacheProperties = (entity, prefix) => {
4
+ const result = {};
5
+ for (const key of Object.keys(entity)) {
6
+ if (key.startsWith(`@cache.${prefix}.`)) {
7
+ const subKey = key.substring(`@cache.${prefix}.`.length);
8
+ result[subKey] = entity[key];
9
+ }
10
+ }
11
+ // If there are no subproperties but the main property exists, use it directly
12
+ if (Object.keys(result).length === 0 && entity[`@cache.${prefix}`]) {
13
+ return entity[`@cache.${prefix}`];
14
+ }
15
+ return Object.keys(result).length > 0 ? result : undefined;
16
+ };
17
+
3
18
  const bindFunction = async (service, action, isBound = false) => {
4
19
  const cache = await cds.connect.to(action['@cache.service'] || "caching");
5
20
  cache.addCachableFunction(action.name.split('.').pop(), action, isBound);
@@ -9,8 +24,8 @@ const bindFunction = async (service, action, isBound = false) => {
9
24
  const cache = await cds.connect.to(action['@cache.service'] || "caching");
10
25
  const data = await cache.run(req, next, {
11
26
  ttl: action['@cache.ttl'],
12
- tags: action['@cache.tags'],
13
- key: action['@cache.key']
27
+ tags: action['@cache.tags'],
28
+ key: extractCacheProperties(action, 'key')
14
29
  });
15
30
  return data;
16
31
  })
@@ -21,10 +36,13 @@ const bindEntity = async (service, entity) => {
21
36
  service.prepend(function () {
22
37
  service.on('READ', entity.name, async (req, next) => {
23
38
  const cache = await cds.connect.to(entity['@cache.service'] || "caching");
39
+
40
+ console.log(entity);
41
+
24
42
  const data = await cache.run(req, next, {
25
43
  ttl: entity['@cache.ttl'],
26
- tags: entity['@cache.tags'],
27
- key: entity['@cache.key']
44
+ tags: entity['@cache.tags'],
45
+ key: extractCacheProperties(entity, 'key')
28
46
  });
29
47
  return data;
30
48
  })