perf: move to disable prisma client extension inference (#23692)
* perf: move to disable prisma client extension inference * Prisma doesn't like it when you pass Record<string, unknown> * API v1 type fixes * Missed one * Fix unit test fail due to faulty expect * Assigning to prisma InputJsonValue/Array must be done as object, not interface * Fix @calcom/web ts error, teams not defined * Run eslint formatter * fixed the routingFormHelpers file causing a failing app store e2e test
This commit is contained in:
@@ -3,7 +3,8 @@ import type { NextApiRequest } from "next";
|
||||
import { OAuth2UniversalSchema } from "@calcom/app-store/_utils/oauth/universalSchema";
|
||||
import { symmetricDecrypt } from "@calcom/lib/crypto";
|
||||
import { defaultResponder } from "@calcom/lib/server/defaultResponder";
|
||||
import prisma from "@calcom/prisma";
|
||||
import { prisma } from "@calcom/prisma";
|
||||
import type { Prisma } from "@calcom/prisma/client";
|
||||
|
||||
import { schemaCredentialPatchParams, schemaCredentialPatchBody } from "~/lib/validations/credential-sync";
|
||||
|
||||
@@ -71,7 +72,7 @@ async function handler(req: NextApiRequest) {
|
||||
userId,
|
||||
},
|
||||
data: {
|
||||
key,
|
||||
key: key as unknown as Prisma.InputJsonValue,
|
||||
},
|
||||
select: {
|
||||
id: true,
|
||||
|
||||
@@ -6,7 +6,8 @@ import { appStoreMetadata } from "@calcom/app-store/appStoreMetaData";
|
||||
import { symmetricDecrypt } from "@calcom/lib/crypto";
|
||||
import { HttpError } from "@calcom/lib/http-error";
|
||||
import { defaultResponder } from "@calcom/lib/server/defaultResponder";
|
||||
import prisma from "@calcom/prisma";
|
||||
import { prisma } from "@calcom/prisma";
|
||||
import type { Prisma } from "@calcom/prisma/client";
|
||||
import { credentialForCalendarServiceSelect } from "@calcom/prisma/selects/credential";
|
||||
|
||||
import { schemaCredentialPostBody, schemaCredentialPostParams } from "~/lib/validations/credential-sync";
|
||||
@@ -92,7 +93,7 @@ async function handler(req: NextApiRequest) {
|
||||
data: {
|
||||
userId,
|
||||
appId: appSlug,
|
||||
key,
|
||||
key: key as unknown as Prisma.InputJsonValue,
|
||||
type: appMetadata.type,
|
||||
},
|
||||
select: credentialForCalendarServiceSelect,
|
||||
|
||||
@@ -77,7 +77,7 @@ describe("POST /api/attendees", () => {
|
||||
|
||||
const userBooking = { id: 1 };
|
||||
|
||||
prismaMock.booking.findFirst.mockResolvedValue(userBooking);
|
||||
prismaMock.booking.findFirst.mockResolvedValue(userBooking as any);
|
||||
|
||||
const attendeeData = {
|
||||
id: 1,
|
||||
|
||||
@@ -25,7 +25,7 @@ beforeEach(() => {
|
||||
id: userId,
|
||||
email: "test@example.com",
|
||||
name: "Test User",
|
||||
});
|
||||
} as any);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
|
||||
@@ -20,7 +20,7 @@ beforeEach(() => {
|
||||
id: userId,
|
||||
email: "test@example.com",
|
||||
name: "Test User",
|
||||
});
|
||||
} as any);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
|
||||
@@ -30,12 +30,13 @@ beforeEach(() => {
|
||||
id: userId,
|
||||
email: "test@example.com",
|
||||
name: "Test User",
|
||||
});
|
||||
} as any);
|
||||
(getAccessibleUsers as any).mockResolvedValue([userId]);
|
||||
(retrieveOrgScopedAccessibleUsers as any).mockResolvedValue([userId]);
|
||||
|
||||
prismaMock.membership.findMany.mockResolvedValue([
|
||||
{
|
||||
// @ts-expect-error Will be fixed by Prisma 6.7.0 upgrade mock changes - which uses vitest-mock-extended
|
||||
team: {
|
||||
id: 1,
|
||||
isOrganization: true,
|
||||
@@ -48,7 +49,7 @@ beforeEach(() => {
|
||||
id: userId,
|
||||
email: "test@example.com",
|
||||
},
|
||||
]);
|
||||
] as any);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
|
||||
@@ -11,9 +11,9 @@ import { getEventTypesFromDB } from "@calcom/features/bookings/lib/handleNewBook
|
||||
import sendPayload from "@calcom/features/webhooks/lib/sendOrSchedulePayload";
|
||||
import { ErrorCode } from "@calcom/lib/errorCodes";
|
||||
import { buildBooking, buildEventType, buildWebhook, buildUser } from "@calcom/lib/test/builder";
|
||||
import prisma from "@calcom/prisma";
|
||||
import { prisma } from "@calcom/prisma";
|
||||
import type { Booking } from "@calcom/prisma/client";
|
||||
import { CreationSource } from "@calcom/prisma/enums";
|
||||
import { CreationSource, BookingStatus } from "@calcom/prisma/enums";
|
||||
|
||||
import handler from "../../../pages/api/bookings/_post";
|
||||
|
||||
@@ -303,6 +303,7 @@ describe("POST /api/bookings", () => {
|
||||
|
||||
prismaMock.eventType.findUniqueOrThrow.mockResolvedValue({
|
||||
...buildEventType({ recurringEvent: { freq: 2, count: 12, interval: 1 } }),
|
||||
// @ts-expect-error requires mockDeep which will be introduced in the Prisma 6.7.0 upgrade, ignore for now.
|
||||
profile: { organizationId: null },
|
||||
hosts: [],
|
||||
users: [buildUser()],
|
||||
@@ -340,6 +341,7 @@ describe("POST /api/bookings", () => {
|
||||
|
||||
prismaMock.eventType.findUniqueOrThrow.mockResolvedValue({
|
||||
...buildEventType({ recurringEvent: { freq: 2, count: 12, interval: 1 } }),
|
||||
// @ts-expect-error requires mockDeep which will be introduced in the Prisma 6.7.0 upgrade, ignore for now.
|
||||
profile: { organizationId: null },
|
||||
hosts: [],
|
||||
users: [buildUser()],
|
||||
@@ -376,6 +378,7 @@ describe("POST /api/bookings", () => {
|
||||
|
||||
prismaMock.eventType.findUniqueOrThrow.mockResolvedValue({
|
||||
...buildEventType({ profileId: null }),
|
||||
// @ts-expect-error requires mockDeep which will be introduced in the Prisma 6.7.0 upgrade, ignore for now.
|
||||
profile: { organizationId: null },
|
||||
hosts: [],
|
||||
users: [buildUser()],
|
||||
@@ -417,6 +420,7 @@ describe("POST /api/bookings", () => {
|
||||
|
||||
prismaMock.eventType.findUniqueOrThrow.mockResolvedValue({
|
||||
...buildEventType({ profileId: null, length: 15 }),
|
||||
// @ts-expect-error requires mockDeep which will be introduced in the Prisma 6.7.0 upgrade, ignore for now.
|
||||
profile: { organizationId: null },
|
||||
hosts: [],
|
||||
users: [buildUser()],
|
||||
@@ -468,7 +472,7 @@ describe("POST /api/bookings", () => {
|
||||
|
||||
prismaMock.booking.findUnique.mockResolvedValue({
|
||||
...originalBooking,
|
||||
status: "cancelled",
|
||||
status: "CANCELLED",
|
||||
});
|
||||
|
||||
const { req, res } = createMocks<CustomNextApiRequest, CustomNextApiResponse>({
|
||||
@@ -492,6 +496,7 @@ describe("POST /api/bookings", () => {
|
||||
|
||||
prismaMock.eventType.findUniqueOrThrow.mockResolvedValue({
|
||||
...buildEventType({ profileId: null, length: 15 }),
|
||||
// @ts-expect-error requires mockDeep which will be introduced in the Prisma 6.7.0 upgrade, ignore for now.
|
||||
profile: { organizationId: null },
|
||||
hosts: [],
|
||||
users: [buildUser()],
|
||||
@@ -532,7 +537,7 @@ describe("POST /api/bookings", () => {
|
||||
const previousBooking = await prisma.booking.findUnique({
|
||||
where: { uid: "original-booking-uid" },
|
||||
});
|
||||
expect(previousBooking?.status).toBe("cancelled");
|
||||
expect(previousBooking?.status).toBe(BookingStatus.CANCELLED);
|
||||
});
|
||||
|
||||
test("Creates source as api_v1", async () => {
|
||||
@@ -556,6 +561,7 @@ describe("POST /api/bookings", () => {
|
||||
|
||||
prismaMock.eventType.findUniqueOrThrow.mockResolvedValue({
|
||||
...buildEventType({ profileId: null, length: 15 }),
|
||||
// @ts-expect-error requires mockDeep which will be introduced in the Prisma 6.7.0 upgrade, ignore for now.
|
||||
profile: { organizationId: null },
|
||||
hosts: [],
|
||||
users: [buildUser()],
|
||||
@@ -627,6 +633,7 @@ describe("POST /api/bookings", () => {
|
||||
|
||||
prismaMock.eventType.findUniqueOrThrow.mockResolvedValue({
|
||||
...buildEventType({ profileId: null, length: 15 }),
|
||||
// @ts-expect-error requires mockDeep which will be introduced in the Prisma 6.7.0 upgrade, ignore for now.
|
||||
profile: { organizationId: null },
|
||||
hosts: [],
|
||||
users: [buildUser()],
|
||||
@@ -684,6 +691,7 @@ describe("POST /api/bookings", () => {
|
||||
|
||||
prismaMock.eventType.findUniqueOrThrow.mockResolvedValue({
|
||||
...buildEventType({ recurringEvent: { freq: 2, count: 12, interval: 1 } }),
|
||||
// @ts-expect-error requires mockDeep which will be introduced in the Prisma 6.7.0 upgrade, ignore for now.
|
||||
profile: { organizationId: null },
|
||||
hosts: [],
|
||||
users: [buildUser()],
|
||||
|
||||
@@ -50,6 +50,7 @@ describe("DELETE /api/event-types/[id]", () => {
|
||||
// Mocking team.findUnique
|
||||
prismaMock.team.findUnique.mockResolvedValue({
|
||||
id: teamId,
|
||||
// @ts-expect-error requires mockDeep which will be introduced in the Prisma 6.7.0 upgrade, ignore for now.
|
||||
members: [
|
||||
{ userId: memberUser, role: MembershipRole.MEMBER, teamId: teamId },
|
||||
{ userId: adminUser, role: MembershipRole.ADMIN, teamId: teamId },
|
||||
|
||||
@@ -84,6 +84,7 @@ describe("GET /api/event-types/[id]", () => {
|
||||
|
||||
prismaMock.team.findFirst.mockResolvedValue({
|
||||
id: teamId,
|
||||
// @ts-expect-error requires mockDeep which will be introduced in the Prisma 6.7.0 upgrade, ignore for now.
|
||||
members: [
|
||||
{
|
||||
userId,
|
||||
|
||||
@@ -29,8 +29,11 @@ interface RouteConfig {
|
||||
value: string;
|
||||
};
|
||||
isFallback?: boolean;
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
queryValue?: any;
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
attributesQueryValue?: any;
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
fallbackAttributesQueryValue?: any;
|
||||
}
|
||||
|
||||
@@ -129,6 +132,7 @@ export async function createRoutingForm(config: CreateRoutingFormConfig) {
|
||||
const teamEventsConfig = config.attributeRouting.teamEvents;
|
||||
|
||||
// Create team events
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const teamEvents: { [key: string]: any } = {};
|
||||
for (const eventConfig of teamEventsConfig) {
|
||||
const eventType = await createRoundRobinTeamEventType({
|
||||
@@ -149,10 +153,8 @@ export async function createRoutingForm(config: CreateRoutingFormConfig) {
|
||||
throw new Error("Attributes not found");
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||
const skillAttribute = attributes.find((attr) => attr.name === "Skills")!;
|
||||
const locationAttribute = attributes.find((attr) => attr.name === "Location")!;
|
||||
|
||||
console.log("Attributes", JSON.stringify(attributes, null, 2));
|
||||
|
||||
const javascriptEventRoute = {
|
||||
id: "8a898988-89ab-4cde-b012-31823f708642",
|
||||
@@ -316,41 +318,44 @@ export async function createRoutingForm(config: CreateRoutingFormConfig) {
|
||||
queryValue: { id: "814899aa-4567-489a-bcde-f1823f708646", type: "group" },
|
||||
},
|
||||
],
|
||||
fields: config.form?.fields || [
|
||||
{
|
||||
id: form.formFieldLocation.id,
|
||||
type: "select",
|
||||
label: "Location",
|
||||
options: formFieldLocationOptions,
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
id: form.formFieldSkills.id,
|
||||
type: "multiselect",
|
||||
label: "skills",
|
||||
options: formFieldSkillsOptions,
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
id: form.formFieldEmail.id,
|
||||
type: "email",
|
||||
label: "Email",
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
id: form.formFieldName.id,
|
||||
identifier: "name",
|
||||
type: "text",
|
||||
label: "Name",
|
||||
required: false,
|
||||
},
|
||||
{
|
||||
id: form.formFieldRating.id,
|
||||
type: "number",
|
||||
label: "Rating",
|
||||
required: false,
|
||||
},
|
||||
],
|
||||
fields: (
|
||||
config.form?.fields ||
|
||||
([
|
||||
{
|
||||
id: form.formFieldLocation.id,
|
||||
type: "select",
|
||||
label: "Location",
|
||||
options: formFieldLocationOptions,
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
id: form.formFieldSkills.id,
|
||||
type: "multiselect",
|
||||
label: "skills",
|
||||
options: formFieldSkillsOptions,
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
id: form.formFieldEmail.id,
|
||||
type: "email",
|
||||
label: "Email",
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
id: form.formFieldName.id,
|
||||
identifier: "name",
|
||||
type: "text",
|
||||
label: "Name",
|
||||
required: false,
|
||||
},
|
||||
{
|
||||
id: form.formFieldRating.id,
|
||||
type: "number",
|
||||
label: "Rating",
|
||||
required: false,
|
||||
},
|
||||
] satisfies FieldConfig[])
|
||||
).map((field) => ({ ...field })),
|
||||
team: {
|
||||
connect: {
|
||||
id: teamId,
|
||||
@@ -379,172 +384,178 @@ export async function createRoutingForm(config: CreateRoutingFormConfig) {
|
||||
|
||||
const form = await prisma.app_RoutingForms_Form.create({
|
||||
data: {
|
||||
routes: config.form?.routes || [
|
||||
{
|
||||
id: "8a898988-89ab-4cde-b012-31823f708642",
|
||||
action: { type: "eventTypeRedirectUrl", value: "pro/30min" },
|
||||
queryValue: {
|
||||
routes: (
|
||||
config.form?.routes ||
|
||||
([
|
||||
{
|
||||
id: "8a898988-89ab-4cde-b012-31823f708642",
|
||||
type: "group",
|
||||
children1: {
|
||||
"8988bbb8-0123-4456-b89a-b1823f70c5ff": {
|
||||
type: "rule",
|
||||
properties: {
|
||||
field: "c4296635-9f12-47b1-8153-c3a854649182",
|
||||
value: ["event-routing"],
|
||||
operator: "equal",
|
||||
valueSrc: ["value"],
|
||||
valueType: ["text"],
|
||||
action: { type: "eventTypeRedirectUrl", value: "pro/30min" },
|
||||
queryValue: {
|
||||
id: "8a898988-89ab-4cde-b012-31823f708642",
|
||||
type: "group",
|
||||
children1: {
|
||||
"8988bbb8-0123-4456-b89a-b1823f70c5ff": {
|
||||
type: "rule",
|
||||
properties: {
|
||||
field: "c4296635-9f12-47b1-8153-c3a854649182",
|
||||
value: ["event-routing"],
|
||||
operator: "equal",
|
||||
valueSrc: ["value"],
|
||||
valueType: ["text"],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
id: "aa8aaba9-cdef-4012-b456-71823f70f7ef",
|
||||
action: { type: "customPageMessage", value: "Custom Page Result" },
|
||||
queryValue: {
|
||||
{
|
||||
id: "aa8aaba9-cdef-4012-b456-71823f70f7ef",
|
||||
type: "group",
|
||||
children1: {
|
||||
"b99b8a89-89ab-4cde-b012-31823f718ff5": {
|
||||
type: "rule",
|
||||
properties: {
|
||||
field: "c4296635-9f12-47b1-8153-c3a854649182",
|
||||
value: ["custom-page"],
|
||||
operator: "equal",
|
||||
valueSrc: ["value"],
|
||||
valueType: ["text"],
|
||||
action: { type: "customPageMessage", value: "Custom Page Result" },
|
||||
queryValue: {
|
||||
id: "aa8aaba9-cdef-4012-b456-71823f70f7ef",
|
||||
type: "group",
|
||||
children1: {
|
||||
"b99b8a89-89ab-4cde-b012-31823f718ff5": {
|
||||
type: "rule",
|
||||
properties: {
|
||||
field: "c4296635-9f12-47b1-8153-c3a854649182",
|
||||
value: ["custom-page"],
|
||||
operator: "equal",
|
||||
valueSrc: ["value"],
|
||||
valueType: ["text"],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
id: "a8ba9aab-4567-489a-bcde-f1823f71b4ad",
|
||||
action: { type: "externalRedirectUrl", value: `${WEBAPP_URL}/pro` },
|
||||
queryValue: {
|
||||
{
|
||||
id: "a8ba9aab-4567-489a-bcde-f1823f71b4ad",
|
||||
type: "group",
|
||||
children1: {
|
||||
"998b9b9a-0123-4456-b89a-b1823f7232b9": {
|
||||
type: "rule",
|
||||
properties: {
|
||||
field: "c4296635-9f12-47b1-8153-c3a854649182",
|
||||
value: ["external-redirect"],
|
||||
operator: "equal",
|
||||
valueSrc: ["value"],
|
||||
valueType: ["text"],
|
||||
action: { type: "externalRedirectUrl", value: `${WEBAPP_URL}/pro` },
|
||||
queryValue: {
|
||||
id: "a8ba9aab-4567-489a-bcde-f1823f71b4ad",
|
||||
type: "group",
|
||||
children1: {
|
||||
"998b9b9a-0123-4456-b89a-b1823f7232b9": {
|
||||
type: "rule",
|
||||
properties: {
|
||||
field: "c4296635-9f12-47b1-8153-c3a854649182",
|
||||
value: ["external-redirect"],
|
||||
operator: "equal",
|
||||
valueSrc: ["value"],
|
||||
valueType: ["text"],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
id: "aa8ba8b9-0123-4456-b89a-b182623406d8",
|
||||
action: { type: "customPageMessage", value: "Multiselect(Legacy) chosen" },
|
||||
queryValue: {
|
||||
{
|
||||
id: "aa8ba8b9-0123-4456-b89a-b182623406d8",
|
||||
type: "group",
|
||||
children1: {
|
||||
"b98a8abb-cdef-4012-b456-718262343d27": {
|
||||
type: "rule",
|
||||
properties: {
|
||||
field: multiSelectLegacyFieldUuid,
|
||||
value: [["Option-2"]],
|
||||
operator: "multiselect_equals",
|
||||
valueSrc: ["value"],
|
||||
valueType: ["multiselect"],
|
||||
action: { type: "customPageMessage", value: "Multiselect(Legacy) chosen" },
|
||||
queryValue: {
|
||||
id: "aa8ba8b9-0123-4456-b89a-b182623406d8",
|
||||
type: "group",
|
||||
children1: {
|
||||
"b98a8abb-cdef-4012-b456-718262343d27": {
|
||||
type: "rule",
|
||||
properties: {
|
||||
field: multiSelectLegacyFieldUuid,
|
||||
value: [["Option-2"]],
|
||||
operator: "multiselect_equals",
|
||||
valueSrc: ["value"],
|
||||
valueType: ["multiselect"],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
id: "bb9ea8b9-0123-4456-b89a-b182623406d8",
|
||||
action: { type: "customPageMessage", value: "Multiselect chosen" },
|
||||
queryValue: {
|
||||
id: "aa8ba8b9-0123-4456-b89a-b182623406d8",
|
||||
type: "group",
|
||||
children1: {
|
||||
"b98a8abb-cdef-4012-b456-718262343d27": {
|
||||
type: "rule",
|
||||
properties: {
|
||||
field: multiSelectFieldUuid,
|
||||
value: [[multiSelectOption2Uuid]],
|
||||
operator: "multiselect_equals",
|
||||
valueSrc: ["value"],
|
||||
valueType: ["multiselect"],
|
||||
{
|
||||
id: "bb9ea8b9-0123-4456-b89a-b182623406d8",
|
||||
action: { type: "customPageMessage", value: "Multiselect chosen" },
|
||||
queryValue: {
|
||||
id: "aa8ba8b9-0123-4456-b89a-b182623406d8",
|
||||
type: "group",
|
||||
children1: {
|
||||
"b98a8abb-cdef-4012-b456-718262343d27": {
|
||||
type: "rule",
|
||||
properties: {
|
||||
field: multiSelectFieldUuid,
|
||||
value: [[multiSelectOption2Uuid]],
|
||||
operator: "multiselect_equals",
|
||||
valueSrc: ["value"],
|
||||
valueType: ["multiselect"],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
id: "898899aa-4567-489a-bcde-f1823f708646",
|
||||
action: { type: "customPageMessage", value: "Fallback Message" },
|
||||
isFallback: true,
|
||||
queryValue: { id: "898899aa-4567-489a-bcde-f1823f708646", type: "group" },
|
||||
},
|
||||
],
|
||||
fields: config.form?.fields || [
|
||||
{
|
||||
id: "c4296635-9f12-47b1-8153-c3a854649182",
|
||||
type: "text",
|
||||
label: "Test field",
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
id: multiSelectLegacyFieldUuid,
|
||||
type: "multiselect",
|
||||
label: "Multi Select(with Legacy `selectText`)",
|
||||
identifier: "multi",
|
||||
selectText: "Option-1\nOption-2",
|
||||
required: false,
|
||||
},
|
||||
{
|
||||
id: multiSelectFieldUuid,
|
||||
type: "multiselect",
|
||||
label: "Multi Select",
|
||||
identifier: "multi-new-format",
|
||||
options: [
|
||||
{
|
||||
id: multiSelectOption1Uuid,
|
||||
label: "Option-1",
|
||||
},
|
||||
{
|
||||
id: multiSelectOption2Uuid,
|
||||
label: "Option-2",
|
||||
},
|
||||
],
|
||||
required: false,
|
||||
},
|
||||
{
|
||||
id: legacySelectFieldUuid,
|
||||
type: "select",
|
||||
label: "Legacy Select",
|
||||
identifier: "test-select",
|
||||
selectText: "Option-1\nOption-2",
|
||||
required: false,
|
||||
},
|
||||
{
|
||||
id: selectFieldUuid,
|
||||
type: "select",
|
||||
label: "Select",
|
||||
identifier: "test-select-new-format",
|
||||
options: [
|
||||
{
|
||||
id: selectOption1Uuid,
|
||||
label: "Option-1",
|
||||
},
|
||||
{
|
||||
id: selectOption2Uuid,
|
||||
label: "Option-2",
|
||||
},
|
||||
],
|
||||
required: false,
|
||||
},
|
||||
],
|
||||
{
|
||||
id: "898899aa-4567-489a-bcde-f1823f708646",
|
||||
action: { type: "customPageMessage", value: "Fallback Message" },
|
||||
isFallback: true,
|
||||
queryValue: { id: "898899aa-4567-489a-bcde-f1823f708646", type: "group" },
|
||||
},
|
||||
] satisfies RouteConfig[])
|
||||
).map((field) => ({ ...field })),
|
||||
fields: (
|
||||
config.form?.fields ||
|
||||
([
|
||||
{
|
||||
id: "c4296635-9f12-47b1-8153-c3a854649182",
|
||||
type: "text",
|
||||
label: "Test field",
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
id: multiSelectLegacyFieldUuid,
|
||||
type: "multiselect",
|
||||
label: "Multi Select(with Legacy `selectText`)",
|
||||
identifier: "multi",
|
||||
selectText: "Option-1\nOption-2",
|
||||
required: false,
|
||||
},
|
||||
{
|
||||
id: multiSelectFieldUuid,
|
||||
type: "multiselect",
|
||||
label: "Multi Select",
|
||||
identifier: "multi-new-format",
|
||||
options: [
|
||||
{
|
||||
id: multiSelectOption1Uuid,
|
||||
label: "Option-1",
|
||||
},
|
||||
{
|
||||
id: multiSelectOption2Uuid,
|
||||
label: "Option-2",
|
||||
},
|
||||
],
|
||||
required: false,
|
||||
},
|
||||
{
|
||||
id: legacySelectFieldUuid,
|
||||
type: "select",
|
||||
label: "Legacy Select",
|
||||
identifier: "test-select",
|
||||
selectText: "Option-1\nOption-2",
|
||||
required: false,
|
||||
},
|
||||
{
|
||||
id: selectFieldUuid,
|
||||
type: "select",
|
||||
label: "Select",
|
||||
identifier: "test-select-new-format",
|
||||
options: [
|
||||
{
|
||||
id: selectOption1Uuid,
|
||||
label: "Option-1",
|
||||
},
|
||||
{
|
||||
id: selectOption2Uuid,
|
||||
label: "Option-2",
|
||||
},
|
||||
],
|
||||
required: false,
|
||||
},
|
||||
] satisfies FieldConfig[])
|
||||
).map((field) => ({ ...field })),
|
||||
user: {
|
||||
connect: {
|
||||
id: userId,
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import type { Prisma } from "@prisma/client";
|
||||
import type z from "zod";
|
||||
|
||||
import logger from "@calcom/lib/logger";
|
||||
import { CredentialRepository } from "@calcom/lib/server/repository/credential";
|
||||
import prisma from "@calcom/prisma";
|
||||
import { prisma } from "@calcom/prisma";
|
||||
import type { Prisma } from "@calcom/prisma/client";
|
||||
|
||||
import type { OAuth2UniversalSchemaWithCalcomBackwardCompatibility } from "./universalSchema";
|
||||
|
||||
@@ -23,7 +23,7 @@ export const updateTokenObject = async ({
|
||||
id: credentialId,
|
||||
},
|
||||
data: {
|
||||
key: tokenObject,
|
||||
key: tokenObject as unknown as Prisma.InputJsonValue,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
@@ -5,6 +5,7 @@ import { z } from "zod";
|
||||
import logger from "@calcom/lib/logger";
|
||||
import { safeStringify } from "@calcom/lib/safeStringify";
|
||||
import prisma from "@calcom/prisma";
|
||||
import type { Prisma } from "@calcom/prisma/client";
|
||||
import type { CalendarEvent } from "@calcom/types/Calendar";
|
||||
import type { CredentialPayload } from "@calcom/types/Credential";
|
||||
import type { PartialReference } from "@calcom/types/EventManager";
|
||||
@@ -102,7 +103,7 @@ const NextcloudTalkVideoApiAdapter = (credential: CredentialPayload): VideoApiAd
|
||||
id: credential.id,
|
||||
},
|
||||
data: {
|
||||
key: newTokenObject,
|
||||
key: newTokenObject as unknown as Prisma.InputJsonValue,
|
||||
},
|
||||
});
|
||||
},
|
||||
|
||||
@@ -10,7 +10,8 @@ import {
|
||||
import logger from "@calcom/lib/logger";
|
||||
import { getPiiFreeCalendarEvent } from "@calcom/lib/piiFreeData";
|
||||
import { safeStringify } from "@calcom/lib/safeStringify";
|
||||
import prisma from "@calcom/prisma";
|
||||
import { prisma } from "@calcom/prisma";
|
||||
import type { Prisma } from "@calcom/prisma/client";
|
||||
import { Frequency } from "@calcom/prisma/zod-utils";
|
||||
import type { CalendarEvent } from "@calcom/types/Calendar";
|
||||
import type { CredentialPayload } from "@calcom/types/Credential";
|
||||
@@ -316,7 +317,8 @@ const ZoomVideoApiAdapter = (credential: CredentialPayload): VideoApiAdapter =>
|
||||
id: credential.id,
|
||||
},
|
||||
data: {
|
||||
key: newTokenObject,
|
||||
// z.passthrough() is not allowed in Prisma, but we know this is trusted.
|
||||
key: newTokenObject as unknown as Prisma.InputJsonValue,
|
||||
},
|
||||
});
|
||||
},
|
||||
|
||||
@@ -36,7 +36,6 @@ export class FeaturesRepository implements IFeaturesRepository {
|
||||
|
||||
const features = await this.prismaClient.feature.findMany({
|
||||
orderBy: { slug: "asc" },
|
||||
cacheStrategy: { swr: 300, ttl: 300 },
|
||||
});
|
||||
|
||||
FeaturesRepository.featuresCache = {
|
||||
|
||||
@@ -12,7 +12,7 @@ import {
|
||||
} from "@calcom/features/insights/server/raw-data.schema";
|
||||
import { getInsightsBookingService } from "@calcom/lib/di/containers/InsightsBooking";
|
||||
import { getInsightsRoutingService } from "@calcom/lib/di/containers/InsightsRouting";
|
||||
import type { readonlyPrisma } from "@calcom/prisma";
|
||||
import type { PrismaClient } from "@calcom/prisma";
|
||||
import { BookingStatus } from "@calcom/prisma/enums";
|
||||
import authedProcedure from "@calcom/trpc/server/procedures/authedProcedure";
|
||||
import { router } from "@calcom/trpc/server/trpc";
|
||||
@@ -31,7 +31,7 @@ const UserBelongsToTeamInput = z.object({
|
||||
type BuildBaseWhereConditionCtxType = {
|
||||
userIsOwnerAdminOfParentTeam: boolean;
|
||||
userOrganizationId: number | null;
|
||||
insightsDb: typeof readonlyPrisma;
|
||||
insightsDb: PrismaClient;
|
||||
};
|
||||
|
||||
interface BuildBaseWhereConditionType {
|
||||
@@ -341,7 +341,7 @@ function createInsightsBookingService(
|
||||
}
|
||||
|
||||
function createInsightsRoutingService(
|
||||
ctx: { insightsDb: typeof readonlyPrisma; user: { id: number; organizationId: number | null } },
|
||||
ctx: { insightsDb: PrismaClient; user: { id: number; organizationId: number | null } },
|
||||
input: z.infer<typeof routingRepositoryBaseInputSchema>
|
||||
) {
|
||||
return getInsightsRoutingService({
|
||||
@@ -1037,7 +1037,7 @@ export async function getEventTypeList({
|
||||
isAll,
|
||||
user,
|
||||
}: {
|
||||
prisma: typeof readonlyPrisma;
|
||||
prisma: PrismaClient;
|
||||
teamId: number | null | undefined;
|
||||
userId: number | null | undefined;
|
||||
isAll: boolean | undefined;
|
||||
|
||||
@@ -1,16 +1,24 @@
|
||||
import type { Prisma } from "@prisma/client";
|
||||
|
||||
import type { FormResponse } from "@calcom/app-store/routing-forms/types/types";
|
||||
import { withReporting } from "@calcom/lib/sentryWrapper";
|
||||
import type { PrismaClient } from "@calcom/prisma";
|
||||
import { bookingMinimalSelect } from "@calcom/prisma";
|
||||
import type { Booking } from "@calcom/prisma/client";
|
||||
import { RRTimestampBasis } from "@calcom/prisma/enums";
|
||||
import { BookingStatus } from "@calcom/prisma/enums";
|
||||
import { RRTimestampBasis, BookingStatus } from "@calcom/prisma/enums";
|
||||
import { bookingMinimalSelect } from "@calcom/prisma/selects/booking";
|
||||
import { credentialForCalendarServiceSelect } from "@calcom/prisma/selects/credential";
|
||||
|
||||
import { UserRepository } from "./user";
|
||||
|
||||
export type FormResponse = Record<
|
||||
// Field ID
|
||||
string,
|
||||
{
|
||||
value: number | string | string[];
|
||||
label: string;
|
||||
identifier?: string;
|
||||
}
|
||||
>;
|
||||
|
||||
type TeamBookingsParamsBase = {
|
||||
user: { id: number; email: string };
|
||||
teamId: number;
|
||||
@@ -540,8 +548,10 @@ export class BookingRepository {
|
||||
},
|
||||
data: {
|
||||
location,
|
||||
metadata,
|
||||
...(responses && { responses }),
|
||||
// FIXME: metadata is untyped
|
||||
metadata: metadata as unknown as Prisma.InputJsonValue,
|
||||
// FIXME: responses is untyped
|
||||
...(responses && { responses: responses as unknown as Prisma.InputJsonValue }),
|
||||
...(iCalSequence !== undefined && { iCalSequence }),
|
||||
references: {
|
||||
create: referencesToCreate,
|
||||
@@ -681,9 +691,13 @@ export class BookingRepository {
|
||||
},
|
||||
},
|
||||
},
|
||||
// eslint-disable-next-line @calcom/eslint/no-prisma-include-true
|
||||
destinationCalendar: true,
|
||||
// eslint-disable-next-line @calcom/eslint/no-prisma-include-true
|
||||
payment: true,
|
||||
// eslint-disable-next-line @calcom/eslint/no-prisma-include-true
|
||||
references: true,
|
||||
// eslint-disable-next-line @calcom/eslint/no-prisma-include-true
|
||||
workflowReminders: true,
|
||||
},
|
||||
});
|
||||
@@ -825,9 +839,13 @@ export class BookingRepository {
|
||||
status: filterForUnconfirmed ? BookingStatus.PENDING : BookingStatus.ACCEPTED,
|
||||
},
|
||||
include: {
|
||||
// eslint-disable-next-line @calcom/eslint/no-prisma-include-true
|
||||
attendees: true,
|
||||
// eslint-disable-next-line @calcom/eslint/no-prisma-include-true
|
||||
references: true,
|
||||
// eslint-disable-next-line @calcom/eslint/no-prisma-include-true
|
||||
user: true,
|
||||
// eslint-disable-next-line @calcom/eslint/no-prisma-include-true
|
||||
payment: true,
|
||||
},
|
||||
});
|
||||
|
||||
@@ -97,7 +97,8 @@ export class DelegationCredentialRepository {
|
||||
id: data.organizationId,
|
||||
},
|
||||
},
|
||||
serviceAccountKey: encryptedKey,
|
||||
// z.passthrough() is not allowed in Prisma, but we know this is trusted.
|
||||
serviceAccountKey: encryptedKey as unknown as Prisma.InputJsonValue,
|
||||
},
|
||||
select: delegationCredentialSafeSelect,
|
||||
});
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { availabilityUserSelect, prisma, type PrismaTransaction, type PrismaClient } from "@calcom/prisma";
|
||||
import { availabilityUserSelect, prisma, type PrismaTransaction } from "@calcom/prisma";
|
||||
import { MembershipRole } from "@calcom/prisma/enums";
|
||||
import type { Prisma, Membership } from "@calcom/prisma/client";
|
||||
import type { Prisma, Membership, PrismaClient } from "@calcom/prisma/client";
|
||||
import { credentialForCalendarServiceSelect } from "@calcom/prisma/selects/credential";
|
||||
|
||||
import logger from "../../logger";
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { Prisma } from "@prisma/client";
|
||||
|
||||
import { prisma } from "@calcom/prisma";
|
||||
import { Prisma } from "@calcom/prisma/client";
|
||||
import type { TServiceAccountKeySchema } from "@calcom/prisma/zod-utils";
|
||||
import { serviceAccountKeySchema } from "@calcom/prisma/zod-utils";
|
||||
|
||||
@@ -42,7 +41,7 @@ export class WorkspacePlatformRepository {
|
||||
: _defaultServiceAccountKey;
|
||||
return await prisma.workspacePlatform.create({
|
||||
data: {
|
||||
defaultServiceAccountKey,
|
||||
defaultServiceAccountKey: defaultServiceAccountKey as unknown as Prisma.InputJsonValue,
|
||||
...rest,
|
||||
},
|
||||
select: safeWorkspacePlatformSelect,
|
||||
@@ -95,7 +94,10 @@ export class WorkspacePlatformRepository {
|
||||
}) {
|
||||
return await prisma.workspacePlatform.update({
|
||||
where: { id },
|
||||
data,
|
||||
data: {
|
||||
...data,
|
||||
defaultServiceAccountKey: data.defaultServiceAccountKey as unknown as Prisma.InputJsonValue,
|
||||
},
|
||||
select: safeWorkspacePlatformSelect,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ import {
|
||||
isNumberFilterValue,
|
||||
} from "@calcom/features/data-table/lib/utils";
|
||||
import type { DateRange } from "@calcom/features/insights/server/insightsDateUtils";
|
||||
import type { readonlyPrisma } from "@calcom/prisma";
|
||||
import type { PrismaClient } from "@calcom/prisma";
|
||||
import { MembershipRole } from "@calcom/prisma/enums";
|
||||
|
||||
import { MembershipRepository } from "../repository/membership";
|
||||
@@ -142,7 +142,7 @@ const NOTHING_CONDITION = Prisma.sql`1=0`;
|
||||
const bookingDataKeys = new Set(Object.keys(bookingDataSchema.shape));
|
||||
|
||||
export class InsightsBookingBaseService {
|
||||
private prisma: typeof readonlyPrisma;
|
||||
private prisma: PrismaClient;
|
||||
private options: InsightsBookingServiceOptions | null;
|
||||
private filters: InsightsBookingServiceFilterOptions | null;
|
||||
private cachedAuthConditions?: Prisma.Sql;
|
||||
@@ -153,7 +153,7 @@ export class InsightsBookingBaseService {
|
||||
options,
|
||||
filters,
|
||||
}: {
|
||||
prisma: typeof readonlyPrisma;
|
||||
prisma: PrismaClient;
|
||||
options: InsightsBookingServicePublicOptions;
|
||||
filters?: InsightsBookingServiceFilterOptions;
|
||||
}) {
|
||||
|
||||
@@ -12,7 +12,7 @@ import {
|
||||
isSingleSelectFilterValue,
|
||||
} from "@calcom/features/data-table/lib/utils";
|
||||
import type { DateRange } from "@calcom/features/insights/server/insightsDateUtils";
|
||||
import type { readonlyPrisma } from "@calcom/prisma";
|
||||
import type { PrismaClient } from "@calcom/prisma";
|
||||
import type { BookingStatus } from "@calcom/prisma/enums";
|
||||
import { MembershipRole } from "@calcom/prisma/enums";
|
||||
|
||||
@@ -136,7 +136,7 @@ type GetConditionsOptions = {
|
||||
};
|
||||
|
||||
export class InsightsRoutingBaseService {
|
||||
private prisma: typeof readonlyPrisma;
|
||||
private prisma: PrismaClient;
|
||||
private options: InsightsRoutingServiceOptions | null;
|
||||
private filters: InsightsRoutingServiceFilterOptions;
|
||||
|
||||
@@ -145,7 +145,7 @@ export class InsightsRoutingBaseService {
|
||||
options,
|
||||
filters,
|
||||
}: {
|
||||
prisma: typeof readonlyPrisma;
|
||||
prisma: PrismaClient;
|
||||
options: InsightsRoutingServicePublicOptions;
|
||||
filters: InsightsRoutingServiceFilterOptions;
|
||||
}) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { readonlyPrisma } from "@calcom/prisma";
|
||||
import type { PrismaClient } from "@calcom/prisma";
|
||||
|
||||
import {
|
||||
InsightsRoutingBaseService,
|
||||
@@ -7,7 +7,7 @@ import {
|
||||
} from "./InsightsRoutingBaseService";
|
||||
|
||||
export interface IInsightsRoutingService {
|
||||
prisma: typeof readonlyPrisma;
|
||||
prisma: PrismaClient;
|
||||
}
|
||||
|
||||
export class InsightsRoutingService {
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import { Prisma } from "@prisma/client";
|
||||
import type { PrismaClient as PrismaClientWithoutExtensions } from "@prisma/client";
|
||||
import type { PrismaClient } from "@prisma/client";
|
||||
import { waitUntil } from "@vercel/functions";
|
||||
|
||||
import { UsageEvent, LicenseKeySingleton } from "@calcom/ee/common/server/LicenseKeyService";
|
||||
import { DeploymentRepository } from "@calcom/lib/server/repository/deployment";
|
||||
|
||||
async function incrementUsage(prismaClient: PrismaClientWithoutExtensions, event?: UsageEvent) {
|
||||
async function incrementUsage(prismaClient: PrismaClient, event?: UsageEvent) {
|
||||
const deploymentRepo = new DeploymentRepository(prismaClient);
|
||||
try {
|
||||
const licenseKeyService = await LicenseKeySingleton.getInstance(deploymentRepo);
|
||||
@@ -15,7 +15,7 @@ async function incrementUsage(prismaClient: PrismaClientWithoutExtensions, event
|
||||
}
|
||||
}
|
||||
|
||||
export function usageTrackingExtention(prismaClient: PrismaClientWithoutExtensions) {
|
||||
export function usageTrackingExtention(prismaClient: PrismaClient) {
|
||||
return Prisma.defineExtension({
|
||||
query: {
|
||||
booking: {
|
||||
|
||||
+20
-25
@@ -1,6 +1,5 @@
|
||||
import type { Prisma } from "@prisma/client";
|
||||
import { PrismaClient as PrismaClientWithoutExtension } from "@prisma/client";
|
||||
import { withAccelerate } from "@prisma/extension-accelerate";
|
||||
import { PrismaClient } from "@prisma/client";
|
||||
|
||||
import { bookingIdempotencyKeyExtension } from "./extensions/booking-idempotency-key";
|
||||
import { disallowUndefinedDeleteUpdateManyExtension } from "./extensions/disallow-undefined-delete-update-many";
|
||||
@@ -12,8 +11,7 @@ import { bookingReferenceMiddleware } from "./middleware";
|
||||
const prismaOptions: Prisma.PrismaClientOptions = {};
|
||||
|
||||
const globalForPrisma = global as unknown as {
|
||||
prismaWithoutClientExtensions: PrismaClientWithoutExtension;
|
||||
prismaWithClientExtensions: PrismaClientWithExtensions;
|
||||
baseClient: PrismaClient;
|
||||
};
|
||||
|
||||
const loggerLevel = parseInt(process.env.NEXT_PUBLIC_LOGGER_LEVEL ?? "", 10);
|
||||
@@ -37,34 +35,32 @@ if (!isNaN(loggerLevel)) {
|
||||
}
|
||||
}
|
||||
|
||||
// Prevents flooding with idle connections
|
||||
const prismaWithoutClientExtensions =
|
||||
globalForPrisma.prismaWithoutClientExtensions || new PrismaClientWithoutExtension(prismaOptions);
|
||||
const baseClient =
|
||||
globalForPrisma.baseClient || new PrismaClient(prismaOptions);
|
||||
|
||||
export const customPrisma = (options?: Prisma.PrismaClientOptions) =>
|
||||
new PrismaClientWithoutExtension({ ...prismaOptions, ...options })
|
||||
.$extends(usageTrackingExtention(prismaWithoutClientExtensions))
|
||||
new PrismaClient({ ...prismaOptions, ...options })
|
||||
.$extends(usageTrackingExtention(baseClient))
|
||||
.$extends(excludeLockedUsersExtension())
|
||||
.$extends(excludePendingPaymentsExtension())
|
||||
.$extends(bookingIdempotencyKeyExtension())
|
||||
.$extends(disallowUndefinedDeleteUpdateManyExtension())
|
||||
.$extends(withAccelerate());
|
||||
.$extends(disallowUndefinedDeleteUpdateManyExtension()) as unknown as PrismaClient;
|
||||
|
||||
// If any changed on middleware server restart is required
|
||||
// TODO: Migrate it to $extends
|
||||
bookingReferenceMiddleware(prismaWithoutClientExtensions);
|
||||
bookingReferenceMiddleware(baseClient);
|
||||
|
||||
// FIXME: Due to some reason, there are types failing in certain places due to the $extends. Fix it and then enable it
|
||||
// Specifically we get errors like `Type 'string | Date | null | undefined' is not assignable to type 'Exact<string | Date | null | undefined, string | Date | null | undefined>'`
|
||||
const prismaWithClientExtensions = prismaWithoutClientExtensions
|
||||
.$extends(usageTrackingExtention(prismaWithoutClientExtensions))
|
||||
|
||||
// Explanation why we cast as PrismaClient. When we leave Prisma to its devices it tries to infer logic based on the extensions, but this is not a simple extends.
|
||||
// this makes the PrismaClient export type-hint impossible and it also is a massive hit on Prisma type hinting performance.
|
||||
export const prisma: PrismaClient = baseClient
|
||||
.$extends(usageTrackingExtention(baseClient))
|
||||
.$extends(excludeLockedUsersExtension())
|
||||
.$extends(excludePendingPaymentsExtension())
|
||||
.$extends(bookingIdempotencyKeyExtension())
|
||||
.$extends(disallowUndefinedDeleteUpdateManyExtension())
|
||||
.$extends(withAccelerate());
|
||||
|
||||
export const prisma = globalForPrisma.prismaWithClientExtensions || prismaWithClientExtensions;
|
||||
.$extends(disallowUndefinedDeleteUpdateManyExtension()) as unknown as PrismaClient;
|
||||
|
||||
// This prisma instance is meant to be used only for READ operations.
|
||||
// If self hosting, feel free to leave INSIGHTS_DATABASE_URL as empty and `readonlyPrisma` will default to `prisma`.
|
||||
@@ -75,24 +71,23 @@ export const readonlyPrisma = process.env.INSIGHTS_DATABASE_URL
|
||||
: prisma;
|
||||
|
||||
if (process.env.NODE_ENV !== "production") {
|
||||
globalForPrisma.prismaWithoutClientExtensions = prismaWithoutClientExtensions;
|
||||
globalForPrisma.prismaWithClientExtensions = prisma;
|
||||
globalForPrisma.baseClient = baseClient;
|
||||
}
|
||||
|
||||
type PrismaClientWithExtensions = typeof prismaWithClientExtensions;
|
||||
export type PrismaClient = PrismaClientWithExtensions;
|
||||
|
||||
type OmitPrismaClient = Omit<
|
||||
PrismaClient,
|
||||
"$connect" | "$disconnect" | "$on" | "$transaction" | "$use" | "$extends"
|
||||
>;
|
||||
|
||||
// we cant pass tx to functions as types miss match since we have a custom prisma client https://github.com/prisma/prisma/discussions/20924#discussioncomment-10077649
|
||||
export type PrismaTransaction = OmitPrismaClient;
|
||||
export type {
|
||||
OmitPrismaClient as PrismaTransaction,
|
||||
// we re-export the native PrismaClient type for backwards-compatibility.
|
||||
PrismaClient
|
||||
};
|
||||
|
||||
/**
|
||||
* @deprecated Use named export `prisma` instead
|
||||
*/
|
||||
export default prisma;
|
||||
|
||||
export * from "./selects";
|
||||
|
||||
Reference in New Issue
Block a user