From 406ec885154142b6d1d7d5d7153e6a9e396f80b6 Mon Sep 17 00:00:00 2001 From: Anshuman Pandey <54475686+pandeymangg@users.noreply.github.com> Date: Tue, 1 Apr 2025 10:50:30 +0530 Subject: [PATCH] fix: adding back hidden fields for backwards compatibility (#5163) --- packages/js-core/src/index.ts | 12 ++++-- .../js-core/src/lib/common/command-queue.ts | 12 +++--- packages/js-core/src/lib/common/utils.ts | 39 ++++++++++++++++++- packages/js-core/src/lib/survey/action.ts | 16 ++++++-- .../src/lib/survey/tests/action.test.ts | 5 ++- .../src/lib/survey/tests/widget.test.ts | 1 + packages/js-core/src/lib/survey/widget.ts | 22 +++++++++-- packages/js-core/src/types/survey.ts | 4 ++ packages/js/package.json | 2 +- packages/js/src/index.ts | 9 +++-- 10 files changed, 99 insertions(+), 23 deletions(-) diff --git a/packages/js-core/src/index.ts b/packages/js-core/src/index.ts index 5d4870810e..e3a17b247f 100644 --- a/packages/js-core/src/index.ts +++ b/packages/js-core/src/index.ts @@ -7,6 +7,7 @@ import { checkPageUrl } from "@/lib/survey/no-code-action"; import * as Attribute from "@/lib/user/attribute"; import * as User from "@/lib/user/user"; import { type TConfigInput, type TLegacyConfigInput } from "@/types/config"; +import { type TTrackProperties } from "@/types/survey"; const queue = new CommandQueue(); @@ -67,8 +68,12 @@ const logout = async (): Promise => { await queue.wait(); }; -const track = async (code: string): Promise => { - queue.add(Action.trackCodeAction, true, code); +/** + * @param code - The code of the action to track + * @param properties - Optional properties to set, like the hidden fields (deprecated, hidden fields will be removed in a future version) + */ +const track = async (code: string, properties?: TTrackProperties): Promise => { + queue.add(Action.trackCodeAction, true, code, properties); await queue.wait(); }; @@ -91,5 +96,6 @@ const formbricks = { registerRouteChange, }; -export type TFormbricks = typeof formbricks; +type TFormbricks = typeof formbricks; +export type { TFormbricks }; export default formbricks; diff --git a/packages/js-core/src/lib/common/command-queue.ts b/packages/js-core/src/lib/common/command-queue.ts index effa4c30fe..f1dcd2f8fb 100644 --- a/packages/js-core/src/lib/common/command-queue.ts +++ b/packages/js-core/src/lib/common/command-queue.ts @@ -4,9 +4,13 @@ import { checkSetup } from "@/lib/common/setup"; import { wrapThrowsAsync } from "@/lib/common/utils"; import type { Result } from "@/types/error"; +export type TCommand = ( + ...args: any[] +) => Promise> | Result | Promise; + export class CommandQueue { private queue: { - command: (...args: any[]) => Promise> | Result | Promise; + command: TCommand; checkSetup: boolean; commandArgs: any[]; }[] = []; @@ -14,11 +18,7 @@ export class CommandQueue { private resolvePromise: (() => void) | null = null; private commandPromise: Promise | null = null; - public add( - command: (...args: A[]) => Promise> | Result | Promise, - shouldCheckSetup = true, - ...args: A[] - ): void { + public add(command: TCommand, shouldCheckSetup = true, ...args: A[]): void { this.queue.push({ command, checkSetup: shouldCheckSetup, commandArgs: args }); if (!this.running) { diff --git a/packages/js-core/src/lib/common/utils.ts b/packages/js-core/src/lib/common/utils.ts index aa4dba8122..8da1aebf33 100644 --- a/packages/js-core/src/lib/common/utils.ts +++ b/packages/js-core/src/lib/common/utils.ts @@ -1,3 +1,4 @@ +import { Logger } from "@/lib/common/logger"; import type { TEnvironmentState, TEnvironmentStateActionClass, @@ -8,7 +9,11 @@ import type { TUserState, } from "@/types/config"; import type { Result } from "@/types/error"; -import { type TActionClassNoCodeConfig, type TActionClassPageUrlRule } from "@/types/survey"; +import { + type TActionClassNoCodeConfig, + type TActionClassPageUrlRule, + type TTrackProperties, +} from "@/types/survey"; // Helper function to calculate difference in days between two dates export const diffInDays = (date1: Date, date2: Date): number => { @@ -225,6 +230,38 @@ export const handleUrlFilters = (urlFilters: TActionClassNoCodeConfig["urlFilter return isMatch; }; +export const handleHiddenFields = ( + hiddenFieldsConfig: TEnvironmentStateSurvey["hiddenFields"], + hiddenFields?: TTrackProperties["hiddenFields"] +): TTrackProperties["hiddenFields"] => { + const logger = Logger.getInstance(); + const { enabled: enabledHiddenFields, fieldIds: surveyHiddenFieldIds } = hiddenFieldsConfig; + + let hiddenFieldsObject: TTrackProperties["hiddenFields"] = {}; + + if (!enabledHiddenFields) { + logger.error("Hidden fields are not enabled for this survey"); + } else if (surveyHiddenFieldIds && hiddenFields) { + const unknownHiddenFields: string[] = []; + hiddenFieldsObject = Object.keys(hiddenFields).reduce((acc, key) => { + if (surveyHiddenFieldIds.includes(key)) { + acc[key] = hiddenFields[key]; + } else { + unknownHiddenFields.push(key); + } + return acc; + }, {}); + + if (unknownHiddenFields.length > 0) { + logger.error( + `Unknown hidden fields: ${unknownHiddenFields.join(", ")}. Please add them to the survey hidden fields.` + ); + } + } + + return hiddenFieldsObject; +}; + export const evaluateNoCodeConfigClick = ( targetElement: HTMLElement, action: TEnvironmentStateActionClass diff --git a/packages/js-core/src/lib/survey/action.ts b/packages/js-core/src/lib/survey/action.ts index 1d1535303a..9eaf3979d5 100644 --- a/packages/js-core/src/lib/survey/action.ts +++ b/packages/js-core/src/lib/survey/action.ts @@ -2,14 +2,20 @@ import { Config } from "@/lib/common/config"; import { Logger } from "@/lib/common/logger"; import { triggerSurvey } from "@/lib/survey/widget"; import { type InvalidCodeError, type NetworkError, type Result, err, okVoid } from "@/types/error"; +import { type TTrackProperties } from "@/types/survey"; /** * Tracks an action name and triggers associated surveys * @param name - The name of the action to track * @param alias - Optional alias for the action name + * @param properties - Optional properties to set, like the hidden fields (deprecated, hidden fields will be removed in a future version) * @returns Result indicating success or network error */ -export const trackAction = async (name: string, alias?: string): Promise> => { +export const trackAction = async ( + name: string, + alias?: string, + properties?: TTrackProperties +): Promise> => { const logger = Logger.getInstance(); const appConfig = Config.getInstance(); @@ -24,7 +30,7 @@ export const trackAction = async (name: string, alias?: string): Promise