@capillarytech/creatives-library 7.17.147 → 7.17.148

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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@capillarytech/creatives-library",
3
3
  "author": "meharaj",
4
- "version": "7.17.147",
4
+ "version": "7.17.148",
5
5
  "description": "Capillary creatives ui",
6
6
  "main": "./index.js",
7
7
  "module": "./index.es.js",
@@ -28,6 +28,7 @@ const CREATIVES_CDN_TRANSFORMATION_URL_SUFFIX_KEY = 'CREATIVES_CDN_TRANSFORMATIO
28
28
  const CREATIVES_CDN_OVERRIDE_DEFAULT_EMAIL_QUALITY_KEY = 'CREATIVES_CDN_OVERRIDE_DEFAULT_EMAIL_QUALITY';
29
29
  const CREATIVES_CDN_OVERRIDE_DEFAULT_EMAIL_QUALITY_MAPPING_KEY = 'CREATIVES_CDN_OVERRIDE_DEFAULT_EMAIL_QUALITY_MAPPING';
30
30
  export const CREATIVES_S3_ASSET_FILESIZES = 'CREATIVES_S3_ASSET_FILESIZES';
31
+ export const S3_CDN_MAP_KEY = 'S3_CDN_MAP';
31
32
 
32
33
  const HTTPS_STR = "https://"
33
34
  const ALLOWED_EXTENSIONS_STR = ".*(?:jpg|png|jpeg|gif)$"
@@ -110,6 +111,35 @@ const CHANNEL_CONFIGS = {
110
111
  }
111
112
  };
112
113
 
