@adobe/spacecat-shared-http-utils 1.14.4 → 1.15.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/CHANGELOG.md CHANGED
@@ -1,3 +1,10 @@
1
+ # [@adobe/spacecat-shared-http-utils-v1.15.0](https://github.com/adobe/spacecat-shared/compare/@adobe/spacecat-shared-http-utils-v1.14.4...@adobe/spacecat-shared-http-utils-v1.15.0) (2025-07-18)
2
+
3
+
4
+ ### Features
5
+
6
+ * gzip support ([#858](https://github.com/adobe/spacecat-shared/issues/858)) ([b2ccb4c](https://github.com/adobe/spacecat-shared/commit/b2ccb4c83b220837b01ba1fe086e0f635a8eb07b))
7
+
1
8
  # [@adobe/spacecat-shared-http-utils-v1.14.4](https://github.com/adobe/spacecat-shared/compare/@adobe/spacecat-shared-http-utils-v1.14.3...@adobe/spacecat-shared-http-utils-v1.14.4) (2025-07-12)
2
9
 
3
10
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adobe/spacecat-shared-http-utils",
3
- "version": "1.14.4",
3
+ "version": "1.15.0",
4
4
  "description": "Shared modules of the Spacecat Services - HTTP Utils",
5
5
  "type": "module",
6
6
  "engines": {
package/src/index.js CHANGED
@@ -11,42 +11,76 @@
11
11
  */
12
12
 
13
13
  import { Response } from '@adobe/fetch';
14
+ import { gzipSync } from 'zlib';
14
15
 
15
16
  import LegacyApiKeyHandler from './auth/handlers/legacy-api-key.js';
16
17
  import AdobeImsHandler from './auth/handlers/ims.js';
17
18
  import ScopedApiKeyHandler from './auth/handlers/scoped-api-key.js';
18
19
  import JwtHandler from './auth/handlers/jwt.js';
19
20
 
20
- const HEADER_CONTENT_TYPE = 'content-type';
21
21
  const HEADER_ERROR = 'x-error';
22
-
22
+ const HEADER_CONTENT_TYPE = 'Content-Type';
23
+ const HEADER_CONTENT_ENCODING = 'Content-Encoding';
23
24
  const CONTENT_TYPE_JSON = 'application/json';
24
25
 
26
+ /**
27
+ * Case-insensitive getter for headers.
28
+ */
29
+ function getHeader(headers, key) {
30
+ const lowerKey = key.toLowerCase();
31
+ const actualKey = Object.keys(headers).find((k) => k.toLowerCase() === lowerKey);
32
+ return actualKey ? headers[actualKey] : undefined;
33
+ }
34
+
35
+ /**
36
+ * Case-insensitive setter for headers.
37
+ */
38
+ function setHeader(headers, key, value) {
39
+ const lowerKey = key.toLowerCase();
40
+ const actualKey = Object.keys(headers).find((k) => k.toLowerCase() === lowerKey);
41
+ if (actualKey) {
42
+ /* c8 ignore next 3 */
43
+ // eslint-disable-next-line no-param-reassign
44
+ headers[actualKey] = value;
45
+ } else {
46
+ // eslint-disable-next-line no-param-reassign
47
+ headers[key] = value;
48
+ }
49
+ }
50
+
25
51
  /**
26
52
  * Creates a response with a JSON body if the content-type is JSON. Defaults to 200 status.
27
53
  * If a header is already defined and has a different content-type, it is handled accordingly.
28
- * @param {object} body - Response body.
54
+ * If the content-encoding is set to 'gzip', the body will be gzipped.
55
+ *
56
+ * @param {object|string|Buffer} body - Response body.
29
57
  * @param {number} [status=200] - Optional status code.
30
58
  * @param {object} [headers={}] - Optional headers.
31
- * @return {Response} Response.
59
+ * @return {Response} Response object.
32
60
  */
33
61
  export function createResponse(body, status = 200, headers = {}) {
34
62
  let responseBody = body;
35
63
 
36
- // Check if headers already contain a 'content-type' key
37
- if (!headers[HEADER_CONTENT_TYPE]) {
38
- // Set content-type to JSON if not already set
39
- Object.assign(headers, { [HEADER_CONTENT_TYPE]: `${CONTENT_TYPE_JSON}; charset=utf-8` });
64
+ const contentType = getHeader(headers, HEADER_CONTENT_TYPE);
65
+ const contentEncoding = getHeader(headers, HEADER_CONTENT_ENCODING);
66
+ const wantsGzip = contentEncoding?.toLowerCase() === 'gzip';
67
+
68
+ // default to application/json if content-type not set
69
+ if (!contentType) {
70
+ setHeader(headers, HEADER_CONTENT_TYPE, `${CONTENT_TYPE_JSON}; charset=utf-8`);
40
71
  }
41
72
 
42
- // Stringify body if content-type is JSON
43
- if (headers[HEADER_CONTENT_TYPE].includes(CONTENT_TYPE_JSON)) {
44
- responseBody = body === '' ? '' : JSON.stringify(body);
73
+ const finalContentType = getHeader(headers, HEADER_CONTENT_TYPE);
74
+
75
+ // if content-type is JSON, serialize and optionally gzip
76
+ if (finalContentType?.toLowerCase().includes(CONTENT_TYPE_JSON)) {
77
+ const jsonBody = body === '' ? '' : JSON.stringify(body);
78
+ responseBody = wantsGzip ? gzipSync(Buffer.from(jsonBody)) : jsonBody;
45
79
  }
46
80
 
47
81
  return new Response(responseBody, {
48
- headers,
49
82
  status,
83
+ headers,
50
84
  });
51
85
  }
52
86