chore: vercel style guide (part 1) (#4451)

This commit is contained in:
Dhruwang Jariwala
2024-12-13 10:53:22 +05:30
committed by GitHub
parent 37966880fd
commit 2a268accff
18 changed files with 116 additions and 114 deletions

View File

@@ -1,7 +1,7 @@
import { responses } from "@/app/lib/api/response";
import { storageCache } from "@formbricks/lib/storage/cache";
import { deleteFile } from "@formbricks/lib/storage/service";
import { TAccessType } from "@formbricks/types/storage";
import { type TAccessType } from "@formbricks/types/storage";
export const handleDeleteFile = async (environmentId: string, accessType: TAccessType, fileName: string) => {
try {

View File

@@ -1,11 +1,14 @@
import { responses } from "@/app/lib/api/response";
import { notFound } from "next/navigation";
import path from "path";
import { UPLOADS_DIR } from "@formbricks/lib/constants";
import { isS3Configured } from "@formbricks/lib/constants";
import path from "node:path";
import { UPLOADS_DIR, isS3Configured } from "@formbricks/lib/constants";
import { getLocalFile, getS3File } from "@formbricks/lib/storage/service";
export const getFile = async (environmentId: string, accessType: string, fileName: string) => {
export const getFile = async (
environmentId: string,
accessType: string,
fileName: string
): Promise<Response> => {
if (!isS3Configured()) {
try {
const { fileBuffer, metaData } = await getLocalFile(
@@ -32,15 +35,16 @@ export const getFile = async (environmentId: string, accessType: string, fileNam
status: 302,
headers: {
Location: signedUrl,
// public file, cache for one hour, private file, cache for 10 minutes
"Cache-Control": `public, max-age=${accessType === "public" ? 3600 : 600}, s-maxage=3600, stale-while-revalidate=300`,
"Cache-Control":
accessType === "public"
? `public, max-age=3600, s-maxage=3600, stale-while-revalidate=300`
: `public, max-age=600, s-maxage=3600, stale-while-revalidate=300`,
},
});
} catch (err) {
if (err.name === "NoSuchKey") {
} catch (error: unknown) {
if (error instanceof Error && error.name === "NoSuchKey") {
return responses.notFoundResponse("File not found", fileName);
} else {
return responses.internalServerErrorResponse("Internal server error");
}
return responses.internalServerErrorResponse("Internal server error");
}
};

View File

@@ -1,18 +1,18 @@
import { authenticateRequest } from "@/app/api/v1/auth";
import { responses } from "@/app/lib/api/response";
import { transformErrorToDetails } from "@/app/lib/api/validator";
import { handleDeleteFile } from "@/app/storage/[environmentId]/[accessType]/[fileName]/lib/deleteFile";
import { handleDeleteFile } from "@/app/storage/[environmentId]/[accessType]/[fileName]/lib/delete-file";
import { authOptions } from "@/modules/auth/lib/authOptions";
import { getServerSession } from "next-auth";
import { NextRequest } from "next/server";
import { type NextRequest } from "next/server";
import { hasUserEnvironmentAccess } from "@formbricks/lib/environment/auth";
import { ZStorageRetrievalParams } from "@formbricks/types/storage";
import { getFile } from "./lib/getFile";
import { getFile } from "./lib/get-file";
export const GET = async (
request: NextRequest,
props: { params: Promise<{ environmentId: string; accessType: string; fileName: string }> }
) => {
): Promise<Response> => {
const params = await props.params;
const paramValidation = ZStorageRetrievalParams.safeParse(params);
@@ -36,7 +36,7 @@ export const GET = async (
const session = await getServerSession(authOptions);
if (!session || !session.user) {
if (!session?.user) {
// check for api key auth
const res = await authenticateRequest(request);
@@ -44,19 +44,22 @@ export const GET = async (
return responses.notAuthenticatedResponse();
}
return await getFile(environmentId, accessType, fileName);
} else {
const isUserAuthorized = await hasUserEnvironmentAccess(session.user.id, environmentId);
if (!isUserAuthorized) {
return responses.unauthorizedResponse();
}
return await getFile(environmentId, accessType, fileName);
}
const isUserAuthorized = await hasUserEnvironmentAccess(session.user.id, environmentId);
if (!isUserAuthorized) {
return responses.unauthorizedResponse();
}
return await getFile(environmentId, accessType, fileName);
};
export const DELETE = async (_: NextRequest, props: { params: Promise<{ fileName: string }> }) => {
export const DELETE = async (
_: NextRequest,
props: { params: Promise<{ fileName: string }> }
): Promise<Response> => {
const params = await props.params;
if (!params.fileName) {
return responses.badRequestResponse("Fields are missing or incorrectly formatted", {
@@ -79,7 +82,7 @@ export const DELETE = async (_: NextRequest, props: { params: Promise<{ fileName
const session = await getServerSession(authOptions);
if (!session || !session.user) {
if (!session?.user) {
return responses.notAuthenticatedResponse();
}

View File

@@ -18,17 +18,17 @@ export const contactAttributeKeyCache = {
return `contactAttributeKey-environment-${environmentId}-key-${key}`;
},
},
revalidate({ id, environmentId, key }: RevalidateProps): void {
revalidate: ({ id, environmentId, key }: RevalidateProps): void => {
if (id) {
revalidateTag(this.tag.byId(id));
revalidateTag(contactAttributeKeyCache.tag.byId(id));
}
if (environmentId) {
revalidateTag(this.tag.byEnvironmentId(environmentId));
revalidateTag(contactAttributeKeyCache.tag.byEnvironmentId(environmentId));
}
if (environmentId && key) {
revalidateTag(this.tag.byEnvironmentIdAndKey(environmentId, key));
revalidateTag(contactAttributeKeyCache.tag.byEnvironmentIdAndKey(environmentId, key));
}
},
};

View File

@@ -22,19 +22,19 @@ export const contactAttributeCache = {
return `contactAttributes-${environmentId}`;
},
},
revalidate({ contactId, environmentId, userId, key }: RevalidateProps): void {
revalidate: ({ contactId, environmentId, userId, key }: RevalidateProps): void => {
if (environmentId) {
revalidateTag(this.tag.byEnvironmentId(environmentId));
revalidateTag(contactAttributeCache.tag.byEnvironmentId(environmentId));
}
if (environmentId && userId) {
revalidateTag(this.tag.byEnvironmentIdAndUserId(environmentId, userId));
revalidateTag(contactAttributeCache.tag.byEnvironmentIdAndUserId(environmentId, userId));
}
if (contactId) {
revalidateTag(this.tag.byContactId(contactId));
revalidateTag(contactAttributeCache.tag.byContactId(contactId));
}
if (contactId && key) {
revalidateTag(this.tag.byKeyAndContactId(key, contactId));
revalidateTag(contactAttributeCache.tag.byKeyAndContactId(key, contactId));
}
},
};

View File

@@ -18,17 +18,17 @@ export const contactCache = {
return `environments-${environmentId}-contactByUserId-${userId}`;
},
},
revalidate({ id, environmentId, userId }: RevalidateProps): void {
revalidate: ({ id, environmentId, userId }: RevalidateProps): void => {
if (id) {
revalidateTag(this.tag.byId(id));
revalidateTag(contactCache.tag.byId(id));
}
if (environmentId) {
revalidateTag(this.tag.byEnvironmentId(environmentId));
revalidateTag(contactCache.tag.byEnvironmentId(environmentId));
}
if (environmentId && userId) {
revalidateTag(this.tag.byEnvironmentIdAndUserId(environmentId, userId));
revalidateTag(contactCache.tag.byEnvironmentIdAndUserId(environmentId, userId));
}
},
};

View File

@@ -1,5 +1,5 @@
import { revalidateTag } from "next/cache";
import { TSurveyQuestionId } from "@formbricks/types/surveys/types";
import { type TSurveyQuestionId } from "@formbricks/types/surveys/types";
interface RevalidateProps {
id?: string;
@@ -37,30 +37,30 @@ export const documentCache = {
return `insights-${insightId}-surveys-${surveyId}-questions-${questionId}-documents`;
},
},
revalidate({ id, environmentId, surveyId, responseId, questionId, insightId }: RevalidateProps): void {
revalidate: ({ id, environmentId, surveyId, responseId, questionId, insightId }: RevalidateProps): void => {
if (id) {
revalidateTag(this.tag.byId(id));
revalidateTag(documentCache.tag.byId(id));
}
if (environmentId) {
revalidateTag(this.tag.byEnvironmentId(environmentId));
revalidateTag(documentCache.tag.byEnvironmentId(environmentId));
}
if (responseId) {
revalidateTag(this.tag.byResponseId(responseId));
revalidateTag(documentCache.tag.byResponseId(responseId));
}
if (surveyId) {
revalidateTag(this.tag.bySurveyId(surveyId));
revalidateTag(documentCache.tag.bySurveyId(surveyId));
}
if (responseId && questionId) {
revalidateTag(this.tag.byResponseIdQuestionId(responseId, questionId));
revalidateTag(documentCache.tag.byResponseIdQuestionId(responseId, questionId));
}
if (surveyId && questionId) {
revalidateTag(this.tag.bySurveyIdQuestionId(surveyId, questionId));
revalidateTag(documentCache.tag.bySurveyIdQuestionId(surveyId, questionId));
}
if (insightId) {
revalidateTag(this.tag.byInsightId(insightId));
revalidateTag(documentCache.tag.byInsightId(insightId));
}
if (insightId && surveyId && questionId) {
revalidateTag(this.tag.byInsightIdSurveyIdQuestionId(insightId, questionId));
revalidateTag(documentCache.tag.byInsightIdSurveyIdQuestionId(insightId, surveyId, questionId));
}
},
};

View File

@@ -14,12 +14,12 @@ export const insightCache = {
return `environments-${environmentId}-documentGroups`;
},
},
revalidate({ id, environmentId }: RevalidateProps): void {
revalidate: ({ id, environmentId }: RevalidateProps): void => {
if (id) {
revalidateTag(this.tag.byId(id));
revalidateTag(insightCache.tag.byId(id));
}
if (environmentId) {
revalidateTag(this.tag.byEnvironmentId(environmentId));
revalidateTag(insightCache.tag.byEnvironmentId(environmentId));
}
},
};

View File

@@ -14,13 +14,13 @@ export const membershipCache = {
return `users-${userId}-memberships`;
},
},
revalidate({ organizationId, userId }: RevalidateProps): void {
revalidate: ({ organizationId, userId }: RevalidateProps): void => {
if (organizationId) {
revalidateTag(this.tag.byOrganizationId(organizationId));
revalidateTag(membershipCache.tag.byOrganizationId(organizationId));
}
if (userId) {
revalidateTag(this.tag.byUserId(userId));
revalidateTag(membershipCache.tag.byUserId(userId));
}
},
};

View File

@@ -22,21 +22,21 @@ export const organizationCache = {
return "organizations-count";
},
},
revalidate({ id, userId, environmentId, count }: RevalidateProps): void {
revalidate: ({ id, userId, environmentId, count }: RevalidateProps): void => {
if (id) {
revalidateTag(this.tag.byId(id));
revalidateTag(organizationCache.tag.byId(id));
}
if (userId) {
revalidateTag(this.tag.byUserId(userId));
revalidateTag(organizationCache.tag.byUserId(userId));
}
if (environmentId) {
revalidateTag(this.tag.byEnvironmentId(environmentId));
revalidateTag(organizationCache.tag.byEnvironmentId(environmentId));
}
if (count) {
revalidateTag(this.tag.byCount());
revalidateTag(organizationCache.tag.byCount());
}
},
};

View File

@@ -22,18 +22,18 @@ export const teamCache = {
return `organization-${organizationId}-teams`;
},
},
revalidate({ id, projectId, userId, organizationId }: RevalidateProps): void {
revalidate: ({ id, projectId, userId, organizationId }: RevalidateProps): void => {
if (id) {
revalidateTag(this.tag.byId(id));
revalidateTag(teamCache.tag.byId(id));
}
if (projectId) {
revalidateTag(this.tag.byProjectId(projectId));
revalidateTag(teamCache.tag.byProjectId(projectId));
}
if (userId) {
revalidateTag(this.tag.byUserId(userId));
revalidateTag(teamCache.tag.byUserId(userId));
}
if (organizationId) {
revalidateTag(this.tag.byOrganizationId(organizationId));
revalidateTag(teamCache.tag.byOrganizationId(organizationId));
}
},
};

View File

@@ -1,11 +1,11 @@
import { getProjectPermissionByUserId, getTeamRoleByTeamIdUserId } from "@/modules/ee/teams/lib/roles";
import { TTeamPermission } from "@/modules/ee/teams/project-teams/types/teams";
import { TTeamRole } from "@/modules/ee/teams/team-list/types/teams";
import { type TTeamPermission } from "@/modules/ee/teams/project-teams/types/teams";
import { type TTeamRole } from "@/modules/ee/teams/team-list/types/teams";
import { returnValidationErrors } from "next-safe-action";
import { ZodIssue, z } from "zod";
import { getMembershipRole } from "@formbricks/lib/membership/hooks/actions";
import { AuthorizationError } from "@formbricks/types/errors";
import { TOrganizationRole } from "@formbricks/types/memberships";
import { type TOrganizationRole } from "@formbricks/types/memberships";
const formatErrors = (issues: ZodIssue[]): Record<string, { _errors: string[] }> => {
return {
@@ -58,7 +58,7 @@ export const checkAuthorizationUpdated = async <T extends z.ZodRawShape>({
}) => {
const role = await getMembershipRole(userId, organizationId);
for (let accessItem of access) {
for (const accessItem of access) {
if (accessItem.type === "organization") {
if (accessItem.schema) {
const resultSchema = accessItem.schema.strict();

View File

@@ -24,6 +24,7 @@ export const actionClient = createSafeActionClient({
return e.message;
}
// eslint-disable-next-line no-console -- This error needs to be logged for debugging server-side errors
console.error("SERVER ERROR: ", e);
return DEFAULT_SERVER_ERROR_MESSAGE;
},

View File

@@ -19,7 +19,7 @@ import {
} from "@/lib/utils/services";
import { ResourceNotFoundError } from "@formbricks/types/errors";
export const getFormattedErrorMessage = (result) => {
export const getFormattedErrorMessage = (result): string => {
let message = "";
if (result.serverError) {

View File

@@ -104,10 +104,8 @@ export const getEnvironment = reactCache(
return environment;
} catch (error) {
if (error instanceof Prisma.PrismaClientKnownRequestError) {
console.error(error);
throw new DatabaseError(error.message);
}
throw error;
}
},
@@ -194,7 +192,6 @@ export const getLanguage = async (languageId: string): Promise<{ projectId: stri
return language;
} catch (error) {
if (error instanceof Prisma.PrismaClientKnownRequestError) {
console.error(error);
throw new DatabaseError(error.message);
}
throw error;
@@ -205,15 +202,13 @@ export const getProject = reactCache(
async (projectId: string): Promise<{ organizationId: string } | null> =>
cache(
async () => {
let projectPrisma;
try {
projectPrisma = await prisma.project.findUnique({
const projectPrisma = await prisma.project.findUnique({
where: {
id: projectId,
},
select: { organizationId: true },
});
return projectPrisma;
} catch (error) {
if (error instanceof Prisma.PrismaClientKnownRequestError) {
@@ -306,7 +301,6 @@ export const getSurvey = reactCache(
return survey;
} catch (error) {
if (error instanceof Prisma.PrismaClientKnownRequestError) {
console.error(error);
throw new DatabaseError(error.message);
}
throw error;
@@ -324,21 +318,15 @@ export const getTag = reactCache(
cache(
async () => {
validateInputs([id, ZId]);
try {
const tag = await prisma.tag.findUnique({
where: {
id,
},
select: {
environmentId: true,
},
});
return tag;
} catch (error) {
throw error;
}
const tag = await prisma.tag.findUnique({
where: {
id,
},
select: {
environmentId: true,
},
});
return tag;
},
[`utils-getTag-${id}`],
{
@@ -476,29 +464,19 @@ export const isProjectPartOfOrganization = async (
organizationId: string,
projectId: string
): Promise<boolean> => {
try {
const project = await getProject(projectId);
if (!project) {
throw new ResourceNotFoundError("Project", projectId);
}
return project.organizationId === organizationId;
} catch (error) {
throw error;
const project = await getProject(projectId);
if (!project) {
throw new ResourceNotFoundError("Project", projectId);
}
return project.organizationId === organizationId;
};
export const isTeamPartOfOrganization = async (organizationId: string, teamId: string): Promise<boolean> => {
try {
const team = await getTeam(teamId);
if (!team) {
throw new ResourceNotFoundError("Team", teamId);
}
return team.organizationId === organizationId;
} catch (error) {
throw error;
const team = await getTeam(teamId);
if (!team) {
throw new ResourceNotFoundError("Team", teamId);
}
return team.organizationId === organizationId;
};
export const getContact = reactCache(

View File

@@ -38,6 +38,7 @@
"@opentelemetry/instrumentation": "0.53.0",
"@opentelemetry/sdk-logs": "0.53.0",
"@paralleldrive/cuid2": "2.2.2",
"@prisma/client": "5.20.0",
"@radix-ui/react-accordion": "1.2.0",
"@radix-ui/react-checkbox": "1.1.1",
"@radix-ui/react-collapsible": "1.1.1",
@@ -87,6 +88,7 @@
"lucide-react": "0.452.0",
"mime": "4.0.4",
"next": "15.0.3",
"next-auth": "4.24.10",
"next-intl": "3.20.0",
"next-safe-action": "7.9.3",
"optional": "0.1.4",
@@ -111,7 +113,8 @@
"tailwindcss": "3.4.13",
"ua-parser-js": "1.0.39",
"webpack": "5.95.0",
"xlsx": "0.18.5"
"xlsx": "0.18.5",
"zod": "3.23.8"
},
"devDependencies": {
"@formbricks/config-typescript": "workspace:*",

View File

@@ -310,7 +310,11 @@ export const putFile = async (
}
};
export const deleteFile = async (environmentId: string, accessType: TAccessType, fileName: string) => {
export const deleteFile = async (
environmentId: string,
accessType: TAccessType,
fileName: string
): Promise<{ success: boolean; message: string; code?: number }> => {
if (!isS3Configured()) {
try {
await deleteLocalFile(path.join(UPLOADS_DIR, environmentId, accessType, fileName));

13
pnpm-lock.yaml generated
View File

@@ -151,7 +151,7 @@ importers:
version: 8.12.1
autoprefixer:
specifier: 10.4.20
version: 10.4.20(postcss@8.4.41)
version: 10.4.20(postcss@8.4.49)
clsx:
specifier: 2.1.1
version: 2.1.1
@@ -421,6 +421,9 @@ importers:
'@paralleldrive/cuid2':
specifier: 2.2.2
version: 2.2.2
'@prisma/client':
specifier: 5.20.0
version: 5.20.0(prisma@5.20.0)
'@radix-ui/react-accordion':
specifier: 1.2.0
version: 1.2.0(@types/react-dom@18.3.0)(@types/react@18.3.11)(react-dom@19.0.0-rc-ed15d500-20241110(react@19.0.0-rc-ed15d500-20241110))(react@19.0.0-rc-ed15d500-20241110)
@@ -504,7 +507,7 @@ importers:
version: 3.4.33(react@19.0.0-rc-ed15d500-20241110)(sswr@2.1.0(svelte@5.4.0))(svelte@5.4.0)(vue@3.5.13(typescript@5.7.2))(zod@3.23.8)
autoprefixer:
specifier: 10.4.20
version: 10.4.20(postcss@8.4.49)
version: 10.4.20(postcss@8.4.41)
bcryptjs:
specifier: 2.4.3
version: 2.4.3
@@ -568,6 +571,9 @@ importers:
next:
specifier: 15.0.3
version: 15.0.3(@opentelemetry/api@1.9.0)(@playwright/test@1.45.3)(react-dom@19.0.0-rc-ed15d500-20241110(react@19.0.0-rc-ed15d500-20241110))(react@19.0.0-rc-ed15d500-20241110)
next-auth:
specifier: 4.24.10
version: 4.24.10(next@15.0.3(@opentelemetry/api@1.9.0)(@playwright/test@1.45.3)(react-dom@19.0.0-rc-ed15d500-20241110(react@19.0.0-rc-ed15d500-20241110))(react@19.0.0-rc-ed15d500-20241110))(nodemailer@6.9.16)(react-dom@19.0.0-rc-ed15d500-20241110(react@19.0.0-rc-ed15d500-20241110))(react@19.0.0-rc-ed15d500-20241110)
next-intl:
specifier: 3.20.0
version: 3.20.0(next@15.0.3(@opentelemetry/api@1.9.0)(@playwright/test@1.45.3)(react-dom@19.0.0-rc-ed15d500-20241110(react@19.0.0-rc-ed15d500-20241110))(react@19.0.0-rc-ed15d500-20241110))(react@19.0.0-rc-ed15d500-20241110)
@@ -643,6 +649,9 @@ importers:
xlsx:
specifier: 0.18.5
version: 0.18.5
zod:
specifier: 3.23.8
version: 3.23.8
devDependencies:
'@formbricks/config-typescript':
specifier: workspace:*