114
+ /**
115
+ * Retrieves the cluster-specific S3 CDN configuration from the given URL based on S3_CDN_MAP.
116
+ *
117
+ * @param {string} url - The URL to check for cluster-specific S3 CDN configuration.
118
+ * @returns {Object} - An object containing the cluster-specific S3 bucket path and CDN base URL.
119
+ */
120
+ const getClusterSpecificS3CdnConfigFromUrl = (url) => {
121
+ const S3_CDN_MAP = getLocalStorageItem(S3_CDN_MAP_KEY, true);
122
+ let CREATIVES_S3_BUCKET_PATH;
123
+ let CREATIVES_CDN_BASE_URL;
124
+
125
+ Object.entries(S3_CDN_MAP).some(([clusterS3Url, cdnConfigs]) => {
126
+ const {cdn_host, bucket_path} = cdnConfigs;
127
+ const s3UrlRegex = new RegExp(`^https://${clusterS3Url}/${bucket_path}/\.*`);
128
+ const cdnUrlRegex = new RegExp(`^https://${cdn_host}/\.*${bucket_path}/\.*`);
129
+
130
+ if(s3UrlRegex.test(url)) {
131
+ CREATIVES_S3_BUCKET_PATH = bucket_path;
132
+ CREATIVES_CDN_BASE_URL = `https://${cdn_host}`;
133
+ return true;
134
+ } else if(cdnUrlRegex.test(url)) {
135
+ CREATIVES_S3_BUCKET_PATH = bucket_path;
136
+ CREATIVES_CDN_BASE_URL = `https://${cdn_host}`;
137
+ return true;
138
+ }
139
+ });
140
+ return { CREATIVES_S3_BUCKET_PATH, CREATIVES_CDN_BASE_URL };
141
+ }
142
+
113
143
  /**
114
144
  *
115
145
  * @param {string} url : required
@@ -144,88 +174,86 @@ export const getCdnUrl = ({
144
174
  emailOverrideQuality = null,
145
175
  }) => {
146
176
  try{
177
+ let cdnUrl;
147
178
  const channelName = receivedChannelName?.toUpperCase();
148
179
  const channelSubType = receivedChannelSubType?.toUpperCase();
149
-
150
- const CREATIVES_CDN_BASE_URL = getLocalStorageItem(CREATIVES_CDN_BASE_URL_KEY);
180
+
151
181
  const CREATIVES_CDN_QUALITY_CONFIG = getLocalStorageItem(CREATIVES_CDN_QUALITY_CONFIG_KEY, true);
152
182
  const CREATIVES_CDN_TRANSFORMATION_URL_SUFFIX = getLocalStorageItem(CREATIVES_CDN_TRANSFORMATION_URL_SUFFIX_KEY);
153
- let CREATIVES_S3_BUCKET_PATH = getLocalStorageItem(CREATIVES_S3_BUCKET_PATH_KEY);
154
-
155
- //remove all leading and trailing forward slash with empty string, if leading/trailing forward slash is present in node env by mistake then url will not be correct hence removing them.
156
- CREATIVES_S3_BUCKET_PATH = CREATIVES_S3_BUCKET_PATH?.replace(/^\/|\/$/g, '');
183
+
184
+ //Get cluster specific S3 CDN configuration from the given URL based on S3_CDN_MAP
185
+ let { CREATIVES_S3_BUCKET_PATH, CREATIVES_CDN_BASE_URL } = getClusterSpecificS3CdnConfigFromUrl(url);
157
186
 
158
187
  //Basic validations on data stored in local storage.
159
188
  if (
160
189
  typeof CREATIVES_CDN_QUALITY_CONFIG !== "object" ||
161
190
  Array.isArray(CREATIVES_CDN_QUALITY_CONFIG) ||
162
191
  CREATIVES_CDN_QUALITY_CONFIG === null ||
163
- typeof CREATIVES_CDN_BASE_URL !== "string" ||
164
- typeof CREATIVES_CDN_TRANSFORMATION_URL_SUFFIX !== "string" ||
165
- typeof CREATIVES_S3_BUCKET_PATH !== 'string'
192
+ !CREATIVES_CDN_TRANSFORMATION_URL_SUFFIX ||
193
+ !CREATIVES_S3_BUCKET_PATH ||
194
+ !CREATIVES_CDN_BASE_URL
166
195
  )
167
196
  return url;
168
-
197
+
198
+ //remove all leading and trailing forward slash with empty string, if leading/trailing forward slash is present in node env by mistake then url will not be correct hence removing them.
199
+ CREATIVES_S3_BUCKET_PATH = CREATIVES_S3_BUCKET_PATH?.replace(/^\/|\/$/g, '');
200
+
169
201
  const QUALITY = CREATIVES_CDN_QUALITY_CONFIG?.[channelName] || CREATIVES_CDN_QUALITY_CONFIG?.DEFAULT;
202
+ const [_, assetKey] = url.split(CREATIVES_S3_BUCKET_PATH);
170
203
 
171
204
  const regexWithExtension = new RegExp(HTTPS_STR + ANY_STR + CREATIVES_S3_BUCKET_PATH + ANY_STR + ALLOWED_EXTENSIONS_STR)
172
205
  const regexWithoutExtension = new RegExp(HTTPS_STR + ANY_STR + CREATIVES_S3_BUCKET_PATH + ANY_STR);
173
-
174
- let skipTransformations = true;
175
-
206
+
176
207
  if (
177
208
  !regexWithoutExtension.test(url) ||
178
209
  !CHANNEL_CONFIGS?.[channelName] ||
179
210
  (channelSubType && !CHANNEL_CONFIGS?.[channelName]?.[channelSubType]) ||
180
- !CREATIVES_CDN_BASE_URL ||
181
- !CREATIVES_CDN_TRANSFORMATION_URL_SUFFIX ||
182
- !QUALITY
211
+ !QUALITY ||
212
+ !assetKey
183
213
  )
184
214
  return url;
215
+
216
+ let skipTransformations = true;
217
+ let applicableTransformations;
185
218
 
186
219
  //Skip transformations if extensions are not proper. Else consider transformations if available.
187
220
  if(regexWithExtension.test(url)){
188
221
  skipTransformations = false;
189
222
  }
190
-
191
- const [, assetKey] = url.split(CREATIVES_S3_BUCKET_PATH);
192
-
193
- let newUrl = `${CREATIVES_CDN_BASE_URL}`;
194
-
195
- let applicableTransformations;
196
223
 
224
+ //Skip trasformations if transformation properties are not present in channel/subchannel.
197
225
  if (channelSubType) {
198
226
  applicableTransformations =
199
227
  CHANNEL_CONFIGS?.[channelName]?.[channelSubType]?.transformations;
200
228
  } else {
201
229
  applicableTransformations = CHANNEL_CONFIGS?.[channelName]?.transformations;
202
230
  }
231
+
232
+ cdnUrl = `${CREATIVES_CDN_BASE_URL}`;
203
233
 
204
234
  if (!isEmpty(applicableTransformations) && !skipTransformations) {
235
+ cdnUrl += `/${CREATIVES_CDN_TRANSFORMATION_URL_SUFFIX}/`;
205
236
 
206
- newUrl += `/${CREATIVES_CDN_TRANSFORMATION_URL_SUFFIX}/`;
207
-
208
- // Object.keys(applicableTransformations)?.forEach((transformationParam) => {
209
237
  forOwn(applicableTransformations, (transformationParamVal, transformationParam)=>{
210
238
  try {
211
239
  switch (transformationParam) {
212
240
  case "height":
213
241
  if (transformationParamVal === SPECIFIED && height) {
214
- newUrl += `${transformationParam}=${height},`;
242
+ cdnUrl += `${transformationParam}=${height},`;
215
243
  } else if(transformationParamVal !== SPECIFIED && isNumber(transformationParamVal)) {
216
- newUrl += `${transformationParam}=${transformationParamVal},`;
244
+ cdnUrl += `${transformationParam}=${transformationParamVal},`;
217
245
  }
218
246
  break;
219
247
  case "width":
220
248
  if (transformationParamVal === SPECIFIED && width) {
221
- newUrl += `${transformationParam}=${width},`;
249
+ cdnUrl += `${transformationParam}=${width},`;
222
250
  } else if(transformationParamVal !== SPECIFIED && isNumber(transformationParamVal)) {
223
- newUrl += `${transformationParam}=${transformationParamVal},`;
251
+ cdnUrl += `${transformationParam}=${transformationParamVal},`;
224
252
  }
225
253
  break;
226
254
  case "format":
227
255
  if(transformationParamVal){
228
- newUrl += `${transformationParam}=${transformationParamVal},`;
256
+ cdnUrl += `${transformationParam}=${transformationParamVal},`;
229
257
  }
230
258
  break;
231
259
  case "quality":
@@ -234,12 +262,12 @@ export const getCdnUrl = ({
234
262
  emailOverrideQuality &&
235
263
  typeof emailOverrideQuality === "number"
236
264
  ) {
237
- newUrl += `${transformationParam}=${emailOverrideQuality},`;
265
+ cdnUrl += `${transformationParam}=${emailOverrideQuality},`;
238
266
  } else {
239
- newUrl += `${transformationParam}=${QUALITY},`;
267
+ cdnUrl += `${transformationParam}=${QUALITY},`;
240
268
  }
241
269
  } else {
242
- newUrl += `${transformationParam}=100,`;
270
+ cdnUrl += `${transformationParam}=100,`;
243
271
  }
244
272
  break;
245
273
  }
@@ -251,9 +279,8 @@ export const getCdnUrl = ({
251
279
  }
252
280
  })
253
281
  }
254
- newUrl += `/${CREATIVES_S3_BUCKET_PATH}${assetKey}`;
255
- return newUrl;
256
-
282
+ cdnUrl += `/${CREATIVES_S3_BUCKET_PATH}${assetKey}`;
283
+ return cdnUrl;
257
284
  }catch(e){
258
285
  Bugsnag.leaveBreadcrumb("Some exception occurred in getCdnUrl");
259
286
  Bugsnag.notify(e, (event) => {
@@ -389,6 +416,7 @@ export function removeAllCdnLocalStorageItems() {
389
416
  removeLocalStorageItem(CREATIVES_S3_BUCKET_PATH_KEY);
390
417
  removeLocalStorageItem(CREATIVES_CDN_OVERRIDE_DEFAULT_EMAIL_QUALITY_KEY);
391
418
  removeLocalStorageItem(CREATIVES_CDN_OVERRIDE_DEFAULT_EMAIL_QUALITY_MAPPING_KEY);
419
+ removeLocalStorageItem(S3_CDN_MAP_KEY);
392
420
  }catch(e){
393
421
  Bugsnag.leaveBreadcrumb("some error occured while deleting all keys for cdn");
394
422
  Bugsnag.notify(e, (event) => {
@@ -476,6 +504,13 @@ export function saveCdnConfigs(configsResponse) {
476
504
  CREATIVES_CDN_OVERRIDE_DEFAULT_EMAIL_QUALITY_MAPPING_KEY
477
505
  );
478
506
  }
507
+
508
+ if (configsResponse?.s3CdnMap) {
509
+ const strigifiedS3CdnMap = JSON.stringify(configsResponse?.s3CdnMap);
510
+ localStorage.setItem(S3_CDN_MAP_KEY, strigifiedS3CdnMap);
511
+ } else {
512
+ removeLocalStorageItem(S3_CDN_MAP_KEY);
513
+ }
479
514
  } catch (e) {
480
515
  Bugsnag.leaveBreadcrumb("some error while setting localstorage cdn configs");
481
516
  Bugsnag.notify(e, (event) => {
@@ -509,8 +544,8 @@ export function storeS3FileSizeDetails(url, fileSize) {
509
544
  export function getKeyFromS3Url(url) {
510
545
  if (typeof url !== "string") return url;
511
546
 
512
- const bucketPathWithSlash =
513
- getLocalStorageItem(CREATIVES_S3_BUCKET_PATH_KEY) + "/";
547
+ const { CREATIVES_S3_BUCKET_PATH } = getClusterSpecificS3CdnConfigFromUrl(url);
548
+ const bucketPathWithSlash = CREATIVES_S3_BUCKET_PATH + "/";
514
549
  const [, key] = url.split(bucketPathWithSlash);
515
550
  return key;
516
551
  }
@@ -527,22 +562,20 @@ export function getKeyFromS3Url(url) {
527
562
  * 'isCdnUrl' refers that it is cdn url.
528
563
  */
