fix: vercel build error and app reset method (#2750)

This commit is contained in:
Piyush Gupta
2024-06-11 13:27:46 +05:30
committed by GitHub
parent 2e64b0d54f
commit 915fe00434
10 changed files with 14798 additions and 17031 deletions

View File

@@ -1,13 +1,12 @@
import { TJsAppConfigInput, TJsTrackProperties } from "@formbricks/types/js";
import { CommandQueue } from "../shared/commandQueue";
import { ErrorHandler } from "../shared/errors";
import { Logger } from "../shared/logger";
import { checkPageUrl } from "../shared/noCodeActions";
import { trackCodeAction } from "./lib/actions";
import { getApi } from "./lib/api";
import { setAttributeInApp } from "./lib/attributes";
import { initialize } from "./lib/initialize";
import { checkPageUrl } from "./lib/noCodeActions";
import { logoutPerson, resetPerson } from "./lib/person";
const logger = Logger.getInstance();

View File

@@ -7,27 +7,27 @@ import {
removeExitIntentListener,
removePageUrlEventListeners,
removeScrollDepthListener,
} from "../../shared/noCodeActions";
} from "../lib/noCodeActions";
import { addExpiryCheckListener, removeExpiryCheckListener } from "./sync";
let areRemoveEventListenersAdded = false;
export const addEventListeners = (): void => {
addExpiryCheckListener();
addPageUrlEventListeners("app");
addClickEventListener("app");
addExitIntentListener("app");
addScrollDepthListener("app");
addPageUrlEventListeners();
addClickEventListener();
addExitIntentListener();
addScrollDepthListener();
};
export const addCleanupEventListeners = (): void => {
if (areRemoveEventListenersAdded) return;
window.addEventListener("beforeunload", () => {
removeExpiryCheckListener();
removePageUrlEventListeners("app");
removeClickEventListener("app");
removeExitIntentListener("app");
removeScrollDepthListener("app");
removePageUrlEventListeners();
removeClickEventListener();
removeExitIntentListener();
removeScrollDepthListener();
});
areRemoveEventListenersAdded = true;
};
@@ -36,19 +36,19 @@ export const removeCleanupEventListeners = (): void => {
if (!areRemoveEventListenersAdded) return;
window.removeEventListener("beforeunload", () => {
removeExpiryCheckListener();
removePageUrlEventListeners("app");
removeClickEventListener("app");
removeExitIntentListener("app");
removeScrollDepthListener("app");
removePageUrlEventListeners();
removeClickEventListener();
removeExitIntentListener();
removeScrollDepthListener();
});
areRemoveEventListenersAdded = false;
};
export const removeAllEventListeners = (): void => {
removeExpiryCheckListener();
removePageUrlEventListeners("app");
removeClickEventListener("app");
removeExitIntentListener("app");
removeScrollDepthListener("app");
removePageUrlEventListeners();
removeClickEventListener();
removeExitIntentListener();
removeScrollDepthListener();
removeCleanupEventListeners();
};

View File

