mirror of
https://github.com/formbricks/formbricks.git
synced 2026-05-03 11:30:50 -05:00
fix: merges the app and website js sdk into @formbricks/js (#3314)
Co-authored-by: Matthias Nannt <mail@matthiasnannt.com>
This commit is contained in:
@@ -7,11 +7,8 @@ export const GET = async (_: NextRequest, { params }: { params: { package: strin
|
||||
const packageRequested = params.package;
|
||||
|
||||
switch (packageRequested) {
|
||||
case "app":
|
||||
path = `../../packages/js-core/dist/app.umd.cjs`;
|
||||
break;
|
||||
case "website":
|
||||
path = `../../packages/js-core/dist/website.umd.cjs`;
|
||||
case "js":
|
||||
path = `../../packages/js-core/dist/index.umd.cjs`;
|
||||
break;
|
||||
case "surveys":
|
||||
path = `../../packages/surveys/dist/index.umd.cjs`;
|
||||
|
||||
+2
-7
@@ -18,7 +18,7 @@ import { productCache } from "@formbricks/lib/product/cache";
|
||||
import { getProductByEnvironmentId } from "@formbricks/lib/product/service";
|
||||
import { surveyCache } from "@formbricks/lib/survey/cache";
|
||||
import { getSurveys } from "@formbricks/lib/survey/service";
|
||||
import { InvalidInputError, ResourceNotFoundError } from "@formbricks/types/errors";
|
||||
import { ResourceNotFoundError } from "@formbricks/types/errors";
|
||||
import { TJsEnvironmentState } from "@formbricks/types/js";
|
||||
|
||||
/**
|
||||
@@ -26,7 +26,6 @@ import { TJsEnvironmentState } from "@formbricks/types/js";
|
||||
* @param environmentId
|
||||
* @returns The environment state
|
||||
* @throws ResourceNotFoundError if the environment or organization does not exist
|
||||
* @throws InvalidInputError if the channel is not "app"
|
||||
*/
|
||||
export const getEnvironmentState = async (
|
||||
environmentId: string
|
||||
@@ -52,10 +51,6 @@ export const getEnvironmentState = async (
|
||||
throw new ResourceNotFoundError("product", null);
|
||||
}
|
||||
|
||||
if (product.config.channel && product.config.channel !== "app") {
|
||||
throw new InvalidInputError("Invalid channel");
|
||||
}
|
||||
|
||||
if (!environment.appSetupCompleted) {
|
||||
await Promise.all([
|
||||
prisma.environment.update({
|
||||
@@ -117,7 +112,7 @@ export const getEnvironmentState = async (
|
||||
revalidateEnvironment,
|
||||
};
|
||||
},
|
||||
[`environmentState-app-${environmentId}`],
|
||||
[`environmentState-${environmentId}`],
|
||||
{
|
||||
...(IS_FORMBRICKS_CLOUD && { revalidate: 24 * 60 * 60 }),
|
||||
tags: [
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
import { getEnvironmentState } from "@/app/api/v1/client/[environmentId]/app/environment/lib/environmentState";
|
||||
import { getEnvironmentState } from "@/app/api/v1/client/[environmentId]/environment/lib/environmentState";
|
||||
import { responses } from "@/app/lib/api/response";
|
||||
import { transformErrorToDetails } from "@/app/lib/api/validator";
|
||||
import { NextRequest } from "next/server";
|
||||
+1
-1
@@ -1,4 +1,3 @@
|
||||
import { getPersonSegmentIds } from "@/app/api/v1/client/[environmentId]/app/people/[userId]/lib/segments";
|
||||
import { prisma } from "@formbricks/database";
|
||||
import { attributeCache } from "@formbricks/lib/attribute/cache";
|
||||
import { getAttributesByUserId } from "@formbricks/lib/attribute/service";
|
||||
@@ -17,6 +16,7 @@ import { getResponsesByUserId } from "@formbricks/lib/response/service";
|
||||
import { segmentCache } from "@formbricks/lib/segment/cache";
|
||||
import { ResourceNotFoundError } from "@formbricks/types/errors";
|
||||
import { TJsPersonState } from "@formbricks/types/js";
|
||||
import { getPersonSegmentIds } from "./segments";
|
||||
|
||||
/**
|
||||
*
|
||||
-126
@@ -1,126 +0,0 @@
|
||||
import { prisma } from "@formbricks/database";
|
||||
import { actionClassCache } from "@formbricks/lib/actionClass/cache";
|
||||
import { getActionClasses } from "@formbricks/lib/actionClass/service";
|
||||
import { cache } from "@formbricks/lib/cache";
|
||||
import { IS_FORMBRICKS_CLOUD } from "@formbricks/lib/constants";
|
||||
import { environmentCache } from "@formbricks/lib/environment/cache";
|
||||
import { getEnvironment } from "@formbricks/lib/environment/service";
|
||||
import { organizationCache } from "@formbricks/lib/organization/cache";
|
||||
import {
|
||||
getMonthlyOrganizationResponseCount,
|
||||
getOrganizationByEnvironmentId,
|
||||
} from "@formbricks/lib/organization/service";
|
||||
import {
|
||||
capturePosthogEnvironmentEvent,
|
||||
sendPlanLimitsReachedEventToPosthogWeekly,
|
||||
} from "@formbricks/lib/posthogServer";
|
||||
import { productCache } from "@formbricks/lib/product/cache";
|
||||
import { getProductByEnvironmentId } from "@formbricks/lib/product/service";
|
||||
import { surveyCache } from "@formbricks/lib/survey/cache";
|
||||
import { getSurveys } from "@formbricks/lib/survey/service";
|
||||
import { InvalidInputError, ResourceNotFoundError } from "@formbricks/types/errors";
|
||||
import { TJsEnvironmentState } from "@formbricks/types/js";
|
||||
|
||||
/**
|
||||
* Get the environment state
|
||||
* @param environmentId
|
||||
* @returns The environment state
|
||||
* @throws ResourceNotFoundError if the organization, environment or product is not found
|
||||
* @throws InvalidInputError if the product channel is not website
|
||||
*/
|
||||
export const getEnvironmentState = async (
|
||||
environmentId: string
|
||||
): Promise<{ state: TJsEnvironmentState["data"]; revalidateEnvironment?: boolean }> =>
|
||||
cache(
|
||||
async () => {
|
||||
let revalidateEnvironment = false;
|
||||
const [environment, organization, product] = await Promise.all([
|
||||
getEnvironment(environmentId),
|
||||
getOrganizationByEnvironmentId(environmentId),
|
||||
getProductByEnvironmentId(environmentId),
|
||||
]);
|
||||
|
||||
if (!environment) {
|
||||
throw new ResourceNotFoundError("environment", environmentId);
|
||||
}
|
||||
|
||||
if (!organization) {
|
||||
throw new ResourceNotFoundError("organization", null);
|
||||
}
|
||||
|
||||
if (!product) {
|
||||
throw new ResourceNotFoundError("product", null);
|
||||
}
|
||||
|
||||
if (product.config.channel && product.config.channel !== "website") {
|
||||
throw new InvalidInputError("Product channel is not website");
|
||||
}
|
||||
|
||||
// check if response limit is reached
|
||||
let isWebsiteSurveyResponseLimitReached = false;
|
||||
if (IS_FORMBRICKS_CLOUD) {
|
||||
const currentResponseCount = await getMonthlyOrganizationResponseCount(organization.id);
|
||||
const monthlyResponseLimit = organization.billing.limits.monthly.responses;
|
||||
|
||||
isWebsiteSurveyResponseLimitReached =
|
||||
monthlyResponseLimit !== null && currentResponseCount >= monthlyResponseLimit;
|
||||
|
||||
if (isWebsiteSurveyResponseLimitReached) {
|
||||
try {
|
||||
await sendPlanLimitsReachedEventToPosthogWeekly(environmentId, {
|
||||
plan: organization.billing.plan,
|
||||
limits: { monthly: { responses: monthlyResponseLimit, miu: null } },
|
||||
});
|
||||
} catch (error) {
|
||||
console.error(`Error sending plan limits reached event to Posthog: ${error}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!environment?.websiteSetupCompleted) {
|
||||
await Promise.all([
|
||||
await prisma.environment.update({
|
||||
where: {
|
||||
id: environmentId,
|
||||
},
|
||||
data: { websiteSetupCompleted: true },
|
||||
}),
|
||||
capturePosthogEnvironmentEvent(environmentId, "website setup completed"),
|
||||
]);
|
||||
|
||||
revalidateEnvironment = true;
|
||||
}
|
||||
|
||||
const [surveys, actionClasses] = await Promise.all([
|
||||
getSurveys(environmentId),
|
||||
getActionClasses(environmentId),
|
||||
]);
|
||||
|
||||
// Common filter condition for selecting surveys that are in progress, are of type 'website' and have no active segment filtering.
|
||||
const filteredSurveys = surveys.filter(
|
||||
(survey) => survey.status === "inProgress" && survey.type === "website"
|
||||
);
|
||||
|
||||
const state: TJsEnvironmentState["data"] = {
|
||||
surveys: filteredSurveys,
|
||||
actionClasses,
|
||||
product,
|
||||
};
|
||||
|
||||
return {
|
||||
state,
|
||||
revalidateEnvironment,
|
||||
};
|
||||
},
|
||||
[`environmentState-website-${environmentId}`],
|
||||
{
|
||||
...(IS_FORMBRICKS_CLOUD && { revalidate: 24 * 60 * 60 }),
|
||||
tags: [
|
||||
environmentCache.tag.byId(environmentId),
|
||||
organizationCache.tag.byEnvironmentId(environmentId),
|
||||
productCache.tag.byEnvironmentId(environmentId),
|
||||
surveyCache.tag.byEnvironmentId(environmentId),
|
||||
actionClassCache.tag.byEnvironmentId(environmentId),
|
||||
],
|
||||
}
|
||||
)();
|
||||
@@ -1,59 +0,0 @@
|
||||
import { responses } from "@/app/lib/api/response";
|
||||
import { transformErrorToDetails } from "@/app/lib/api/validator";
|
||||
import { NextRequest } from "next/server";
|
||||
import { environmentCache } from "@formbricks/lib/environment/cache";
|
||||
import { ResourceNotFoundError } from "@formbricks/types/errors";
|
||||
import { ZJsSyncInput } from "@formbricks/types/js";
|
||||
import { getEnvironmentState } from "./lib/environmentState";
|
||||
|
||||
export const OPTIONS = async (): Promise<Response> => {
|
||||
return responses.successResponse({}, true);
|
||||
};
|
||||
|
||||
export const GET = async (
|
||||
_: NextRequest,
|
||||
{ params }: { params: { environmentId: string } }
|
||||
): Promise<Response> => {
|
||||
try {
|
||||
const syncInputValidation = ZJsSyncInput.safeParse({
|
||||
environmentId: params.environmentId,
|
||||
});
|
||||
|
||||
if (!syncInputValidation.success) {
|
||||
return responses.badRequestResponse(
|
||||
"Fields are missing or incorrectly formatted",
|
||||
transformErrorToDetails(syncInputValidation.error),
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
const { environmentId } = syncInputValidation.data;
|
||||
|
||||
try {
|
||||
const environmentState = await getEnvironmentState(environmentId);
|
||||
|
||||
if (environmentState.revalidateEnvironment) {
|
||||
environmentCache.revalidate({
|
||||
id: syncInputValidation.data.environmentId,
|
||||
productId: environmentState.state.product.id,
|
||||
});
|
||||
}
|
||||
|
||||
return responses.successResponse(
|
||||
environmentState.state,
|
||||
true,
|
||||
"public, s-maxage=600, max-age=840, stale-while-revalidate=600, stale-if-error=600"
|
||||
);
|
||||
} catch (err) {
|
||||
if (err instanceof ResourceNotFoundError) {
|
||||
return responses.notFoundResponse(err.resourceType, err.resourceId);
|
||||
}
|
||||
|
||||
console.error(err);
|
||||
return responses.internalServerErrorResponse(err.message ?? "Unable to complete response", true);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
return responses.internalServerErrorResponse(`Unable to complete response: ${error.message}`, true);
|
||||
}
|
||||
};
|
||||
@@ -24,7 +24,6 @@ export const GET = async () => {
|
||||
},
|
||||
},
|
||||
appSetupCompleted: true,
|
||||
websiteSetupCompleted: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user