From ab70e02594fa055c4a53feed5e6bc7110e780c3f Mon Sep 17 00:00:00 2001 From: Gauravudia Date: Tue, 27 Feb 2024 12:09:00 +0530 Subject: [PATCH] refactor: replace handlebar with regex --- package-lock.json | 11 +++- package.json | 1 - .../analytics-js-integrations/.size-limit.js | 2 +- .../integrations/Mixpanel/util.test.js | 56 +++++++------------ .../src/integrations/Mixpanel/util.js | 28 +++++++--- 5 files changed, 48 insertions(+), 50 deletions(-) diff --git a/package-lock.json b/package-lock.json index 429e617fcf..fef9fdf0f4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -34,7 +34,6 @@ "crypto-js": "4.2.0", "deep-object-diff": "1.1.9", "get-value": "3.0.1", - "handlebars": "^4.7.8", "is": "3.3.0", "lodash.get": "4.4.2", "lodash.isempty": "4.4.0", @@ -13255,6 +13254,7 @@ "version": "4.7.8", "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz", "integrity": "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==", + "dev": true, "dependencies": { "minimist": "^1.2.5", "neo-async": "^2.6.2", @@ -18542,6 +18542,7 @@ "version": "1.2.7", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.7.tgz", "integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==", + "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -19032,7 +19033,8 @@ "node_modules/neo-async": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==" + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true }, "node_modules/node-fetch": { "version": "2.7.0", @@ -23526,6 +23528,7 @@ "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, "engines": { "node": ">=0.10.0" } @@ -24787,6 +24790,7 @@ "version": "3.17.4", "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.17.4.tgz", "integrity": "sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==", + "dev": true, "optional": true, "bin": { "uglifyjs": "bin/uglifyjs" @@ -25403,7 +25407,8 @@ "node_modules/wordwrap": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==" + "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", + "dev": true }, "node_modules/wrap-ansi": { "version": "7.0.0", diff --git a/package.json b/package.json index d26857ec0e..f08923e3fa 100644 --- a/package.json +++ b/package.json @@ -85,7 +85,6 @@ "crypto-js": "4.2.0", "deep-object-diff": "1.1.9", "get-value": "3.0.1", - "handlebars": "^4.7.8", "is": "3.3.0", "lodash.get": "4.4.2", "lodash.isempty": "4.4.0", diff --git a/packages/analytics-js-integrations/.size-limit.js b/packages/analytics-js-integrations/.size-limit.js index e62ba9dbb3..6a99214399 100644 --- a/packages/analytics-js-integrations/.size-limit.js +++ b/packages/analytics-js-integrations/.size-limit.js @@ -6,6 +6,6 @@ module.exports = [ { name: 'All Integrations (legacy build) - CDN', path: 'dist/cdn/legacy/js-integrations/*.min.js', - limit: '123 KiB', + limit: '105 KiB', }, ]; diff --git a/packages/analytics-js-integrations/__tests__/integrations/Mixpanel/util.test.js b/packages/analytics-js-integrations/__tests__/integrations/Mixpanel/util.test.js index 350ae2ba6a..8b64372ec4 100644 --- a/packages/analytics-js-integrations/__tests__/integrations/Mixpanel/util.test.js +++ b/packages/analytics-js-integrations/__tests__/integrations/Mixpanel/util.test.js @@ -457,58 +457,42 @@ describe('formatTraits', () => { }); describe('generatePageCustomEventName', () => { - it('should generate a custom event name when userDefinedEventTemplate contains handlebars and message object is provided', () => { - const message = { name: 'Home' }; - const userDefinedEventTemplate = 'Viewed a {{ name }} page'; - const expected = 'Viewed a Home page'; + it('should generate a custom event name when userDefinedEventTemplate contains event template and message object is provided', () => { + const message = { name: 'Doc', properties: { category: 'Integration' } }; + const userDefinedEventTemplate = 'Viewed {{ category }} {{ name }} page'; + const expected = 'Viewed Integration Doc page'; const result = generatePageCustomEventName(message, userDefinedEventTemplate); expect(result).toBe(expected); }); - it('should generate a default `Loaded a Page` event name when userDefinedEventTemplate is undefined/null/empty', () => { - const message = { name: 'Home' }; - const userDefinedEventTemplate = undefined; - const expected = 'Loaded a Page'; - const result = generatePageCustomEventName(message, userDefinedEventTemplate); - expect(result).toBe(expected); - }); - - it('should return the userDefinedEventTemplate when it does not contain handlebars', () => { - const message = { name: 'Home' }; - const userDefinedEventTemplate = 'Viewed a Home page'; - const expected = 'Viewed a Home page'; + it('should generate a custom event name when userDefinedEventTemplate contains event template and category or name is missing in message object', () => { + const message = { name: 'Doc' }; + const userDefinedEventTemplate = 'Viewed {{ category }} {{ name }} page'; + const expected = 'Viewed Doc page'; const result = generatePageCustomEventName(message, userDefinedEventTemplate); expect(result).toBe(expected); }); - it('should return a event name when message object is not provided', () => { - const message = undefined; - const userDefinedEventTemplate = 'Viewed a {{ path }} page'; - const expected = 'Viewed a page'; + it('should generate a custom event name when userDefinedEventTemplate contains only category or name placeholder and message object is provided', () => { + const message = { name: 'Doc', properties: { category: 'Integration' } }; + const userDefinedEventTemplate = 'Viewed {{ name }} page'; + const expected = 'Viewed Doc page'; const result = generatePageCustomEventName(message, userDefinedEventTemplate); expect(result).toBe(expected); }); - it('should return a custom event name when userDefinedEventTemplate contains handlebars and message object is nested', () => { - const message = { a: { b: 'abc' } }; - const userDefinedEventTemplate = 'Viewed a {{ a.b }} page'; - const expected = 'Viewed a abc page'; - const result = generatePageCustomEventName(message, userDefinedEventTemplate); - expect(result).toBe(expected); - }); - - it('should return a default `Loaded a Page` event name when userDefinedEventTemplate contains invalid handlebars and message object is provided', () => { - const message = { name: 'Home' }; - const userDefinedEventTemplate = 'Viewed a {{ name } page'; - const expected = 'Loaded a Page'; + it('should return the userDefinedEventTemplate when it does not contain placeholder {{}}', () => { + const message = { name: 'Index' }; + const userDefinedEventTemplate = 'Viewed a Home page'; + const expected = 'Viewed a Home page'; const result = generatePageCustomEventName(message, userDefinedEventTemplate); expect(result).toBe(expected); }); - it('should return a custom event name when userDefinedEventTemplate contains multiple handlebar and message object is provided', () => { - const message = { name: 'Home', properties: { category: 'Index' } }; - const userDefinedEventTemplate = 'Viewed a {{ properties.category }} {{ name }} page'; - const expected = 'Viewed a Index Home page'; + it('should return a event name when message object is not provided/empty', () => { + const message = {}; + const userDefinedEventTemplate = 'Viewed {{ category }} {{ name }} page'; + const expected = 'Viewed page'; const result = generatePageCustomEventName(message, userDefinedEventTemplate); expect(result).toBe(expected); }); diff --git a/packages/analytics-js-integrations/src/integrations/Mixpanel/util.js b/packages/analytics-js-integrations/src/integrations/Mixpanel/util.js index 109157449d..4226f44c05 100644 --- a/packages/analytics-js-integrations/src/integrations/Mixpanel/util.js +++ b/packages/analytics-js-integrations/src/integrations/Mixpanel/util.js @@ -3,7 +3,6 @@ /* eslint-disable no-prototype-builtins */ import get from 'get-value'; import { DISPLAY_NAME } from '@rudderstack/analytics-js-common/constants/integrations/Mixpanel/constants'; -import Handlebars from 'handlebars'; import Logger from '../../utils/logger'; import { getDefinedTraits, extractCustomFields } from '../../utils/utils'; @@ -241,21 +240,32 @@ const getConsolidatedPageCalls = config => : true; /** - * Generates a custom event name for a page calls. + * Generates a custom event name for a page or screen. * * @param {Object} message - The message object * @param {string} userDefinedEventTemplate - The user-defined event template to be used for generating the event name. + * @throws {ConfigurationError} If the event template is missing. * @returns {string} The generated custom event name. + * @example + * const userDefinedEventTemplate = "Viewed {{ category }} {{ name }} Page"; + * const message = {name: 'Home', properties: {category: 'Index'}}; + * output: "Viewed Index Home Page" */ const generatePageCustomEventName = (message, userDefinedEventTemplate) => { - try { - const eventTemplate = Handlebars.compile(userDefinedEventTemplate); - return eventTemplate(message); - } catch (error) { - logger.error(`Error generating custom event name: ${error.message}`); - // Return a default or empty string as a fallback - return 'Loaded a Page'; + let eventName = userDefinedEventTemplate + .replace('{{ category }}', message.properties?.category || '') + .trim(); + eventName = eventName.replace('{{ name }}', message.name || '').trim(); + // Remove any extra space between placeholders + eventName = eventName.replace(/\s{2,}/g, ' '); + + // Check if any placeholders remain + if (eventName.includes('{{')) { + // Handle the case where either name or category is missing + eventName = eventName.replace(/{{\s*\w+\s*}}/g, ''); } + + return eventName.trim(); }; export {