@adobe/spacecat-shared-utils 1.56.0 → 1.57.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-utils-v1.57.0](https://github.com/adobe/spacecat-shared/compare/@adobe/spacecat-shared-utils-v1.56.0...@adobe/spacecat-shared-utils-v1.57.0) (2025-10-09)
2
+
3
+
4
+ ### Features
5
+
6
+ * cdn-logs-infra provisioning response prettifier ([#1011](https://github.com/adobe/spacecat-shared/issues/1011)) ([2e83fbf](https://github.com/adobe/spacecat-shared/commit/2e83fbf4f67d48202cdf33538afcbc0146297161))
7
+
1
8
  # [@adobe/spacecat-shared-utils-v1.56.0](https://github.com/adobe/spacecat-shared/compare/@adobe/spacecat-shared-utils-v1.55.0...@adobe/spacecat-shared-utils-v1.56.0) (2025-10-07)
2
9
 
3
10
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adobe/spacecat-shared-utils",
3
- "version": "1.56.0",
3
+ "version": "1.57.0",
4
4
  "description": "Shared modules of the Spacecat Services - utils",
5
5
  "type": "module",
6
6
  "engines": {
@@ -12,6 +12,7 @@
12
12
  "scripts": {
13
13
  "test": "c8 mocha",
14
14
  "lint": "eslint .",
15
+ "lint:fix": "eslint --fix .",
15
16
  "clean": "rm -rf package-lock.json node_modules"
16
17
  },
17
18
  "mocha": {
@@ -0,0 +1,201 @@
1
+ /*
2
+ * Copyright 2024 Adobe. All rights reserved.
3
+ * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
+ * you may not use this file except in compliance with the License. You may obtain a copy
5
+ * of the License at http://www.apache.org/licenses/LICENSE-2.0
6
+ *
7
+ * Unless required by applicable law or agreed to in writing, software distributed under
8
+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9
+ * OF ANY KIND, either express or implied. See the License for the specific language
10
+ * governing permissions and limitations under the License.
11
+ */
12
+
13
+ /**
14
+ * CDN-specific transformations for log forwarding configuration preparation
15
+ */
16
+
17
+ const FASTLY_LOG_FORMAT = `{
18
+ "timestamp": "%{strftime(\\{"%Y-%m-%dT%H:%M:%S%z"\\}, time.start)}V",
19
+ "host": "%{if(req.http.Fastly-Orig-Host, req.http.Fastly-Orig-Host, req.http.Host)}V",
20
+ "url": "%{json.escape(req.url)}V",
21
+ "request_method": "%{json.escape(req.method)}V",
22
+ "request_referer": "%{json.escape(req.http.referer)}V",
23
+ "request_user_agent": "%{json.escape(req.http.User-Agent)}V",
24
+ "response_status": %{resp.status}V,
25
+ "response_content_type": "%{json.escape(resp.http.Content-Type)}V",
26
+ "client_country_code": "%{client.geo.country_name}V",
27
+ "time_to_first_byte": "%{time.to_first_byte}V"
28
+ }`;
29
+ const CDN_TRANSFORMATIONS = {
30
+ 'byocdn-fastly': (payload) => ({
31
+ 'Bucket Name': payload.bucketName,
32
+ Domain: `s3.${payload.region}.amazonaws.com`,
33
+ Path: `${payload.allowedPaths?.[0] || ''}%Y/%m/%d/%H/`,
34
+ 'Timestamp Format': '%Y-%m-%dT%H:%M:%S.000',
35
+ Placement: 'Format Version Default',
36
+ 'Log format': FASTLY_LOG_FORMAT,
37
+ 'Access method': 'User credentials',
38
+ 'Access key': payload.accessKey,
39
+ 'Secret key': payload.secretKey,
40
+ Period: 300,
41
+ 'Log line format': 'Blank',
42
+ Compression: 'Gzip',
43
+ 'Redundancy level': 'Standard',
44
+ ACL: 'None',
45
+ 'Server side encryption': 'None',
46
+ 'Maximum bytes': 0,
47
+ }),
48
+ 'byocdn-akamai': (payload) => ({
49
+ 'Bucket Name': payload.bucketName,
50
+ Region: payload.region,
51
+ Path: `${payload.allowedPaths?.[0] || ''}{%Y}/{%m}/{%d}/{%H}`,
52
+ 'Logged Properties': [
53
+ 'reqTimeSec',
54
+ 'country',
55
+ 'reqHost',
56
+ 'reqPath',
57
+ 'queryStr',
58
+ 'reqMethod',
59
+ 'ua',
60
+ 'statusCode',
61
+ 'referer',
62
+ 'rspContentType',
63
+ 'timeToFirstByte',
64
+ ],
65
+ 'Log file prefix': '{%Y}-{%m}-{%d}T{%H}:{%M}:{%S}.000',
66
+ 'Log file suffix': '.log',
67
+ 'Log interval': '60 seconds',
68
+ 'Access key': payload.accessKey,
69
+ 'Secret key': payload.secretKey,
70
+ }),
71
+ 'byocdn-cloudflare': (payload) => ({
72
+ 'Bucket Name': payload.bucketName,
73
+ Region: payload.region,
74
+ Path: `${payload.allowedPaths?.[0] || ''}{DATE}/`,
75
+ 'Timestamp format': 'RFC3339',
76
+ 'Sampling rate': 'All logs',
77
+ 'Organize logs into daily subfolders': 'Yes',
78
+ 'Logged Properties': [
79
+ 'EdgeStartTimestamp',
80
+ 'ClientCountry',
81
+ 'ClientRequestHost',
82
+ 'ClientRequestURI',
83
+ 'ClientRequestMethod',
84
+ 'ClientRequestUserAgent',
85
+ 'EdgeResponseStatus',
86
+ 'ClientRequestReferer',
87
+ 'EdgeResponseContentType',
88
+ 'EdgeTimeToFirstByteMs',
89
+ ],
90
+ 'Ownership token': 'Please reach out to Adobe support for obtaining the token once you completed the configuration.',
91
+ }),
92
+ 'byocdn-cloudfront': (payload) => ({
93
+ 'Bucket Name': payload.bucketName,
94
+ Region: payload.region,
95
+ 'Delivery destination ARN': payload.deliveryDestinationArn,
96
+ 'Delivery Destination Name': payload.deliveryDestinationName,
97
+ 'Destination AWS Account ID': '640168421876',
98
+ 'Path suffix': '/{yyyy}/{MM}/{dd}/{HH}',
99
+ 'Logged Properties': [
100
+ 'date',
101
+ 'time',
102
+ 'x-edge-location',
103
+ 'cs-method',
104
+ 'x-host-header',
105
+ 'cs-uri-stem',
106
+ 'sc-status',
107
+ 'cs(Referer)',
108
+ 'cs(User-Agent)',
109
+ 'time-to-first-byte',
110
+ 'sc-content-type',
111
+ ],
112
+ }),
113
+ 'ams-cloudfront': (payload) => ({
114
+ 'Bucket Name': payload.bucketName,
115
+ Region: payload.region,
116
+ 'Delivery destination ARN': payload.deliveryDestinationArn,
117
+ 'Delivery Destination Name': payload.deliveryDestinationName,
118
+ 'Destination AWS Account ID': '640168421876',
119
+ 'Path suffix': '/{yyyy}/{MM}/{dd}/{HH}',
120
+ 'Logged Properties': [
121
+ 'date',
122
+ 'time',
123
+ 'x-edge-location',
124
+ 'cs-method',
125
+ 'x-host-header',
126
+ 'cs-uri-stem',
127
+ 'sc-status',
128
+ 'cs(Referer)',
129
+ 'cs(User-Agent)',
130
+ 'time-to-first-byte',
131
+ 'sc-content-type',
132
+ ],
133
+ }),
134
+ };
135
+
136
+ /**
137
+ * Prepares log forwarding configuration parameters
138
+ * from CDN-Logs-Infrastructure-Provisioning API result
139
+ *
140
+ * Takes the result of the CDN-Logs-Infrastructure-Provisioning API and prepares all configuration
141
+ * parameters needed for setting up log forwarding. Some parameters are read from the API result,
142
+ * while others are static values that don't come from the API.
143
+ *
144
+ * @param {Object} payload - The result from CDN-Logs-Infrastructure-Provisioning API
145
+ * @param {string} payload.logSource - The CDN type ('byocdn-fastly' | 'byocdn-akamai'
146
+ * | 'byocdn-cloudflare' | 'byocdn-cloudfront' | 'ams-cloudfront')
147
+ * @returns {Object} - The prepared log forwarding configuration parameters
148
+ * @throws {Error} - If logSource is not supported or missing
149
+ */
150
+ const prettifyLogForwardingConfig = (payload) => {
151
+ if (!payload) {
152
+ throw new Error('payload is required as input');
153
+ }
154
+
155
+ if (!payload.logSource) {
156
+ throw new Error('logSource is required in payload');
157
+ }
158
+
159
+ if (!payload.bucketName) {
160
+ throw new Error('bucketName is required in payload');
161
+ }
162
+
163
+ if (!payload.region) {
164
+ throw new Error('region is required in payload');
165
+ }
166
+
167
+ if (!payload.authMethod) {
168
+ throw new Error('authMethod is required in payload');
169
+ }
170
+
171
+ if (!payload.allowedPaths) {
172
+ throw new Error('allowedPaths is required in payload');
173
+ }
174
+
175
+ if (payload.logSource === 'byocdn-fastly' || payload.logSource === 'byocdn-akamai') {
176
+ if (!payload.accessKey) {
177
+ throw new Error('accessKey is required in payload');
178
+ }
179
+ if (!payload.secretKey) {
180
+ throw new Error('secretKey is required in payload');
181
+ }
182
+ }
183
+
184
+ if (payload.logSource === 'byocdn-cloudfront' || payload.logSource === 'ams-cloudfront') {
185
+ if (!payload.deliveryDestinationArn) {
186
+ throw new Error('deliveryDestinationArn is required in payload');
187
+ }
188
+ if (!payload.deliveryDestinationName) {
189
+ throw new Error('deliveryDestinationName is required in payload');
190
+ }
191
+ }
192
+
193
+ const transformation = CDN_TRANSFORMATIONS[payload.logSource];
194
+ if (!transformation) {
195
+ throw new Error(`Unsupported log source: ${payload.logSource}. Supported types: ${Object.keys(CDN_TRANSFORMATIONS).join(', ')}`);
196
+ }
197
+
198
+ return transformation(payload);
199
+ };
200
+
201
+ export { prettifyLogForwardingConfig };
package/src/index.js CHANGED
@@ -97,3 +97,5 @@ export { determineAEMCSPageId, getPageEditUrl } from './aem-content-api-utils.js
97
97
 
98
98
  export * as llmoConfig from './llmo-config.js';
99
99
  export * as schemas from './schemas.js';
100
+
101
+ export { prettifyLogForwardingConfig } from './cdn-helpers.js';