@vercel/functions 3.3.6 → 3.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,20 @@
1
1
  # @vercel/functions
2
2
 
3
+ ## 3.4.1
4
+
5
+ ### Patch Changes
6
+
7
+ - Fix InMemoryCache to use JSON serialization for consistency with RuntimeCache ([#14751](https://github.com/vercel/vercel/pull/14751))
8
+
9
+ InMemoryCache now serializes values with `JSON.stringify()` on set and deserializes with `JSON.parse()` on get, matching the behavior of RuntimeCache. This ensures consistent behavior when switching between cache implementations (e.g., in-memory for development, remote for production), particularly for types that don't survive JSON round-trips like `Date`, `Map`, `Set`, and `undefined`.
10
+
11
+ ## 3.4.0
12
+
13
+ ### Minor Changes
14
+
15
+ - Fix cache tags to be URL encoded before being sent to the cache API. Tags containing special characters (spaces, commas, ampersands, etc.) are now properly encoded using `encodeURIComponent`. This ([#14749](https://github.com/vercel/vercel/pull/14749))
16
+ ensures tags like `"my tag"` or `"category,item"` are correctly handled when setting cache entries or expiring tags.
17
+
3
18
  ## 3.3.6
4
19
 
5
20
  ### Patch Changes
@@ -32,13 +32,14 @@ class InMemoryCache {
32
32
  await this.delete(key);
33
33
  return null;
34
34
  }
35
- return entry.value;
35
+ return JSON.parse(entry.value);
36
36
  }
37
37
  return null;
38
38
  }
39
39
  async set(key, value, options) {
40
+ const serialized = JSON.stringify(value ?? null);
40
41
  this.cache[key] = {
41
- value,
42
+ value: serialized,
42
43
  lastModified: Date.now(),
43
44
  ttl: options?.ttl,
44
45
  tags: new Set(options?.tags || [])
package/cache/index.js CHANGED
@@ -37,6 +37,21 @@ const defaultKeyHashFunction = (key) => {
37
37
  return (hash >>> 0).toString(16);
38
38
  };
39
39
  const defaultNamespaceSeparator = "$";
40
+ function encodeTags(tags) {
41
+ return tags.map(encodeURIComponent);
42
+ }
43
+ function encodeTag(tag) {
44
+ return Array.isArray(tag) ? encodeTags(tag) : encodeURIComponent(tag);
45
+ }
46
+ function encodeOptions(options) {
47
+ if (!options) {
48
+ return void 0;
49
+ }
50
+ if (options.tags && options.tags.length > 0) {
51
+ return { ...options, tags: encodeTags(options.tags) };
52
+ }
53
+ return options;
54
+ }
40
55
  let inMemoryCacheInstance = null;
41
56
  let buildCacheInstance = null;
42
57
  const getCache = (cacheOptions) => {
@@ -71,13 +86,17 @@ function wrapWithKeyTransformation(resolveCache, makeKey) {
71
86
  return resolveCache().get(makeKey(key));
72
87
  },
73
88
  set: (key, value, options) => {
74
- return resolveCache().set(makeKey(key), value, options);
89
+ const encodedOptions = encodeOptions(options);
90
+ if (encodedOptions) {
91
+ return resolveCache().set(makeKey(key), value, encodedOptions);
92
+ }
93
+ return resolveCache().set(makeKey(key), value);
75
94
  },
76
95
  delete: (key) => {
77
96
  return resolveCache().delete(makeKey(key));
78
97
  },
79
98
  expireTag: (tag) => {
80
- return resolveCache().expireTag(tag);
99
+ return resolveCache().expireTag(encodeTag(tag));
81
100
  }
82
101
  };
83
102
  }
@@ -261,7 +261,7 @@ An instance of the Vercel Runtime Cache.
261
261
 
262
262
  #### Defined in
263
263
 
264
- [packages/functions/src/cache/index.ts:33](https://github.com/vercel/vercel/blob/main/packages/functions/src/cache/index.ts#L33)
264
+ [packages/functions/src/cache/index.ts:55](https://github.com/vercel/vercel/blob/main/packages/functions/src/cache/index.ts#L55)
265
265
 
266
266
  ---
267
267
 
package/package.json CHANGED
@@ -30,7 +30,7 @@
30
30
  "require": "./middleware.js"
31
31
  }
32
32
  },
33
- "version": "3.3.6",
33
+ "version": "3.4.1",
34
34
  "repository": {
35
35
  "directory": "packages/functions",
36
36
  "type": "git",