529
564
  export function checkValidUrl(url){
565
+ const { CREATIVES_S3_BUCKET_PATH, CREATIVES_CDN_BASE_URL } = getClusterSpecificS3CdnConfigFromUrl(url);
530
566
 
531
- const CREATIVES_CDN_BASE_URL = getLocalStorageItem(CREATIVES_CDN_BASE_URL_KEY);
532
-
533
- let CREATIVES_S3_BUCKET_PATH = getLocalStorageItem(CREATIVES_S3_BUCKET_PATH_KEY);
534
567
  const regexWithExtension = new RegExp(HTTPS_STR + ANY_STR + CREATIVES_S3_BUCKET_PATH + ANY_STR + ALLOWED_EXTENSIONS_STR)
535
-
568
+
536
569
  //It is S3 url if tests with regex but doesn't contain cdn base url.
537
-
570
+
538
571
  const isValidUrl = regexWithExtension.test(url);
539
572
  const isCdnUrl = url.includes(CREATIVES_CDN_BASE_URL);
540
573
  const isS3Url = isValidUrl && !isCdnUrl;
541
574
 
542
575
  return {
543
576
  isValidUrl,
544
- isCdnUrl,
545
577
  isS3Url,
578
+ isCdnUrl,
546
579
  }
547
580
  }