@@ -1,6 +1,5 @@
import { TAttributes } from "@formbricks/types/attributes";
import type { TJSAppConfig, TJsAppConfigInput } from "@formbricks/types/js";
import {
ErrorHandler,
MissingFieldError,
@@ -13,12 +12,12 @@ import {
wrapThrows,
} from "../../shared/errors";
import { Logger } from "../../shared/logger";
import { checkPageUrl } from "../../shared/noCodeActions";
import { getIsDebug } from "../../shared/utils";
import { trackNoCodeAction } from "./actions";
import { updateAttributes } from "./attributes";
import { AppConfig, IN_APP_LOCAL_STORAGE_KEY } from "./config";
import { addCleanupEventListeners, addEventListeners, removeAllEventListeners } from "./eventListeners";
import { checkPageUrl } from "./noCodeActions";
import { sync } from "./sync";
import { addWidgetContainer, removeWidgetContainer, setIsSurveyRunning } from "./widget";
@@ -186,7 +185,7 @@ export const initialize = async (
// check page url if initialized after page load
checkPageUrl("app");
checkPageUrl();
return okVoid();
};

View File

@@ -0,0 +1,188 @@
import type { TActionClass } from "@formbricks/types/actionClasses";
import { ErrorHandler, NetworkError, Result, err, match, okVoid } from "../../shared/errors";
import { Logger } from "../../shared/logger";
import { evaluateNoCodeConfigClick, handleUrlFilters } from "../../shared/utils";
import { trackNoCodeAction } from "./actions";
import { AppConfig } from "./config";
const inAppConfig = AppConfig.getInstance();
const logger = Logger.getInstance();
const errorHandler = ErrorHandler.getInstance();
// Event types for various listeners
const events = ["hashchange", "popstate", "pushstate", "replacestate", "load"];
// Page URL Event Handlers
let arePageUrlEventListenersAdded = false;
export const checkPageUrl = async (): Promise<Result<void, NetworkError>> => {
logger.debug(`Checking page url: ${window.location.href}`);
const { state } = inAppConfig.get();
const { actionClasses = [] } = state ?? {};
const noCodePageViewActionClasses = actionClasses.filter(
(action) => action.type === "noCode" && action.noCodeConfig?.type === "pageView"
);
for (const event of noCodePageViewActionClasses) {
const urlFilters = event.noCodeConfig?.urlFilters ?? [];
const isValidUrl = handleUrlFilters(urlFilters);
if (!isValidUrl) continue;
const trackResult = await trackNoCodeAction(event.name);
if (trackResult.ok !== true) return err(trackResult.error);
}
return okVoid();
};
const checkPageUrlWrapper = () => checkPageUrl();
export const addPageUrlEventListeners = (): void => {
if (typeof window === "undefined" || arePageUrlEventListenersAdded) return;
events.forEach((event) => window.addEventListener(event, checkPageUrlWrapper));
arePageUrlEventListenersAdded = true;
};
export const removePageUrlEventListeners = (): void => {
if (typeof window === "undefined" || !arePageUrlEventListenersAdded) return;
events.forEach((event) => window.removeEventListener(event, checkPageUrlWrapper));
arePageUrlEventListenersAdded = false;
};
// Click Event Handlers
let isClickEventListenerAdded = false;
const checkClickMatch = (event: MouseEvent) => {
const { state } = inAppConfig.get();
if (!state) return;
const { actionClasses = [] } = state;
const noCodeClickActionClasses = actionClasses.filter(
(action) => action.type === "noCode" && action.noCodeConfig?.type === "click"
);
const targetElement = event.target as HTMLElement;
noCodeClickActionClasses.forEach((action: TActionClass) => {
if (evaluateNoCodeConfigClick(targetElement, action)) {
trackNoCodeAction(action.name).then((res) => {
match(
res,
(_value: unknown) => {},
(err: any) => errorHandler.handle(err)
);
});
}
});
};
const checkClickMatchWrapper = (e: MouseEvent) => checkClickMatch(e);
export const addClickEventListener = (): void => {
if (typeof window === "undefined" || isClickEventListenerAdded) return;
document.addEventListener("click", checkClickMatchWrapper);
isClickEventListenerAdded = true;
};
export const removeClickEventListener = (): void => {
if (!isClickEventListenerAdded) return;
document.removeEventListener("click", checkClickMatchWrapper);
isClickEventListenerAdded = false;
};
// Exit Intent Handlers
let isExitIntentListenerAdded = false;
const checkExitIntent = async (e: MouseEvent) => {
const { state } = inAppConfig.get();
const { actionClasses = [] } = state ?? {};
const noCodeExitIntentActionClasses = actionClasses.filter(
(action) => action.type === "noCode" && action.noCodeConfig?.type === "exitIntent"
);
if (e.clientY <= 0 && noCodeExitIntentActionClasses.length > 0) {
for (const event of noCodeExitIntentActionClasses) {
const urlFilters = event.noCodeConfig?.urlFilters ?? [];
const isValidUrl = handleUrlFilters(urlFilters);
if (!isValidUrl) continue;
const trackResult = await trackNoCodeAction(event.name);
if (trackResult.ok !== true) return err(trackResult.error);
}
}
};
const checkExitIntentWrapper = (e: MouseEvent) => checkExitIntent(e);
export const addExitIntentListener = (): void => {
if (typeof document !== "undefined" && !isExitIntentListenerAdded) {
document.querySelector("body")!.addEventListener("mouseleave", checkExitIntentWrapper);
isExitIntentListenerAdded = true;
}
};
export const removeExitIntentListener = (): void => {
if (isExitIntentListenerAdded) {
document.removeEventListener("mouseleave", checkExitIntentWrapper);
isExitIntentListenerAdded = false;
}
};
// Scroll Depth Handlers
let scrollDepthListenerAdded = false;
let scrollDepthTriggered = false;
const checkScrollDepth = async () => {
const scrollPosition = window.scrollY;
const windowSize = window.innerHeight;
const bodyHeight = document.documentElement.scrollHeight;
if (scrollPosition === 0) {
scrollDepthTriggered = false;
}
if (!scrollDepthTriggered && scrollPosition / (bodyHeight - windowSize) >= 0.5) {
scrollDepthTriggered = true;
const { state } = inAppConfig.get();
const { actionClasses = [] } = state ?? {};
const noCodefiftyPercentScrollActionClasses = actionClasses.filter(
(action) => action.type === "noCode" && action.noCodeConfig?.type === "fiftyPercentScroll"
);
for (const event of noCodefiftyPercentScrollActionClasses) {
const urlFilters = event.noCodeConfig?.urlFilters ?? [];
const isValidUrl = handleUrlFilters(urlFilters);
if (!isValidUrl) continue;
const trackResult = await trackNoCodeAction(event.name);
if (trackResult.ok !== true) return err(trackResult.error);
}
}
return okVoid();
};
const checkScrollDepthWrapper = () => checkScrollDepth();
export const addScrollDepthListener = (): void => {
if (typeof window !== "undefined" && !scrollDepthListenerAdded) {
window.addEventListener("load", () => {
window.addEventListener("scroll", checkScrollDepthWrapper);
});
scrollDepthListenerAdded = true;
}
};
export const removeScrollDepthListener = (): void => {
if (scrollDepthListenerAdded) {
window.removeEventListener("scroll", checkScrollDepthWrapper);
scrollDepthListenerAdded = false;
}
};

View File

@@ -1,14 +1,13 @@
import { TJsTrackProperties, TJsWebsiteConfigInput } from "@formbricks/types/js";
// Shared imports
import { CommandQueue } from "../shared/commandQueue";
import { ErrorHandler } from "../shared/errors";
import { Logger } from "../shared/logger";
import { checkPageUrl } from "../shared/noCodeActions";
// Website package specific imports
import { trackCodeAction } from "./lib/actions";
import { resetConfig } from "./lib/common";
import { initialize } from "./lib/initialize";
import { checkPageUrl } from "./lib/noCodeActions";
const logger = Logger.getInstance();

View File

@@ -7,27 +7,27 @@ import {
removeExitIntentListener,
removePageUrlEventListeners,
removeScrollDepthListener,
} from "../../shared/noCodeActions";
} from "../lib/noCodeActions";
import { addExpiryCheckListener, removeExpiryCheckListener } from "./sync";
let areRemoveEventListenersAdded = false;
export const addEventListeners = (): void => {
addExpiryCheckListener();
addPageUrlEventListeners("website");
addClickEventListener("website");
addExitIntentListener("website");
addScrollDepthListener("website");
addPageUrlEventListeners();
addClickEventListener();
addExitIntentListener();
addScrollDepthListener();
};
export const addCleanupEventListeners = (): void => {
if (areRemoveEventListenersAdded) return;
window.addEventListener("beforeunload", () => {
removeExpiryCheckListener();
removePageUrlEventListeners("website");
removeClickEventListener("website");
removeExitIntentListener("website");
removeScrollDepthListener("website");
removePageUrlEventListeners();
removeClickEventListener();
removeExitIntentListener();
removeScrollDepthListener();
});
areRemoveEventListenersAdded = true;
};
@@ -36,19 +36,19 @@ export const removeCleanupEventListeners = (): void => {
if (!areRemoveEventListenersAdded) return;
window.removeEventListener("beforeunload", () => {
removeExpiryCheckListener();
removePageUrlEventListeners("website");
removeClickEventListener("website");
removeExitIntentListener("website");
removeScrollDepthListener("website");
removePageUrlEventListeners();
removeClickEventListener();
removeExitIntentListener();
removeScrollDepthListener();
});
areRemoveEventListenersAdded = false;
};
export const removeAllEventListeners = (): void => {
removeExpiryCheckListener();
removePageUrlEventListeners("website");
removeClickEventListener("website");
removeExitIntentListener("website");
removeScrollDepthListener("website");
removePageUrlEventListeners();
removeClickEventListener();
removeExitIntentListener();
removeScrollDepthListener();
removeCleanupEventListeners();
};

