Skip to content

Commit 0e3696f

Browse files
chore: dedupe yarn.lock to remove duplicate package versions (calcom#26068)
* chore: dedupe yarn.lock to remove duplicate package versions - Consolidated 762 duplicate package versions - Reduced yarn.lock from 51,211 lines (1.7MB) to 44,471 lines (1.5MB) - Removed 7,071 lines (~200KB) of redundant dependency entries - Major packages deduplicated include: resolve, semver, type-fest, commander, glob, lru-cache, dotenv, @babel/* packages, typescript, tslib, postcss, and many more Co-Authored-By: keith@cal.com <keithwillcode@gmail.com> * fix: resolve type errors in managed event types and react-select components - Add Zod-compatible versions of allManagedEventTypeProps and unlockedManagedEventTypeProps that only include scalar fields (excludes Prisma relation fields) - Update handleChildrenEventTypes.ts and queries.ts to use the new Zod-compatible props - Fix react-select CSS type errors in Select.tsx files by using Object.assign instead of spread operator to avoid TypeScript type inference issues - Fix lint warning in updateNewTeamMemberEventTypes by using if statement Co-Authored-By: keith@cal.com <keithwillcode@gmail.com> * fix: derive eventType parameter type from actual query result Use Awaited<ReturnType<typeof getEventTypesToAddNewMembers>>[number] to ensure type safety at call sites, avoiding Prisma type namespace mismatches. Co-Authored-By: keith@cal.com <keithwillcode@gmail.com> * fix: disable turbo cache for @calcom/trpc#build to prevent stale type errors Co-Authored-By: keith@cal.com <keithwillcode@gmail.com> * fix: correct field names in API v1 validation schemas - Remove timeZone from booking schema (field doesn't exist on Booking model) - Remove bookingId from destination-calendar schema (field doesn't exist, only booking relation) - Change avatar to avatarUrl in user schema (correct field name) Co-Authored-By: keith@cal.com <keithwillcode@gmail.com> * fix: use Object.assign for react-select styles to fix TypeScript spread type errors The spread operator causes TypeScript to compute an incompatible type with CSSObjectWithLabel due to the accentColor property. Using Object.assign preserves the correct type inference. Fixed files: - FormEdit.tsx - DestinationCalendarSelector.tsx (features and platform) - TimezoneSelect.tsx - ApiKeyDialogForm.tsx - Select.tsx (features/form) - WebhookForm.tsx Also fixed pre-existing lint warnings: - Constant truthiness in label assignment - Unused variant parameter Co-Authored-By: keith@cal.com <keithwillcode@gmail.com> * fix: remove extra fields from allManagedEventTypePropsForZod to match original behavior The Zod-compatible version should only include scalar fields that were in the original allManagedEventTypeProps. Removed instantMeetingScheduleId, profileId, rrSegmentQueryValue, and assignRRMembersUsingSegment which were incorrectly added and caused test failures by including extra fields in Prisma update payloads. Co-Authored-By: keith@cal.com <keithwillcode@gmail.com> * fix: remove access to fields not in Zod schema - Remove unnecessary destructuring of profileId and instantMeetingScheduleId from managedEventTypeValues in handleChildrenEventTypes.ts (these fields are already sourced from other variables) - Set rrSegmentQueryValue to undefined directly in queries.ts instead of accessing it from managedEventTypeValues (not applicable for managed children) Co-Authored-By: keith@cal.com <keithwillcode@gmail.com> * fix: add name property to mock credentials and revert turbo cache change - Add name property to MockCredential type and factory function in InstallAppButtonChild.test.tsx to match expected credentials type - Revert turbo cache disable for @calcom/trpc#build (per review comment) Co-Authored-By: keith@cal.com <keithwillcode@gmail.com> * fix: revert API v1 validation changes and restore eslint comment - Revert API v1 validation changes (booking.ts, destination-calendar.ts, user.ts) since API v1 is deprecated and these could be breaking changes - Restore eslint-disable comment for @typescript-eslint/no-empty-function in Select.tsx that was accidentally removed Co-Authored-By: keith@cal.com <keithwillcode@gmail.com> * fix: add inputs to @calcom/trpc#build to properly invalidate cache Co-Authored-By: keith@cal.com <keithwillcode@gmail.com> * fix: properly fix API v1 validation schemas for stricter zod 3.25.76 The yarn dedupe upgraded zod from 3.22.4 to 3.25.76, which has stricter .pick() typing that now properly rejects picking non-existent fields. Changes: - user.ts: Pick avatarUrl (actual Prisma field) and extend with avatar for API v1 backward compatibility - booking.ts: Remove timeZone from pick (not a field on Booking model, only exists in nested attendees/user objects) - destination-calendar.ts: Remove bookingId from pick (not a field on DestinationCalendar model) Co-Authored-By: keith@cal.com <keithwillcode@gmail.com> * fix: remove turbo.json inputs for @calcom/trpc#build to use cached artifacts Co-Authored-By: keith@cal.com <keithwillcode@gmail.com> * fix: use robust selector for react-select option in routing forms E2E test The previous selector used .nth(1) which assumed the email text appeared exactly twice in the DOM in a specific order. This broke when react-select was upgraded from 5.7.2 to 5.8.0 via yarn dedupe. The new approach waits for the react-select listbox to appear and clicks the option within it, which is more robust against DOM structure changes. Co-Authored-By: keith@cal.com <keithwillcode@gmail.com> --------- Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
1 parent f846126 commit 0e3696f

18 files changed

Lines changed: 546 additions & 7219 deletions

File tree

apps/api/v1/lib/validations/booking.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ export const schemaBookingReadPublic = Booking.extend({
128128
title: true,
129129
startTime: true,
130130
endTime: true,
131-
timeZone: true,
131+
// Note: timeZone is not a field on Booking model - it's in nested attendees/user objects
132132
attendees: true,
133133
user: true,
134134
eventType: true,

apps/api/v1/lib/validations/destination-calendar.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@ import { z } from "zod";
22

33
import { DestinationCalendarSchema } from "@calcom/prisma/zod/modelSchema/DestinationCalendarSchema";
44

5+
// Note: bookingId is not a field on DestinationCalendar model in Prisma schema
56
export const schemaDestinationCalendarBaseBodyParams = DestinationCalendarSchema.pick({
67
integration: true,
78
externalId: true,
89
eventTypeId: true,
9-
bookingId: true,
1010
userId: true,
1111
}).partial();
1212

@@ -38,11 +38,11 @@ export const schemaDestinationCalendarEditBodyParams = schemaDestinationCalendar
3838
schemaDestinationCalendarEditParams
3939
);
4040

41+
// Note: bookingId is not a field on DestinationCalendar model in Prisma schema
4142
export const schemaDestinationCalendarReadPublic = DestinationCalendarSchema.pick({
4243
id: true,
4344
integration: true,
4445
externalId: true,
4546
eventTypeId: true,
46-
bookingId: true,
4747
userId: true,
4848
});

apps/api/v1/lib/validations/user.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,14 +151,15 @@ export const schemaUserCreateBodyParams = schemaUserBaseBodyParams
151151
.strict();
152152

153153
// @note: These are the values that are always returned when reading a user
154+
// Note: We pick avatarUrl from the Prisma schema and extend with avatar for API v1 backward compatibility
154155
export const schemaUserReadPublic = UserSchema.pick({
155156
id: true,
156157
username: true,
157158
name: true,
158159
email: true,
159160
emailVerified: true,
160161
bio: true,
161-
avatar: true,
162+
avatarUrl: true,
162163
timeZone: true,
163164
weekStart: true,
164165
endTime: true,
@@ -176,6 +177,9 @@ export const schemaUserReadPublic = UserSchema.pick({
176177
verified: true,
177178
invitedTo: true,
178179
role: true,
180+
}).extend({
181+
// API v1 backward compatibility: expose avatarUrl as avatar
182+
avatar: UserSchema.shape.avatarUrl,
179183
});
180184

181185
export const schemaUsersReadPublic = z.array(schemaUserReadPublic);

apps/web/app/(use-page-wrapper)/apps/routing-forms/[...pages]/FormEdit.tsx

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -162,14 +162,14 @@ function Field({
162162
<SelectField
163163
maxMenuHeight={200}
164164
styles={{
165-
singleValue: (baseStyles) => ({
166-
...baseStyles,
167-
fontSize: "14px",
168-
}),
169-
option: (baseStyles) => ({
170-
...baseStyles,
171-
fontSize: "14px",
172-
}),
165+
singleValue: (baseStyles) =>
166+
Object.assign({}, baseStyles, {
167+
fontSize: "14px",
168+
}),
169+
option: (baseStyles) =>
170+
Object.assign({}, baseStyles, {
171+
fontSize: "14px",
172+
}),
173173
}}
174174
label="Type"
175175
isDisabled={!!router}

apps/web/components/apps/InstallAppButtonChild.test.tsx

Lines changed: 10 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -7,35 +7,26 @@ import { InstallAppButtonChild } from "./InstallAppButtonChild";
77
type MockCredential = {
88
id: number;
99
delegatedToId: string;
10-
userId: number;
11-
user: { email: string };
10+
userId: number | null;
11+
user: { email: string; name: string | null } | null;
1212
key: { access_token: string };
13-
invalid: boolean;
14-
teamId: null;
15-
team: null;
16-
delegationCredentialId: string;
17-
type:
18-
| `${string}_calendar`
19-
| `${string}_messaging`
20-
| `${string}_payment`
21-
| `${string}_video`
22-
| `${string}_other`
23-
| `${string}_automation`
24-
| `${string}_analytics`
25-
| `${string}_crm`
26-
| `${string}_other_calendar`;
27-
appId: string;
13+
invalid: boolean | null;
14+
teamId: number | null;
15+
team: { name: string } | null;
16+
delegationCredentialId: string | null;
17+
type: string;
18+
appId: string | null;
2819
};
2920

3021
// Factory function to create mock credentials
3122
const createMockCredential = (overrides: Partial<MockCredential> = {}): MockCredential => ({
3223
id: 1,
33-
type: "google_calendar" as const,
24+
type: "google_calendar",
3425
userId: 1,
3526
delegatedToId: "delegation-123",
3627
teamId: null,
3728
team: null,
38-
user: { email: "test@example.com" },
29+
user: { email: "test@example.com", name: "Test User" },
3930
key: { access_token: "mock_token_123" },
4031
delegationCredentialId: "delegation-123",
4132
appId: "google-calendar",

packages/app-store/routing-forms/playwright/tests/basic.e2e.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -910,7 +910,11 @@ test.describe("Routing Forms", () => {
910910
await page.goto(`apps/routing-forms/form-edit/${formId}`);
911911
await page.getByTestId("settings-button").click();
912912
await page.click('[data-testid="routing-form-select-members"]');
913-
await page.getByText(text).nth(1).click();
913+
// Wait for the react-select menu to appear and click the option within it
914+
// This is more robust than using .nth(1) which assumes specific DOM structure
915+
const menuListbox = page.locator('[id$="-listbox"]');
916+
await menuListbox.waitFor({ state: "visible" });
917+
await menuListbox.getByText(text).click();
914918
await page.getByTestId("settings-slider-over-done").click();
915919
await saveCurrentForm(page);
916920
};

packages/features/calendars/DestinationCalendarSelector.tsx

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ const DestinationCalendarSelector = ({
9999

100100
setSelectedOption({
101101
value: `${selected.integration}:${selected.externalId}`,
102-
label: `${selected.name} ` || "",
102+
label: selected.name ? `${selected.name} ` : "",
103103
subtitle: `(${selectedIntegration?.integration.title?.replace(/calendar/i, "")} - ${
104104
selectedIntegration?.primary?.name
105105
})`,
@@ -148,17 +148,16 @@ const DestinationCalendarSelector = ({
148148
}
149149
options={options}
150150
styles={{
151-
placeholder: (styles) => ({ ...styles, ...content(hidePlaceholder) }),
152-
singleValue: (styles) => ({ ...styles, ...content(hidePlaceholder) }),
153-
control: (defaultStyles) => {
154-
return {
155-
...defaultStyles,
156-
"@media only screen and (min-width: 640px)": {
157-
...(defaultStyles["@media only screen and (min-width: 640px)"] as object),
158-
maxWidth,
159-
},
160-
};
161-
},
151+
placeholder: (styles) => Object.assign({}, styles, content(hidePlaceholder)),
152+
singleValue: (styles) => Object.assign({}, styles, content(hidePlaceholder)),
153+
control: (defaultStyles) =>
154+
Object.assign({}, defaultStyles, {
155+
"@media only screen and (min-width: 640px)": Object.assign(
156+
{},
157+
defaultStyles["@media only screen and (min-width: 640px)"] as object,
158+
{ maxWidth }
159+
),
160+
}),
162161
}}
163162
isSearchable={false}
164163
className={classNames(

packages/features/components/timezone-select/TimezoneSelect.tsx

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ export function TimezoneSelectComponent({
7575
classNames: timezoneClassNames,
7676
timezoneSelectCustomClassname,
7777
components,
78-
variant = "default",
78+
variant: _variant = "default",
7979
isPending,
8080
value,
8181
size = "md",
@@ -116,15 +116,15 @@ export function TimezoneSelectComponent({
116116
...(isWebTimezoneSelect ? addTimezonesToDropdown(additionalTimezones) : {}),
117117
}}
118118
styles={{
119-
control: (base) => ({
120-
...base,
121-
minHeight: size === "sm" ? "28px" : "36px",
122-
height: grow ? "h-auto " : size === "sm" ? "28px" : "36px",
123-
}),
124-
menuList: (base) => ({
125-
...base,
126-
height: grow ? "h-auto " : size === "sm" ? "200px" : "180px",
127-
}),
119+
control: (base) =>
120+
Object.assign({}, base, {
121+
minHeight: size === "sm" ? "28px" : "36px",
122+
height: grow ? "h-auto " : size === "sm" ? "28px" : "36px",
123+
}),
124+
menuList: (base) =>
125+
Object.assign({}, base, {
126+
height: grow ? "h-auto " : size === "sm" ? "200px" : "180px",
127+
}),
128128
}}
129129
onInputChange={handleInputChange}
130130
{...props}

packages/features/ee/api-keys/components/ApiKeyDialogForm.tsx

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -217,14 +217,14 @@ export default function ApiKeyDialogForm({
217217
return (
218218
<SelectField
219219
styles={{
220-
singleValue: (baseStyles) => ({
221-
...baseStyles,
222-
fontSize: "14px",
223-
}),
224-
option: (baseStyles) => ({
225-
...baseStyles,
226-
fontSize: "14px",
227-
}),
220+
singleValue: (baseStyles) =>
221+
Object.assign({}, baseStyles, {
222+
fontSize: "14px",
223+
}),
224+
option: (baseStyles) =>
225+
Object.assign({}, baseStyles, {
226+
fontSize: "14px",
227+
}),
228228
}}
229229
isDisabled={watchNeverExpires || !!defaultValues}
230230
containerClassName="data-testid-field-type"

packages/features/ee/managed-event-types/lib/handleChildrenEventTypes.ts

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,11 @@ import { getTranslation } from "@calcom/lib/server/i18n";
66
import type { PrismaClient } from "@calcom/prisma";
77
import type { Prisma } from "@calcom/prisma/client";
88
import { SchedulingType } from "@calcom/prisma/enums";
9-
import { allManagedEventTypeProps, unlockedManagedEventTypeProps } from "@calcom/prisma/zod-utils";
9+
import {
10+
allManagedEventTypeProps,
11+
allManagedEventTypePropsForZod,
12+
unlockedManagedEventTypePropsForZod,
13+
} from "@calcom/prisma/zod-utils";
1014
import { EventTypeSchema } from "@calcom/prisma/zod/modelSchema/EventTypeSchema";
1115

1216
interface handleChildrenEventTypesProps {
@@ -157,9 +161,9 @@ export default async function handleChildrenEventTypes({
157161
bookingFields: EventTypeSchema.shape.bookingFields.nullish(),
158162
});
159163

160-
const allManagedEventTypePropsZod = _ManagedEventTypeModel.pick(allManagedEventTypeProps);
164+
const allManagedEventTypePropsZod = _ManagedEventTypeModel.pick(allManagedEventTypePropsForZod);
161165
const managedEventTypeValues = allManagedEventTypePropsZod
162-
.omit(unlockedManagedEventTypeProps)
166+
.omit(unlockedManagedEventTypePropsForZod)
163167
.parse(eventType);
164168

165169
// Check we are certainly dealing with a managed event type through its metadata
@@ -170,7 +174,7 @@ export default async function handleChildrenEventTypes({
170174

171175
// Define the values for unlocked properties to use on creation, not updation
172176
const unlockedEventTypeValues = allManagedEventTypePropsZod
173-
.pick(unlockedManagedEventTypeProps)
177+
.pick(unlockedManagedEventTypePropsForZod)
174178
.parse(eventType);
175179
// Calculate if there are new/existent/deleted children users for which the event type needs to be created/updated/deleted
176180
const previousUserIds = oldEventType.children?.flatMap((ch) => ch.userId ?? []);
@@ -197,17 +201,10 @@ export default async function handleChildrenEventTypes({
197201

198202
// Create event types for new users added
199203
const eventTypesToCreateData = newUserIds.map((userId) => {
200-
// Exclude profileId and instantMeetingScheduleId from managed values to avoid duplication
201-
const {
202-
profileId: _,
203-
instantMeetingScheduleId: __,
204-
...managedValuesWithoutExplicit
205-
} = managedEventTypeValues;
206-
207204
return {
208205
instantMeetingScheduleId: eventType.instantMeetingScheduleId ?? undefined,
209206
profileId: profileId ?? null,
210-
...managedValuesWithoutExplicit,
207+
...managedEventTypeValues,
211208
...{
212209
...unlockedEventTypeValues,
213210
// pre-genned as allowed null

0 commit comments

Comments
 (0)