548
581
 
@@ -15,6 +15,7 @@ beforeEach(() => {
15
15
  CREATIVES_CDN_BASE_URL: "https://storage.crm.n.content-cdn.io",
16
16
  CREATIVES_CDN_QUALITY_CONFIG:
17
17
  '{"EMAIL":75,"RCS":75,"VIBER":75,"WHATSAPP":75,"MOBILE_PUSH":75,"FACEBOOK":75,"LINE":75,"DEFAULT":75}',
18
+ S3_CDN_MAP: '{"crm-nightly-new-fileservice.s3.amazonaws.com":{"cdn_host":"storage.crm.n.content-cdn.io","bucket_path":"intouch_creative_assets"}, "crm-prod-new-fileservice.s3.amazonaws.com": { "cdn_host": "storage.crm.p.content-cdn.io", "bucket_path": "fileservice.p/intouch_creative_assets" }}',
18
19
  };
19
20
  return {
20
21
  getItem: function (key) {
@@ -99,27 +100,27 @@ describe("cdnTransformationTests", () => {
99
100
 
100
101
  it("Should replace s3 url with cdn url for email when bucket name is other than intouch_creatives_assets in case of prod.", () => {
101
102
  localStorage.setItem("CREATIVES_S3_BUCKET_PATH", "fileservice.in/intouch_creative_assets");
102
- const TEST_S3_URL = `https://crm-nightly-new-fileservice.s3.amazonaws.com/fileservice.in/intouch_creative_assets/2c9233ed-0959-4aff-b749-9171b5c8.jpg`;
103
+ const TEST_S3_URL = `https://crm-prod-new-fileservice.s3.amazonaws.com/fileservice.p/intouch_creative_assets/2c9233ed-0959-4aff-b749-9171b5c8.jpg`;
103
104
  const GENERATED_CDN_URL = cdnUtils.getCdnUrl({
104
105
  url: TEST_S3_URL,
105
106
  channelName: "EMAIL",
106
107
  height: 100,
107
108
  width: 200,
108
109
  });
109
- const EXPECTED_CDN_URL = `https://storage.crm.n.content-cdn.io/cdn-cgi/image/width=200,height=100,format=auto,quality=75,/fileservice.in/intouch_creative_assets/2c9233ed-0959-4aff-b749-9171b5c8.jpg`;
110
+ const EXPECTED_CDN_URL = `https://storage.crm.p.content-cdn.io/cdn-cgi/image/width=200,height=100,format=auto,quality=75,/fileservice.p/intouch_creative_assets/2c9233ed-0959-4aff-b749-9171b5c8.jpg`;
110
111
  expect(GENERATED_CDN_URL).toEqual(EXPECTED_CDN_URL);
111
112
  });
112
113
 
113
114
  it("Should replace s3 url with cdn url for email when bucket name is other than intouch_creatives_assets in case of prod. It should remove leading/trailing forward slashes from bucket path", () => {
114
115
  localStorage.setItem("CREATIVES_S3_BUCKET_PATH", "/fileservice.in/intouch_creative_assets/");
115
- const TEST_S3_URL = `https://crm-nightly-new-fileservice.s3.amazonaws.com/fileservice.in/intouch_creative_assets/2c9233ed-0959-4aff-b749-9171b5c8.jpg`;
116
+ const TEST_S3_URL = `https://crm-prod-new-fileservice.s3.amazonaws.com/fileservice.p/intouch_creative_assets/2c9233ed-0959-4aff-b749-9171b5c8.jpg`;
116
117
  const GENERATED_CDN_URL = cdnUtils.getCdnUrl({
117
118
  url: TEST_S3_URL,
118
119
  channelName: "EMAIL",
119
120
  height: 100,
120
121
  width: 200,
121
122
  });
122
- const EXPECTED_CDN_URL = `https://storage.crm.n.content-cdn.io/cdn-cgi/image/width=200,height=100,format=auto,quality=75,/fileservice.in/intouch_creative_assets/2c9233ed-0959-4aff-b749-9171b5c8.jpg`;
123
+ const EXPECTED_CDN_URL = `https://storage.crm.p.content-cdn.io/cdn-cgi/image/width=200,height=100,format=auto,quality=75,/fileservice.p/intouch_creative_assets/2c9233ed-0959-4aff-b749-9171b5c8.jpg`;
123
124
  expect(GENERATED_CDN_URL).toEqual(EXPECTED_CDN_URL);
124
125
  });
125
126