View File

@@ -1,5 +1,4 @@
import type { TJSAppConfig, TJsWebsiteConfig, TJsWebsiteConfigInput } from "@formbricks/types/js";
import {
ErrorHandler,
MissingFieldError,
@@ -12,11 +11,11 @@ import {
wrapThrows,
} from "../../shared/errors";
import { Logger } from "../../shared/logger";
import { checkPageUrl } from "../../shared/noCodeActions";
import { getIsDebug } from "../../shared/utils";
import { trackNoCodeAction } from "./actions";
import { WEBSITE_LOCAL_STORAGE_KEY, WebsiteConfig } from "./config";
import { addCleanupEventListeners, addEventListeners, removeAllEventListeners } from "./eventListeners";
import { checkPageUrl } from "./noCodeActions";
import { sync } from "./sync";
import { addWidgetContainer, removeWidgetContainer, setIsSurveyRunning } from "./widget";
@@ -159,7 +158,7 @@ export const initialize = async (
// check page url if initialized after page load
checkPageUrl("website");
checkPageUrl();
return okVoid();
};

View File

@@ -1,50 +1,23 @@
import type { TActionClass } from "@formbricks/types/actionClasses";
import { TJsPackageType } from "@formbricks/types/js";
import { ErrorHandler, NetworkError, Result, err, match, okVoid } from "../../shared/errors";
import { Logger } from "../../shared/logger";
import { evaluateNoCodeConfigClick, handleUrlFilters } from "../../shared/utils";
import { trackNoCodeAction } from "./actions";
import { WebsiteConfig } from "./config";
import { trackNoCodeAction as trackNoCodeAppAction } from "../app/lib/actions";
import { AppConfig } from "../app/lib/config";
import { trackNoCodeAction as trackNoCodeWebsiteAction } from "../website/lib/actions";
import { WebsiteConfig } from "../website/lib/config";
import { ErrorHandler, NetworkError, Result, err, match, okVoid } from "./errors";
import { Logger } from "./logger";
import { evaluateNoCodeConfigClick, handleUrlFilters } from "./utils";
const inAppConfig = AppConfig.getInstance();
const websiteConfig = WebsiteConfig.getInstance();
const logger = Logger.getInstance();
const errorHandler = ErrorHandler.getInstance();
const getConfig = (packageType: TJsPackageType): WebsiteConfig | AppConfig => {
switch (packageType) {
case "website":
return websiteConfig;
case "app":
return inAppConfig;
}
};
const getNoCodeActionTracker = (packageType: TJsPackageType) => {
switch (packageType) {
case "website":
return trackNoCodeWebsiteAction;
case "app":
return trackNoCodeAppAction;
}
};
// Event types for various listeners
const events = ["hashchange", "popstate", "pushstate", "replacestate", "load"];
// Page URL Event Handlers
let arePageUrlEventListenersAdded = false;
export const checkPageUrl = async (packageType: TJsPackageType): Promise<Result<void, NetworkError>> => {
export const checkPageUrl = async (): Promise<Result<void, NetworkError>> => {
logger.debug(`Checking page url: ${window.location.href}`);
const config = getConfig(packageType);
const { state } = config.get();
const { state } = websiteConfig.get();
const { actionClasses = [] } = state ?? {};
const noCodePageViewActionClasses = actionClasses.filter(
@@ -57,7 +30,6 @@ export const checkPageUrl = async (packageType: TJsPackageType): Promise<Result<
if (!isValidUrl) continue;
const trackNoCodeAction = getNoCodeActionTracker(packageType);
const trackResult = await trackNoCodeAction(event.name);
if (trackResult.ok !== true) return err(trackResult.error);
}
@@ -65,26 +37,25 @@ export const checkPageUrl = async (packageType: TJsPackageType): Promise<Result<
return okVoid();
};
const checkPageUrlWrapper = (packageType: TJsPackageType) => checkPageUrl(packageType);
const checkPageUrlWrapper = () => checkPageUrl();
export const addPageUrlEventListeners = (packageType: TJsPackageType): void => {
export const addPageUrlEventListeners = (): void => {
if (typeof window === "undefined" || arePageUrlEventListenersAdded) return;
events.forEach((event) => window.addEventListener(event, () => checkPageUrlWrapper(packageType)));
events.forEach((event) => window.addEventListener(event, checkPageUrlWrapper));
arePageUrlEventListenersAdded = true;
};
export const removePageUrlEventListeners = (packageType: TJsPackageType): void => {
export const removePageUrlEventListeners = (): void => {
if (typeof window === "undefined" || !arePageUrlEventListenersAdded) return;
events.forEach((event) => window.removeEventListener(event, () => checkPageUrlWrapper(packageType)));
events.forEach((event) => window.removeEventListener(event, checkPageUrlWrapper));
arePageUrlEventListenersAdded = false;
};
// Click Event Handlers
let isClickEventListenerAdded = false;
const checkClickMatch = (event: MouseEvent, packageType: TJsPackageType) => {
const config = getConfig(packageType);
const { state } = config.get();
const checkClickMatch = (event: MouseEvent) => {
const { state } = websiteConfig.get();
if (!state) return;
const { actionClasses = [] } = state;
@@ -94,8 +65,6 @@ const checkClickMatch = (event: MouseEvent, packageType: TJsPackageType) => {
const targetElement = event.target as HTMLElement;
const trackNoCodeAction = getNoCodeActionTracker(packageType);
noCodeClickActionClasses.forEach((action: TActionClass) => {
if (evaluateNoCodeConfigClick(targetElement, action)) {
trackNoCodeAction(action.name).then((res) => {
@@ -109,31 +78,27 @@ const checkClickMatch = (event: MouseEvent, packageType: TJsPackageType) => {
});
};
const checkClickMatchWrapper = (e: MouseEvent, packageType: TJsPackageType) =>
checkClickMatch(e, packageType);
const checkClickMatchWrapper = (e: MouseEvent) => checkClickMatch(e);
export const addClickEventListener = (packageType: TJsPackageType): void => {
export const addClickEventListener = (): void => {
if (typeof window === "undefined" || isClickEventListenerAdded) return;
document.addEventListener("click", (e) => checkClickMatchWrapper(e, packageType));
document.addEventListener("click", checkClickMatchWrapper);
isClickEventListenerAdded = true;
};
export const removeClickEventListener = (packageType: TJsPackageType): void => {
export const removeClickEventListener = (): void => {
if (!isClickEventListenerAdded) return;
document.removeEventListener("click", (e) => checkClickMatchWrapper(e, packageType));
document.removeEventListener("click", checkClickMatchWrapper);
isClickEventListenerAdded = false;
};
// Exit Intent Handlers
let isExitIntentListenerAdded = false;
const checkExitIntent = async (e: MouseEvent, packageType: TJsPackageType) => {
const config = getConfig(packageType);
const { state } = config.get();
const checkExitIntent = async (e: MouseEvent) => {
const { state } = websiteConfig.get();
const { actionClasses = [] } = state ?? {};
const trackNoCodeAction = getNoCodeActionTracker(packageType);
const noCodeExitIntentActionClasses = actionClasses.filter(
(action) => action.type === "noCode" && action.noCodeConfig?.type === "exitIntent"
);
@@ -151,21 +116,18 @@ const checkExitIntent = async (e: MouseEvent, packageType: TJsPackageType) => {
}
};
const checkExitIntentWrapper = (e: MouseEvent, packageType: TJsPackageType) =>
checkExitIntent(e, packageType);
const checkExitIntentWrapper = (e: MouseEvent) => checkExitIntent(e);
export const addExitIntentListener = (packageType: TJsPackageType): void => {
export const addExitIntentListener = (): void => {
if (typeof document !== "undefined" && !isExitIntentListenerAdded) {
document
.querySelector("body")!
.addEventListener("mouseleave", (e) => checkExitIntentWrapper(e, packageType));
document.querySelector("body")!.addEventListener("mouseleave", checkExitIntentWrapper);
isExitIntentListenerAdded = true;
}
};
export const removeExitIntentListener = (packageType: TJsPackageType): void => {
export const removeExitIntentListener = (): void => {
if (isExitIntentListenerAdded) {
document.removeEventListener("mouseleave", (e) => checkExitIntentWrapper(e, packageType));
document.removeEventListener("mouseleave", checkExitIntentWrapper);
isExitIntentListenerAdded = false;
}
};
@@ -174,7 +136,7 @@ export const removeExitIntentListener = (packageType: TJsPackageType): void => {
let scrollDepthListenerAdded = false;
let scrollDepthTriggered = false;
const checkScrollDepth = async (packageType: TJsPackageType) => {
const checkScrollDepth = async () => {
const scrollPosition = window.scrollY;
const windowSize = window.innerHeight;
const bodyHeight = document.documentElement.scrollHeight;
@@ -186,13 +148,9 @@ const checkScrollDepth = async (packageType: TJsPackageType) => {
if (!scrollDepthTriggered && scrollPosition / (bodyHeight - windowSize) >= 0.5) {
scrollDepthTriggered = true;
const config = getConfig(packageType);
const { state } = config.get();
const { state } = websiteConfig.get();
const { actionClasses = [] } = state ?? {};
const trackNoCodeAction = getNoCodeActionTracker(packageType);
const noCodefiftyPercentScrollActionClasses = actionClasses.filter(
(action) => action.type === "noCode" && action.noCodeConfig?.type === "fiftyPercentScroll"
);
@@ -211,20 +169,20 @@ const checkScrollDepth = async (packageType: TJsPackageType) => {
return okVoid();
};
const checkScrollDepthWrapper = (packageType: TJsPackageType) => checkScrollDepth(packageType);
const checkScrollDepthWrapper = () => checkScrollDepth();
export const addScrollDepthListener = (packageType: TJsPackageType): void => {
export const addScrollDepthListener = (): void => {
if (typeof window !== "undefined" && !scrollDepthListenerAdded) {
window.addEventListener("load", () => {
window.addEventListener("scroll", () => checkScrollDepthWrapper(packageType));
window.addEventListener("scroll", checkScrollDepthWrapper);
});
scrollDepthListenerAdded = true;
}
};
export const removeScrollDepthListener = (packageType: TJsPackageType): void => {
export const removeScrollDepthListener = (): void => {
if (scrollDepthListenerAdded) {
window.removeEventListener("scroll", () => checkScrollDepthWrapper(packageType));
window.removeEventListener("scroll", checkScrollDepthWrapper);
scrollDepthListenerAdded = false;
}
};

View File

@@ -1,5 +1,3 @@
"use client";
import { cn } from "@/lib/utils";
import { useEffect, useMemo, useRef, useState } from "preact/hooks";
import { TProductStyling } from "@formbricks/types/product";

31447
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff