feat: added Ability to set organizer's default app as a valid input location in api/v2 (#19549)
* feat: added Ability to set organizer's default app as a valid input location in api/v2 * only allow organizers default for team events * fixed for atoms and added unit and e2e tests * Update organizations-event-types.e2e-spec.ts * Update transformApiEventTypeForAtom.ts * published platform-libraries@0.0.124 --------- Co-authored-by: Peer Richelsen <peeroke@gmail.com>
This commit is contained in:
co-authored by
Peer Richelsen
parent
615ef93572
commit
6244b5a2c0
@@ -30,7 +30,7 @@
|
||||
"@axiomhq/winston": "^1.2.0",
|
||||
"@calcom/platform-constants": "*",
|
||||
"@calcom/platform-enums": "*",
|
||||
"@calcom/platform-libraries": "npm:@calcom/platform-libraries@0.0.123",
|
||||
"@calcom/platform-libraries": "npm:@calcom/platform-libraries@0.0.124",
|
||||
"@calcom/platform-libraries-0.0.2": "npm:@calcom/platform-libraries@0.0.2",
|
||||
"@calcom/platform-types": "*",
|
||||
"@calcom/platform-utils": "*",
|
||||
|
||||
+3
@@ -187,6 +187,9 @@ describe("Organizations Event Types Endpoints", () => {
|
||||
type: "integration",
|
||||
integration: "cal-video",
|
||||
},
|
||||
{
|
||||
type: "organizersDefaultApp",
|
||||
},
|
||||
],
|
||||
schedulingType: "COLLECTIVE",
|
||||
hosts: [
|
||||
|
||||
@@ -4,6 +4,7 @@ import { TeamsRepository } from "@/modules/teams/teams/teams.repository";
|
||||
import { UsersRepository } from "@/modules/users/users.repository";
|
||||
import { BadRequestException, Injectable, NotFoundException } from "@nestjs/common";
|
||||
|
||||
import { transformTeamLocationsApiToInternal } from "@calcom/platform-libraries";
|
||||
import {
|
||||
CreateTeamEventTypeInput_2024_06_14,
|
||||
UpdateTeamEventTypeInput_2024_06_14,
|
||||
@@ -81,9 +82,17 @@ export class InputOrganizationsEventTypesService {
|
||||
teamId: number,
|
||||
inputEventType: CreateTeamEventTypeInput_2024_06_14
|
||||
) {
|
||||
const { hosts, assignAllTeamMembers, ...rest } = inputEventType;
|
||||
const { hosts, assignAllTeamMembers, locations, ...rest } = inputEventType;
|
||||
|
||||
const eventType = this.inputEventTypesService.transformInputCreateEventType(rest);
|
||||
|
||||
const defaultLocations: CreateTeamEventTypeInput_2024_06_14["locations"] = [
|
||||
{
|
||||
type: "integration",
|
||||
integration: "cal-video",
|
||||
},
|
||||
];
|
||||
|
||||
const children = await this.getChildEventTypesForManagedEventType(null, inputEventType, teamId);
|
||||
|
||||
const metadata =
|
||||
@@ -100,6 +109,7 @@ export class InputOrganizationsEventTypesService {
|
||||
: this.transformInputHosts(hosts, inputEventType.schedulingType)
|
||||
: undefined,
|
||||
assignAllTeamMembers,
|
||||
locations: this.transformInputTeamLocations(locations || defaultLocations),
|
||||
metadata,
|
||||
children,
|
||||
};
|
||||
@@ -112,7 +122,7 @@ export class InputOrganizationsEventTypesService {
|
||||
teamId: number,
|
||||
inputEventType: UpdateTeamEventTypeInput_2024_06_14
|
||||
) {
|
||||
const { hosts, assignAllTeamMembers, ...rest } = inputEventType;
|
||||
const { hosts, assignAllTeamMembers, locations, ...rest } = inputEventType;
|
||||
|
||||
const eventType = await this.inputEventTypesService.transformInputUpdateEventType(rest, eventTypeId);
|
||||
const dbEventType = await this.teamsEventTypesRepository.getTeamEventType(teamId, eventTypeId);
|
||||
@@ -132,6 +142,7 @@ export class InputOrganizationsEventTypesService {
|
||||
: undefined,
|
||||
assignAllTeamMembers,
|
||||
children,
|
||||
locations: locations ? this.transformInputTeamLocations(locations) : undefined,
|
||||
};
|
||||
|
||||
return teamEventType;
|
||||
@@ -179,6 +190,10 @@ export class InputOrganizationsEventTypesService {
|
||||
return eventType?.children.map((child) => child.userId).filter((id) => !!id) as number[];
|
||||
}
|
||||
|
||||
transformInputTeamLocations(inputLocations: CreateTeamEventTypeInput_2024_06_14["locations"]) {
|
||||
return transformTeamLocationsApiToInternal(inputLocations);
|
||||
}
|
||||
|
||||
async getOwnersForManagedEventType(userIds: number[]) {
|
||||
const users = await this.usersRepository.findByIdsWithEventTypes(userIds);
|
||||
|
||||
|
||||
@@ -9095,6 +9095,19 @@
|
||||
"slug"
|
||||
]
|
||||
},
|
||||
"InputOrganizersDefaultApp_2024_06_14": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"type": {
|
||||
"type": "string",
|
||||
"example": "organizersDefaultApp",
|
||||
"description": "only allowed value for type is `organizersDefaultApp`"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"type"
|
||||
]
|
||||
},
|
||||
"BookerLayouts_2024_06_14": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
@@ -9190,35 +9203,6 @@
|
||||
"type": "string",
|
||||
"example": "Discover the culinary wonders of the Argentina by making the best flan ever!"
|
||||
},
|
||||
"locations": {
|
||||
"type": "array",
|
||||
"description": "Locations where the event will take place. If not provided, cal video link will be used as the location.",
|
||||
"items": {
|
||||
"oneOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/InputAddressLocation_2024_06_14"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/InputLinkLocation_2024_06_14"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/InputIntegrationLocation_2024_06_14"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/InputPhoneLocation_2024_06_14"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/InputAttendeeAddressLocation_2024_06_14"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/InputAttendeePhoneLocation_2024_06_14"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/InputAttendeeDefinedLocation_2024_06_14"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"bookingFields": {
|
||||
"type": "array",
|
||||
"description": "Custom fields that can be added to the booking form when the event is booked by someone. By default booking form has name and email field.",
|
||||
@@ -9423,6 +9407,35 @@
|
||||
"type": "string",
|
||||
"description": "A valid URL where the booker will redirect to, once the booking is completed successfully",
|
||||
"example": "https://masterchief.com/argentina/flan/video/9129412"
|
||||
},
|
||||
"locations": {
|
||||
"type": "array",
|
||||
"description": "Locations where the event will take place. If not provided, cal video link will be used as the location.",
|
||||
"items": {
|
||||
"oneOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/InputAddressLocation_2024_06_14"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/InputLinkLocation_2024_06_14"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/InputIntegrationLocation_2024_06_14"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/InputPhoneLocation_2024_06_14"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/InputAttendeeAddressLocation_2024_06_14"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/InputAttendeePhoneLocation_2024_06_14"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/InputAttendeeDefinedLocation_2024_06_14"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
@@ -9443,7 +9456,8 @@
|
||||
"phone",
|
||||
"attendeeAddress",
|
||||
"attendeePhone",
|
||||
"attendeeDefined"
|
||||
"attendeeDefined",
|
||||
"organizersDefaultApp"
|
||||
],
|
||||
"example": "address",
|
||||
"description": "only allowed value for type is `address`"
|
||||
@@ -9474,7 +9488,8 @@
|
||||
"phone",
|
||||
"attendeeAddress",
|
||||
"attendeePhone",
|
||||
"attendeeDefined"
|
||||
"attendeeDefined",
|
||||
"organizersDefaultApp"
|
||||
],
|
||||
"example": "link",
|
||||
"description": "only allowed value for type is `link`"
|
||||
@@ -9506,6 +9521,7 @@
|
||||
"attendeeAddress",
|
||||
"attendeePhone",
|
||||
"attendeeDefined",
|
||||
"organizersDefaultApp",
|
||||
"conferencing",
|
||||
"unknown"
|
||||
],
|
||||
@@ -9575,7 +9591,8 @@
|
||||
"phone",
|
||||
"attendeeAddress",
|
||||
"attendeePhone",
|
||||
"attendeeDefined"
|
||||
"attendeeDefined",
|
||||
"organizersDefaultApp"
|
||||
],
|
||||
"example": "phone",
|
||||
"description": "only allowed value for type is `phone`"
|
||||
@@ -9594,7 +9611,7 @@
|
||||
"public"
|
||||
]
|
||||
},
|
||||
"OutputConferencingLocation_2024_06_14": {
|
||||
"OutputOrganizersDefaultAppLocation_2024_06_14": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"type": {
|
||||
@@ -9607,11 +9624,12 @@
|
||||
"attendeeAddress",
|
||||
"attendeePhone",
|
||||
"attendeeDefined",
|
||||
"organizersDefaultApp",
|
||||
"conferencing",
|
||||
"unknown"
|
||||
],
|
||||
"example": "conferencing",
|
||||
"description": "only allowed value for type is `conferencing`"
|
||||
"example": "organizersDefaultApp",
|
||||
"description": "only allowed value for type is `organizersDefaultApp`"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
@@ -9631,6 +9649,7 @@
|
||||
"attendeeAddress",
|
||||
"attendeePhone",
|
||||
"attendeeDefined",
|
||||
"organizersDefaultApp",
|
||||
"conferencing",
|
||||
"unknown"
|
||||
],
|
||||
@@ -10838,7 +10857,7 @@
|
||||
"$ref": "#/components/schemas/OutputPhoneLocation_2024_06_14"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/OutputConferencingLocation_2024_06_14"
|
||||
"$ref": "#/components/schemas/OutputOrganizersDefaultAppLocation_2024_06_14"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/OutputUnknownLocation_2024_06_14"
|
||||
@@ -11164,35 +11183,6 @@
|
||||
"type": "string",
|
||||
"example": "Discover the culinary wonders of the Argentina by making the best flan ever!"
|
||||
},
|
||||
"locations": {
|
||||
"type": "array",
|
||||
"description": "Locations where the event will take place. If not provided, cal video link will be used as the location.",
|
||||
"items": {
|
||||
"oneOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/InputAddressLocation_2024_06_14"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/InputLinkLocation_2024_06_14"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/InputIntegrationLocation_2024_06_14"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/InputPhoneLocation_2024_06_14"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/InputAttendeeAddressLocation_2024_06_14"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/InputAttendeePhoneLocation_2024_06_14"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/InputAttendeeDefinedLocation_2024_06_14"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"bookingFields": {
|
||||
"type": "array",
|
||||
"description": "Custom fields that can be added to the booking form when the event is booked by someone. By default booking form has name and email field.",
|
||||
@@ -11394,6 +11384,35 @@
|
||||
"type": "string",
|
||||
"description": "A valid URL where the booker will redirect to, once the booking is completed successfully",
|
||||
"example": "https://masterchief.com/argentina/flan/video/9129412"
|
||||
},
|
||||
"locations": {
|
||||
"type": "array",
|
||||
"description": "Locations where the event will take place. If not provided, cal video link will be used as the location.",
|
||||
"items": {
|
||||
"oneOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/InputAddressLocation_2024_06_14"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/InputLinkLocation_2024_06_14"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/InputIntegrationLocation_2024_06_14"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/InputPhoneLocation_2024_06_14"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/InputAttendeeAddressLocation_2024_06_14"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/InputAttendeePhoneLocation_2024_06_14"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/InputAttendeeDefinedLocation_2024_06_14"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -12753,35 +12772,6 @@
|
||||
"type": "string",
|
||||
"example": "Discover the culinary wonders of the Argentina by making the best flan ever!"
|
||||
},
|
||||
"locations": {
|
||||
"type": "array",
|
||||
"description": "Locations where the event will take place. If not provided, cal video link will be used as the location.",
|
||||
"items": {
|
||||
"oneOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/InputAddressLocation_2024_06_14"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/InputLinkLocation_2024_06_14"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/InputIntegrationLocation_2024_06_14"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/InputPhoneLocation_2024_06_14"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/InputAttendeeAddressLocation_2024_06_14"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/InputAttendeePhoneLocation_2024_06_14"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/InputAttendeeDefinedLocation_2024_06_14"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"bookingFields": {
|
||||
"type": "array",
|
||||
"description": "Custom fields that can be added to the booking form when the event is booked by someone. By default booking form has name and email field.",
|
||||
@@ -12999,6 +12989,38 @@
|
||||
"assignAllTeamMembers": {
|
||||
"type": "boolean",
|
||||
"description": "If true, all current and future team members will be assigned to this event type"
|
||||
},
|
||||
"locations": {
|
||||
"type": "array",
|
||||
"description": "Locations where the event will take place. If not provided, cal video link will be used as the location.",
|
||||
"items": {
|
||||
"oneOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/InputAddressLocation_2024_06_14"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/InputLinkLocation_2024_06_14"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/InputIntegrationLocation_2024_06_14"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/InputPhoneLocation_2024_06_14"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/InputAttendeeAddressLocation_2024_06_14"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/InputAttendeePhoneLocation_2024_06_14"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/InputAttendeeDefinedLocation_2024_06_14"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/InputOrganizersDefaultApp_2024_06_14"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
@@ -13166,7 +13188,7 @@
|
||||
"$ref": "#/components/schemas/OutputPhoneLocation_2024_06_14"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/OutputConferencingLocation_2024_06_14"
|
||||
"$ref": "#/components/schemas/OutputOrganizersDefaultAppLocation_2024_06_14"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/OutputUnknownLocation_2024_06_14"
|
||||
@@ -13594,35 +13616,6 @@
|
||||
"type": "string",
|
||||
"example": "Discover the culinary wonders of the Argentina by making the best flan ever!"
|
||||
},
|
||||
"locations": {
|
||||
"type": "array",
|
||||
"description": "Locations where the event will take place. If not provided, cal video link will be used as the location.",
|
||||
"items": {
|
||||
"oneOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/InputAddressLocation_2024_06_14"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/InputLinkLocation_2024_06_14"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/InputIntegrationLocation_2024_06_14"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/InputPhoneLocation_2024_06_14"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/InputAttendeeAddressLocation_2024_06_14"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/InputAttendeePhoneLocation_2024_06_14"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/InputAttendeeDefinedLocation_2024_06_14"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"bookingFields": {
|
||||
"type": "array",
|
||||
"description": "Custom fields that can be added to the booking form when the event is booked by someone. By default booking form has name and email field.",
|
||||
@@ -13834,6 +13827,38 @@
|
||||
"assignAllTeamMembers": {
|
||||
"type": "boolean",
|
||||
"description": "If true, all current and future team members will be assigned to this event type"
|
||||
},
|
||||
"locations": {
|
||||
"type": "array",
|
||||
"description": "Locations where the event will take place. If not provided, cal video link will be used as the location.",
|
||||
"items": {
|
||||
"oneOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/InputAddressLocation_2024_06_14"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/InputLinkLocation_2024_06_14"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/InputIntegrationLocation_2024_06_14"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/InputPhoneLocation_2024_06_14"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/InputAttendeeAddressLocation_2024_06_14"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/InputAttendeePhoneLocation_2024_06_14"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/InputAttendeeDefinedLocation_2024_06_14"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/InputOrganizersDefaultApp_2024_06_14"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
+147
-124
@@ -8415,6 +8415,17 @@
|
||||
},
|
||||
"required": ["slug"]
|
||||
},
|
||||
"InputOrganizersDefaultApp_2024_06_14": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"type": {
|
||||
"type": "string",
|
||||
"example": "organizersDefaultApp",
|
||||
"description": "only allowed value for type is `organizersDefaultApp`"
|
||||
}
|
||||
},
|
||||
"required": ["type"]
|
||||
},
|
||||
"BookerLayouts_2024_06_14": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
@@ -8489,35 +8500,6 @@
|
||||
"type": "string",
|
||||
"example": "Discover the culinary wonders of the Argentina by making the best flan ever!"
|
||||
},
|
||||
"locations": {
|
||||
"type": "array",
|
||||
"description": "Locations where the event will take place. If not provided, cal video link will be used as the location.",
|
||||
"items": {
|
||||
"oneOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/InputAddressLocation_2024_06_14"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/InputLinkLocation_2024_06_14"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/InputIntegrationLocation_2024_06_14"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/InputPhoneLocation_2024_06_14"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/InputAttendeeAddressLocation_2024_06_14"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/InputAttendeePhoneLocation_2024_06_14"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/InputAttendeeDefinedLocation_2024_06_14"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"bookingFields": {
|
||||
"type": "array",
|
||||
"description": "Custom fields that can be added to the booking form when the event is booked by someone. By default booking form has name and email field.",
|
||||
@@ -8722,6 +8704,35 @@
|
||||
"type": "string",
|
||||
"description": "A valid URL where the booker will redirect to, once the booking is completed successfully",
|
||||
"example": "https://masterchief.com/argentina/flan/video/9129412"
|
||||
},
|
||||
"locations": {
|
||||
"type": "array",
|
||||
"description": "Locations where the event will take place. If not provided, cal video link will be used as the location.",
|
||||
"items": {
|
||||
"oneOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/InputAddressLocation_2024_06_14"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/InputLinkLocation_2024_06_14"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/InputIntegrationLocation_2024_06_14"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/InputPhoneLocation_2024_06_14"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/InputAttendeeAddressLocation_2024_06_14"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/InputAttendeePhoneLocation_2024_06_14"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/InputAttendeeDefinedLocation_2024_06_14"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": ["lengthInMinutes", "title", "slug"]
|
||||
@@ -8738,7 +8749,8 @@
|
||||
"phone",
|
||||
"attendeeAddress",
|
||||
"attendeePhone",
|
||||
"attendeeDefined"
|
||||
"attendeeDefined",
|
||||
"organizersDefaultApp"
|
||||
],
|
||||
"example": "address",
|
||||
"description": "only allowed value for type is `address`"
|
||||
@@ -8765,7 +8777,8 @@
|
||||
"phone",
|
||||
"attendeeAddress",
|
||||
"attendeePhone",
|
||||
"attendeeDefined"
|
||||
"attendeeDefined",
|
||||
"organizersDefaultApp"
|
||||
],
|
||||
"example": "link",
|
||||
"description": "only allowed value for type is `link`"
|
||||
@@ -8793,6 +8806,7 @@
|
||||
"attendeeAddress",
|
||||
"attendeePhone",
|
||||
"attendeeDefined",
|
||||
"organizersDefaultApp",
|
||||
"conferencing",
|
||||
"unknown"
|
||||
],
|
||||
@@ -8859,7 +8873,8 @@
|
||||
"phone",
|
||||
"attendeeAddress",
|
||||
"attendeePhone",
|
||||
"attendeeDefined"
|
||||
"attendeeDefined",
|
||||
"organizersDefaultApp"
|
||||
],
|
||||
"example": "phone",
|
||||
"description": "only allowed value for type is `phone`"
|
||||
@@ -8874,7 +8889,7 @@
|
||||
},
|
||||
"required": ["type", "phone", "public"]
|
||||
},
|
||||
"OutputConferencingLocation_2024_06_14": {
|
||||
"OutputOrganizersDefaultAppLocation_2024_06_14": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"type": {
|
||||
@@ -8887,11 +8902,12 @@
|
||||
"attendeeAddress",
|
||||
"attendeePhone",
|
||||
"attendeeDefined",
|
||||
"organizersDefaultApp",
|
||||
"conferencing",
|
||||
"unknown"
|
||||
],
|
||||
"example": "conferencing",
|
||||
"description": "only allowed value for type is `conferencing`"
|
||||
"example": "organizersDefaultApp",
|
||||
"description": "only allowed value for type is `organizersDefaultApp`"
|
||||
}
|
||||
},
|
||||
"required": ["type"]
|
||||
@@ -8909,6 +8925,7 @@
|
||||
"attendeeAddress",
|
||||
"attendeePhone",
|
||||
"attendeeDefined",
|
||||
"organizersDefaultApp",
|
||||
"conferencing",
|
||||
"unknown"
|
||||
],
|
||||
@@ -9953,7 +9970,7 @@
|
||||
"$ref": "#/components/schemas/OutputPhoneLocation_2024_06_14"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/OutputConferencingLocation_2024_06_14"
|
||||
"$ref": "#/components/schemas/OutputOrganizersDefaultAppLocation_2024_06_14"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/OutputUnknownLocation_2024_06_14"
|
||||
@@ -10257,35 +10274,6 @@
|
||||
"type": "string",
|
||||
"example": "Discover the culinary wonders of the Argentina by making the best flan ever!"
|
||||
},
|
||||
"locations": {
|
||||
"type": "array",
|
||||
"description": "Locations where the event will take place. If not provided, cal video link will be used as the location.",
|
||||
"items": {
|
||||
"oneOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/InputAddressLocation_2024_06_14"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/InputLinkLocation_2024_06_14"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/InputIntegrationLocation_2024_06_14"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/InputPhoneLocation_2024_06_14"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/InputAttendeeAddressLocation_2024_06_14"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/InputAttendeePhoneLocation_2024_06_14"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/InputAttendeeDefinedLocation_2024_06_14"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"bookingFields": {
|
||||
"type": "array",
|
||||
"description": "Custom fields that can be added to the booking form when the event is booked by someone. By default booking form has name and email field.",
|
||||
@@ -10487,6 +10475,35 @@
|
||||
"type": "string",
|
||||
"description": "A valid URL where the booker will redirect to, once the booking is completed successfully",
|
||||
"example": "https://masterchief.com/argentina/flan/video/9129412"
|
||||
},
|
||||
"locations": {
|
||||
"type": "array",
|
||||
"description": "Locations where the event will take place. If not provided, cal video link will be used as the location.",
|
||||
"items": {
|
||||
"oneOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/InputAddressLocation_2024_06_14"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/InputLinkLocation_2024_06_14"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/InputIntegrationLocation_2024_06_14"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/InputPhoneLocation_2024_06_14"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/InputAttendeeAddressLocation_2024_06_14"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/InputAttendeePhoneLocation_2024_06_14"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/InputAttendeeDefinedLocation_2024_06_14"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -11614,35 +11631,6 @@
|
||||
"type": "string",
|
||||
"example": "Discover the culinary wonders of the Argentina by making the best flan ever!"
|
||||
},
|
||||
"locations": {
|
||||
"type": "array",
|
||||
"description": "Locations where the event will take place. If not provided, cal video link will be used as the location.",
|
||||
"items": {
|
||||
"oneOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/InputAddressLocation_2024_06_14"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/InputLinkLocation_2024_06_14"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/InputIntegrationLocation_2024_06_14"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/InputPhoneLocation_2024_06_14"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/InputAttendeeAddressLocation_2024_06_14"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/InputAttendeePhoneLocation_2024_06_14"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/InputAttendeeDefinedLocation_2024_06_14"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"bookingFields": {
|
||||
"type": "array",
|
||||
"description": "Custom fields that can be added to the booking form when the event is booked by someone. By default booking form has name and email field.",
|
||||
@@ -11860,6 +11848,38 @@
|
||||
"assignAllTeamMembers": {
|
||||
"type": "boolean",
|
||||
"description": "If true, all current and future team members will be assigned to this event type"
|
||||
},
|
||||
"locations": {
|
||||
"type": "array",
|
||||
"description": "Locations where the event will take place. If not provided, cal video link will be used as the location.",
|
||||
"items": {
|
||||
"oneOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/InputAddressLocation_2024_06_14"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/InputLinkLocation_2024_06_14"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/InputIntegrationLocation_2024_06_14"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/InputPhoneLocation_2024_06_14"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/InputAttendeeAddressLocation_2024_06_14"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/InputAttendeePhoneLocation_2024_06_14"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/InputAttendeeDefinedLocation_2024_06_14"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/InputOrganizersDefaultApp_2024_06_14"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": ["lengthInMinutes", "title", "slug", "schedulingType", "hosts"]
|
||||
@@ -12000,7 +12020,7 @@
|
||||
"$ref": "#/components/schemas/OutputPhoneLocation_2024_06_14"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/OutputConferencingLocation_2024_06_14"
|
||||
"$ref": "#/components/schemas/OutputOrganizersDefaultAppLocation_2024_06_14"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/OutputUnknownLocation_2024_06_14"
|
||||
@@ -12391,35 +12411,6 @@
|
||||
"type": "string",
|
||||
"example": "Discover the culinary wonders of the Argentina by making the best flan ever!"
|
||||
},
|
||||
"locations": {
|
||||
"type": "array",
|
||||
"description": "Locations where the event will take place. If not provided, cal video link will be used as the location.",
|
||||
"items": {
|
||||
"oneOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/InputAddressLocation_2024_06_14"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/InputLinkLocation_2024_06_14"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/InputIntegrationLocation_2024_06_14"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/InputPhoneLocation_2024_06_14"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/InputAttendeeAddressLocation_2024_06_14"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/InputAttendeePhoneLocation_2024_06_14"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/InputAttendeeDefinedLocation_2024_06_14"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"bookingFields": {
|
||||
"type": "array",
|
||||
"description": "Custom fields that can be added to the booking form when the event is booked by someone. By default booking form has name and email field.",
|
||||
@@ -12631,6 +12622,38 @@
|
||||
"assignAllTeamMembers": {
|
||||
"type": "boolean",
|
||||
"description": "If true, all current and future team members will be assigned to this event type"
|
||||
},
|
||||
"locations": {
|
||||
"type": "array",
|
||||
"description": "Locations where the event will take place. If not provided, cal video link will be used as the location.",
|
||||
"items": {
|
||||
"oneOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/InputAddressLocation_2024_06_14"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/InputLinkLocation_2024_06_14"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/InputIntegrationLocation_2024_06_14"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/InputPhoneLocation_2024_06_14"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/InputAttendeeAddressLocation_2024_06_14"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/InputAttendeePhoneLocation_2024_06_14"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/InputAttendeeDefinedLocation_2024_06_14"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/InputOrganizersDefaultApp_2024_06_14"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -22,6 +22,7 @@ import type {
|
||||
InputAttendeeAddressLocation_2024_06_14,
|
||||
InputAttendeePhoneLocation_2024_06_14,
|
||||
InputAttendeeDefinedLocation_2024_06_14,
|
||||
InputTeamLocation_2024_06_14,
|
||||
} from "@calcom/platform-types";
|
||||
|
||||
import {
|
||||
@@ -41,6 +42,7 @@ import {
|
||||
transformEventColorsApiToInternal,
|
||||
transformBookerLayoutsApiToInternal,
|
||||
transformConfirmationPolicyApiToInternal,
|
||||
transformTeamLocationsApiToInternal,
|
||||
} from "./index";
|
||||
|
||||
describe("transformLocationsApiToInternal", () => {
|
||||
@@ -111,6 +113,20 @@ describe("transformLocationsApiToInternal", () => {
|
||||
expect(result).toEqual(expectedOutput);
|
||||
});
|
||||
|
||||
it("should transform OrganizersDefaultApp", () => {
|
||||
const input: InputTeamLocation_2024_06_14[] = [
|
||||
{
|
||||
type: "organizersDefaultApp",
|
||||
},
|
||||
];
|
||||
|
||||
const expectedOutput = [{ type: "conferencing" }];
|
||||
|
||||
const result = transformTeamLocationsApiToInternal(input);
|
||||
|
||||
expect(result).toEqual(expectedOutput);
|
||||
});
|
||||
|
||||
it("should transform attendee address", () => {
|
||||
const input: InputAttendeeAddressLocation_2024_06_14[] = [
|
||||
{
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { InputLocation_2024_06_14 } from "@calcom/platform-types";
|
||||
import type { InputLocation_2024_06_14, InputTeamLocation_2024_06_14 } from "@calcom/platform-types";
|
||||
import { type Integration_2024_06_14 } from "@calcom/platform-types";
|
||||
|
||||
import type {
|
||||
@@ -9,6 +9,7 @@ import type {
|
||||
OrganizerIntegrationLocation,
|
||||
OrganizerLinkLocation,
|
||||
OrganizerPhoneLocation,
|
||||
OrganizerConferencingSchema,
|
||||
} from "../internal/locations";
|
||||
|
||||
const apiToInternalintegrationsMapping: Record<
|
||||
@@ -21,43 +22,54 @@ const apiToInternalintegrationsMapping: Record<
|
||||
zoom: "integrations:zoom",
|
||||
};
|
||||
|
||||
export function transformLocationsApiToInternal(inputLocations: InputLocation_2024_06_14[] | undefined) {
|
||||
if (!inputLocations) {
|
||||
return [];
|
||||
function transformLocation<T extends InputLocation_2024_06_14>(location: T) {
|
||||
const { type } = location;
|
||||
switch (type) {
|
||||
case "address":
|
||||
return {
|
||||
type: "inPerson",
|
||||
address: location.address,
|
||||
displayLocationPublicly: location.public,
|
||||
} satisfies OrganizerAddressLocation;
|
||||
case "attendeeAddress":
|
||||
return { type: "attendeeInPerson" } satisfies AttendeeAddressLocation;
|
||||
case "link":
|
||||
return {
|
||||
type: "link",
|
||||
link: location.link,
|
||||
displayLocationPublicly: location.public,
|
||||
} satisfies OrganizerLinkLocation;
|
||||
case "integration":
|
||||
const integrationLabel = apiToInternalintegrationsMapping[location.integration];
|
||||
return { type: integrationLabel } satisfies OrganizerIntegrationLocation;
|
||||
case "phone":
|
||||
return {
|
||||
type: "userPhone",
|
||||
hostPhoneNumber: location.phone,
|
||||
displayLocationPublicly: location.public,
|
||||
} satisfies OrganizerPhoneLocation;
|
||||
case "attendeePhone":
|
||||
return { type: "phone" } satisfies AttendeePhoneLocation;
|
||||
case "attendeeDefined":
|
||||
return { type: "somewhereElse" } satisfies AttendeeDefinedLocation;
|
||||
default:
|
||||
throw new Error(`Unsupported input location type '${type}'`);
|
||||
}
|
||||
}
|
||||
|
||||
export function transformLocationsApiToInternal(inputLocations: InputLocation_2024_06_14[] | undefined) {
|
||||
return inputLocations ? inputLocations.map(transformLocation) : [];
|
||||
}
|
||||
|
||||
export function transformTeamLocationsApiToInternal(
|
||||
inputLocations: InputTeamLocation_2024_06_14[] | undefined
|
||||
) {
|
||||
if (!inputLocations) return [];
|
||||
|
||||
return inputLocations.map((location) => {
|
||||
const { type } = location;
|
||||
switch (type) {
|
||||
case "address":
|
||||
return {
|
||||
type: "inPerson",
|
||||
address: location.address,
|
||||
displayLocationPublicly: location.public,
|
||||
} satisfies OrganizerAddressLocation;
|
||||
case "attendeeAddress":
|
||||
return { type: "attendeeInPerson" } satisfies AttendeeAddressLocation;
|
||||
case "link":
|
||||
return {
|
||||
type: "link",
|
||||
link: location.link,
|
||||
displayLocationPublicly: location.public,
|
||||
} satisfies OrganizerLinkLocation;
|
||||
case "integration":
|
||||
const integrationLabel = apiToInternalintegrationsMapping[location.integration];
|
||||
return { type: integrationLabel } satisfies OrganizerIntegrationLocation;
|
||||
case "phone":
|
||||
return {
|
||||
type: "userPhone",
|
||||
hostPhoneNumber: location.phone,
|
||||
displayLocationPublicly: location.public,
|
||||
} satisfies OrganizerPhoneLocation;
|
||||
case "attendeePhone":
|
||||
return { type: "phone" } satisfies AttendeePhoneLocation;
|
||||
case "attendeeDefined":
|
||||
return { type: "somewhereElse" } satisfies AttendeeDefinedLocation;
|
||||
default:
|
||||
throw new Error(`Unsupported input location type '${type}'`);
|
||||
if (location.type === "organizersDefaultApp") {
|
||||
return { type: "conferencing" } satisfies OrganizerConferencingSchema;
|
||||
}
|
||||
return transformLocation(location);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ import type {
|
||||
SeatOptionsDisabledSchema,
|
||||
OutputAddressLocation_2024_06_14,
|
||||
OutputAttendeeAddressLocation_2024_06_14,
|
||||
OutputOrganizersDefaultAppLocation_2024_06_14,
|
||||
OutputAttendeeDefinedLocation_2024_06_14,
|
||||
OutputAttendeePhoneLocation_2024_06_14,
|
||||
OutputIntegrationLocation_2024_06_14,
|
||||
@@ -230,6 +231,23 @@ describe("transformLocationsInternalToApi", () => {
|
||||
expect(result).toEqual(expectedOutput);
|
||||
});
|
||||
|
||||
it("should reverse transform organizersDefaultApp locations", () => {
|
||||
const transformedLocation = [
|
||||
{
|
||||
type: "conferencing" as const,
|
||||
},
|
||||
];
|
||||
|
||||
const expectedOutput: OutputOrganizersDefaultAppLocation_2024_06_14[] = [
|
||||
{
|
||||
type: "organizersDefaultApp",
|
||||
},
|
||||
];
|
||||
|
||||
const result = transformLocationsInternalToApi(transformedLocation);
|
||||
expect(result).toEqual(expectedOutput);
|
||||
});
|
||||
|
||||
it("should reverse transform attendee phone location", () => {
|
||||
const transformedLocation = [
|
||||
{
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import type {
|
||||
OutputConferencingLocation_2024_06_14,
|
||||
OutputOrganizersDefaultAppLocation_2024_06_14,
|
||||
OutputIntegration_2024_06_14,
|
||||
OutputIntegrationLocation_2024_06_14,
|
||||
OutputAddressLocation_2024_06_14,
|
||||
@@ -106,8 +106,8 @@ export function transformLocationsInternalToApi(internalLocations: InternalLocat
|
||||
return attendeeDefinedLocation;
|
||||
}
|
||||
case "conferencing": {
|
||||
const conferencingLocation: OutputConferencingLocation_2024_06_14 = {
|
||||
type: "conferencing",
|
||||
const conferencingLocation: OutputOrganizersDefaultAppLocation_2024_06_14 = {
|
||||
type: "organizersDefaultApp",
|
||||
};
|
||||
return conferencingLocation;
|
||||
}
|
||||
|
||||
+7
-6
@@ -1,7 +1,7 @@
|
||||
import { defaultEvents } from "@calcom/lib/defaultEvents";
|
||||
import type { SystemField } from "@calcom/lib/event-types/transformers";
|
||||
import {
|
||||
transformLocationsApiToInternal,
|
||||
transformTeamLocationsApiToInternal,
|
||||
transformBookingFieldsApiToInternal,
|
||||
systemBeforeFieldName,
|
||||
systemBeforeFieldEmail,
|
||||
@@ -299,20 +299,20 @@ function isDefaultEvent(eventSlug: string) {
|
||||
}
|
||||
|
||||
function getLocations(locations: EventTypeOutput_2024_06_14["locations"]) {
|
||||
const transformed = transformLocationsApiToInternal(
|
||||
const transformed = transformTeamLocationsApiToInternal(
|
||||
locations.filter((location) => isAtomSupportedLocation(location))
|
||||
);
|
||||
|
||||
const withPrivateHidden = transformed.map((location) => {
|
||||
const { displayLocationPublicly, type } = location;
|
||||
const { type } = location;
|
||||
|
||||
switch (type) {
|
||||
case "inPerson":
|
||||
return displayLocationPublicly ? location : { ...location, address: "" };
|
||||
return location?.displayLocationPublicly ? location : { ...location, address: "" };
|
||||
case "link":
|
||||
return displayLocationPublicly ? location : { ...location, link: "" };
|
||||
return location?.displayLocationPublicly ? location : { ...location, link: "" };
|
||||
case "userPhone":
|
||||
return displayLocationPublicly
|
||||
return location?.displayLocationPublicly
|
||||
? location
|
||||
: {
|
||||
...location,
|
||||
@@ -338,6 +338,7 @@ function isAtomSupportedLocation(
|
||||
location.type === "phone" ||
|
||||
location.type === "attendeePhone" ||
|
||||
location.type === "attendeeDefined" ||
|
||||
location.type === "organizersDefaultApp" ||
|
||||
(location.type === "integration" && supportedIntegrations.includes(location.integration))
|
||||
);
|
||||
}
|
||||
|
||||
@@ -166,6 +166,7 @@ export {
|
||||
// note(Lauris): Api to internal
|
||||
transformBookingFieldsApiToInternal,
|
||||
transformLocationsApiToInternal,
|
||||
transformTeamLocationsApiToInternal,
|
||||
transformIntervalLimitsApiToInternal,
|
||||
transformFutureBookingLimitsApiToInternal,
|
||||
transformRecurrenceApiToInternal,
|
||||
|
||||
+47
-23
@@ -67,13 +67,15 @@ import {
|
||||
InputAddressLocation_2024_06_14,
|
||||
InputAttendeeAddressLocation_2024_06_14,
|
||||
InputAttendeeDefinedLocation_2024_06_14,
|
||||
InputOrganizersDefaultApp_2024_06_14,
|
||||
InputAttendeePhoneLocation_2024_06_14,
|
||||
InputIntegrationLocation_2024_06_14,
|
||||
InputLinkLocation_2024_06_14,
|
||||
InputPhoneLocation_2024_06_14,
|
||||
ValidateLocations_2024_06_14,
|
||||
ValidateTeamLocations_2024_06_14,
|
||||
} from "./locations.input";
|
||||
import type { InputLocation_2024_06_14 } from "./locations.input";
|
||||
import type { InputLocation_2024_06_14, InputTeamLocation_2024_06_14 } from "./locations.input";
|
||||
import { Recurrence_2024_06_14 } from "./recurrence.input";
|
||||
import { Seats_2024_06_14 } from "./seats.input";
|
||||
|
||||
@@ -117,9 +119,10 @@ export const CREATE_EVENT_SLUG_EXAMPLE = "learn-the-secrets-of-masterchief";
|
||||
TitleDefaultFieldInput_2024_06_14,
|
||||
NotesDefaultFieldInput_2024_06_14,
|
||||
GuestsDefaultFieldInput_2024_06_14,
|
||||
RescheduleReasonDefaultFieldInput_2024_06_14
|
||||
RescheduleReasonDefaultFieldInput_2024_06_14,
|
||||
InputOrganizersDefaultApp_2024_06_14
|
||||
)
|
||||
export class CreateEventTypeInput_2024_06_14 {
|
||||
class BaseCreateEventTypeInput {
|
||||
@IsInt()
|
||||
@Min(1)
|
||||
@DocsProperty({ example: CREATE_EVENT_LENGTH_EXAMPLE })
|
||||
@@ -151,25 +154,6 @@ export class CreateEventTypeInput_2024_06_14 {
|
||||
@DocsPropertyOptional({ example: CREATE_EVENT_DESCRIPTION_EXAMPLE })
|
||||
description?: string;
|
||||
|
||||
@IsOptional()
|
||||
@ValidateLocations_2024_06_14()
|
||||
@DocsPropertyOptional({
|
||||
description:
|
||||
"Locations where the event will take place. If not provided, cal video link will be used as the location.",
|
||||
oneOf: [
|
||||
{ $ref: getSchemaPath(InputAddressLocation_2024_06_14) },
|
||||
{ $ref: getSchemaPath(InputLinkLocation_2024_06_14) },
|
||||
{ $ref: getSchemaPath(InputIntegrationLocation_2024_06_14) },
|
||||
{ $ref: getSchemaPath(InputPhoneLocation_2024_06_14) },
|
||||
{ $ref: getSchemaPath(InputAttendeeAddressLocation_2024_06_14) },
|
||||
{ $ref: getSchemaPath(InputAttendeePhoneLocation_2024_06_14) },
|
||||
{ $ref: getSchemaPath(InputAttendeeDefinedLocation_2024_06_14) },
|
||||
],
|
||||
type: "array",
|
||||
})
|
||||
@Type(() => Object)
|
||||
locations?: InputLocation_2024_06_14[];
|
||||
|
||||
@IsOptional()
|
||||
@ValidateInputBookingFields_2024_06_14()
|
||||
@DocsPropertyOptional({
|
||||
@@ -412,6 +396,26 @@ export class CreateEventTypeInput_2024_06_14 {
|
||||
})
|
||||
successRedirectUrl?: string;
|
||||
}
|
||||
export class CreateEventTypeInput_2024_06_14 extends BaseCreateEventTypeInput {
|
||||
@IsOptional()
|
||||
@ValidateLocations_2024_06_14()
|
||||
@DocsPropertyOptional({
|
||||
description:
|
||||
"Locations where the event will take place. If not provided, cal video link will be used as the location.",
|
||||
oneOf: [
|
||||
{ $ref: getSchemaPath(InputAddressLocation_2024_06_14) },
|
||||
{ $ref: getSchemaPath(InputLinkLocation_2024_06_14) },
|
||||
{ $ref: getSchemaPath(InputIntegrationLocation_2024_06_14) },
|
||||
{ $ref: getSchemaPath(InputPhoneLocation_2024_06_14) },
|
||||
{ $ref: getSchemaPath(InputAttendeeAddressLocation_2024_06_14) },
|
||||
{ $ref: getSchemaPath(InputAttendeePhoneLocation_2024_06_14) },
|
||||
{ $ref: getSchemaPath(InputAttendeeDefinedLocation_2024_06_14) },
|
||||
],
|
||||
type: "array",
|
||||
})
|
||||
@Type(() => Object)
|
||||
locations?: InputLocation_2024_06_14[];
|
||||
}
|
||||
|
||||
export enum HostPriority {
|
||||
lowest = "lowest",
|
||||
@@ -442,7 +446,7 @@ export class Host {
|
||||
priority?: keyof typeof HostPriority = "medium";
|
||||
}
|
||||
|
||||
export class CreateTeamEventTypeInput_2024_06_14 extends CreateEventTypeInput_2024_06_14 {
|
||||
export class CreateTeamEventTypeInput_2024_06_14 extends BaseCreateEventTypeInput {
|
||||
@Transform(({ value }) => {
|
||||
if (value === "collective") {
|
||||
return SchedulingType.COLLECTIVE;
|
||||
@@ -471,4 +475,24 @@ export class CreateTeamEventTypeInput_2024_06_14 extends CreateEventTypeInput_20
|
||||
description: "If true, all current and future team members will be assigned to this event type",
|
||||
})
|
||||
assignAllTeamMembers?: boolean;
|
||||
|
||||
@IsOptional()
|
||||
@ValidateTeamLocations_2024_06_14()
|
||||
@DocsPropertyOptional({
|
||||
description:
|
||||
"Locations where the event will take place. If not provided, cal video link will be used as the location.",
|
||||
oneOf: [
|
||||
{ $ref: getSchemaPath(InputAddressLocation_2024_06_14) },
|
||||
{ $ref: getSchemaPath(InputLinkLocation_2024_06_14) },
|
||||
{ $ref: getSchemaPath(InputIntegrationLocation_2024_06_14) },
|
||||
{ $ref: getSchemaPath(InputPhoneLocation_2024_06_14) },
|
||||
{ $ref: getSchemaPath(InputAttendeeAddressLocation_2024_06_14) },
|
||||
{ $ref: getSchemaPath(InputAttendeePhoneLocation_2024_06_14) },
|
||||
{ $ref: getSchemaPath(InputAttendeeDefinedLocation_2024_06_14) },
|
||||
{ $ref: getSchemaPath(InputOrganizersDefaultApp_2024_06_14) },
|
||||
],
|
||||
type: "array",
|
||||
})
|
||||
@Type(() => Object)
|
||||
locations?: InputTeamLocation_2024_06_14[];
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ export const inputLocations = [
|
||||
"attendeeAddress",
|
||||
"attendeePhone",
|
||||
"attendeeDefined",
|
||||
"organizersDefaultApp",
|
||||
] as const;
|
||||
|
||||
export class InputAddressLocation_2024_06_14 {
|
||||
@@ -29,6 +30,15 @@ export class InputAddressLocation_2024_06_14 {
|
||||
public!: boolean;
|
||||
}
|
||||
|
||||
export class InputOrganizersDefaultApp_2024_06_14 {
|
||||
@IsIn(inputLocations)
|
||||
@DocsProperty({
|
||||
example: "organizersDefaultApp",
|
||||
description: "only allowed value for type is `organizersDefaultApp`",
|
||||
})
|
||||
type!: "organizersDefaultApp";
|
||||
}
|
||||
|
||||
export class InputLinkLocation_2024_06_14 {
|
||||
@IsIn(inputLocations)
|
||||
@DocsProperty({ example: "link", description: "only allowed value for type is `link`" })
|
||||
@@ -102,6 +112,8 @@ export type InputLocation_2024_06_14 =
|
||||
| InputAttendeePhoneLocation_2024_06_14
|
||||
| InputAttendeeDefinedLocation_2024_06_14;
|
||||
|
||||
export type InputTeamLocation_2024_06_14 = InputLocation_2024_06_14 | InputOrganizersDefaultApp_2024_06_14;
|
||||
|
||||
@ValidatorConstraint({ async: true })
|
||||
class InputLocationValidator_2024_06_14 implements ValidatorConstraintInterface {
|
||||
private classTypeMap: { [key: string]: new () => InputLocation_2024_06_14 } = {
|
||||
@@ -152,6 +164,57 @@ class InputLocationValidator_2024_06_14 implements ValidatorConstraintInterface
|
||||
}
|
||||
}
|
||||
|
||||
@ValidatorConstraint({ async: true })
|
||||
class InputTeamLocationValidator_2024_06_14 implements ValidatorConstraintInterface {
|
||||
private classTypeMap: { [key: string]: new () => InputTeamLocation_2024_06_14 } = {
|
||||
address: InputAddressLocation_2024_06_14,
|
||||
link: InputLinkLocation_2024_06_14,
|
||||
integration: InputIntegrationLocation_2024_06_14,
|
||||
phone: InputPhoneLocation_2024_06_14,
|
||||
attendeePhone: InputAttendeePhoneLocation_2024_06_14,
|
||||
attendeeAddress: InputAttendeeAddressLocation_2024_06_14,
|
||||
attendeeDefined: InputAttendeeDefinedLocation_2024_06_14,
|
||||
organizersDefaultApp: InputOrganizersDefaultApp_2024_06_14,
|
||||
};
|
||||
|
||||
async validate(locations: { type: string }[]) {
|
||||
if (!Array.isArray(locations)) {
|
||||
throw new BadRequestException(`'locations' must be an array.`);
|
||||
}
|
||||
|
||||
if (!locations.length) {
|
||||
throw new BadRequestException(`'locations' must contain at least 1 location.`);
|
||||
}
|
||||
|
||||
for (const location of locations) {
|
||||
const { type } = location;
|
||||
if (!type) {
|
||||
throw new BadRequestException(`Each object in 'locations' must have a 'type' property.`);
|
||||
}
|
||||
|
||||
const ClassType = this.classTypeMap[type];
|
||||
if (!ClassType) {
|
||||
throw new BadRequestException(
|
||||
`Unsupported location type '${type}'. Valid types are address, link, integration, and phone.`
|
||||
);
|
||||
}
|
||||
|
||||
const instance = plainToInstance(ClassType, location);
|
||||
const errors = await validate(instance);
|
||||
if (errors.length > 0) {
|
||||
const message = errors.flatMap((error) => Object.values(error.constraints || {})).join(", ");
|
||||
throw new BadRequestException(`Validation failed for ${type} location: ${message}`);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
defaultMessage() {
|
||||
return `Validation failed for one or more location entries.`;
|
||||
}
|
||||
}
|
||||
|
||||
export function ValidateLocations_2024_06_14(validationOptions?: ValidationOptions) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
return function (object: any, propertyName: string) {
|
||||
@@ -164,3 +227,16 @@ export function ValidateLocations_2024_06_14(validationOptions?: ValidationOptio
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
export function ValidateTeamLocations_2024_06_14(validationOptions?: ValidationOptions) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
return function (object: any, propertyName: string) {
|
||||
registerDecorator({
|
||||
name: "ValidateTeamLocation",
|
||||
target: object.constructor,
|
||||
propertyName: propertyName,
|
||||
options: validationOptions,
|
||||
validator: new InputTeamLocationValidator_2024_06_14(),
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
+45
-22
@@ -73,10 +73,12 @@ import {
|
||||
InputAttendeePhoneLocation_2024_06_14,
|
||||
InputIntegrationLocation_2024_06_14,
|
||||
InputLinkLocation_2024_06_14,
|
||||
InputOrganizersDefaultApp_2024_06_14,
|
||||
InputPhoneLocation_2024_06_14,
|
||||
ValidateLocations_2024_06_14,
|
||||
ValidateTeamLocations_2024_06_14,
|
||||
} from "./locations.input";
|
||||
import type { InputLocation_2024_06_14 } from "./locations.input";
|
||||
import type { InputLocation_2024_06_14, InputTeamLocation_2024_06_14 } from "./locations.input";
|
||||
import { Recurrence_2024_06_14 } from "./recurrence.input";
|
||||
import { Seats_2024_06_14 } from "./seats.input";
|
||||
|
||||
@@ -115,7 +117,7 @@ import { Seats_2024_06_14 } from "./seats.input";
|
||||
GuestsDefaultFieldInput_2024_06_14,
|
||||
RescheduleReasonDefaultFieldInput_2024_06_14
|
||||
)
|
||||
export class UpdateEventTypeInput_2024_06_14 {
|
||||
class BaseUpdateEventTypeInput {
|
||||
@IsOptional()
|
||||
@IsInt()
|
||||
@Min(1)
|
||||
@@ -150,25 +152,6 @@ export class UpdateEventTypeInput_2024_06_14 {
|
||||
@DocsPropertyOptional({ example: CREATE_EVENT_DESCRIPTION_EXAMPLE })
|
||||
description?: string;
|
||||
|
||||
@IsOptional()
|
||||
@ValidateLocations_2024_06_14()
|
||||
@DocsPropertyOptional({
|
||||
description:
|
||||
"Locations where the event will take place. If not provided, cal video link will be used as the location.",
|
||||
oneOf: [
|
||||
{ $ref: getSchemaPath(InputAddressLocation_2024_06_14) },
|
||||
{ $ref: getSchemaPath(InputLinkLocation_2024_06_14) },
|
||||
{ $ref: getSchemaPath(InputIntegrationLocation_2024_06_14) },
|
||||
{ $ref: getSchemaPath(InputPhoneLocation_2024_06_14) },
|
||||
{ $ref: getSchemaPath(InputAttendeeAddressLocation_2024_06_14) },
|
||||
{ $ref: getSchemaPath(InputAttendeePhoneLocation_2024_06_14) },
|
||||
{ $ref: getSchemaPath(InputAttendeeDefinedLocation_2024_06_14) },
|
||||
],
|
||||
type: "array",
|
||||
})
|
||||
@Type(() => Object)
|
||||
locations?: InputLocation_2024_06_14[];
|
||||
|
||||
@IsOptional()
|
||||
@ValidateInputBookingFields_2024_06_14()
|
||||
@DocsPropertyOptional({
|
||||
@@ -410,8 +393,28 @@ export class UpdateEventTypeInput_2024_06_14 {
|
||||
})
|
||||
successRedirectUrl?: string;
|
||||
}
|
||||
export class UpdateEventTypeInput_2024_06_14 extends BaseUpdateEventTypeInput {
|
||||
@IsOptional()
|
||||
@ValidateLocations_2024_06_14()
|
||||
@DocsPropertyOptional({
|
||||
description:
|
||||
"Locations where the event will take place. If not provided, cal video link will be used as the location.",
|
||||
oneOf: [
|
||||
{ $ref: getSchemaPath(InputAddressLocation_2024_06_14) },
|
||||
{ $ref: getSchemaPath(InputLinkLocation_2024_06_14) },
|
||||
{ $ref: getSchemaPath(InputIntegrationLocation_2024_06_14) },
|
||||
{ $ref: getSchemaPath(InputPhoneLocation_2024_06_14) },
|
||||
{ $ref: getSchemaPath(InputAttendeeAddressLocation_2024_06_14) },
|
||||
{ $ref: getSchemaPath(InputAttendeePhoneLocation_2024_06_14) },
|
||||
{ $ref: getSchemaPath(InputAttendeeDefinedLocation_2024_06_14) },
|
||||
],
|
||||
type: "array",
|
||||
})
|
||||
@Type(() => Object)
|
||||
locations?: InputLocation_2024_06_14[];
|
||||
}
|
||||
|
||||
export class UpdateTeamEventTypeInput_2024_06_14 extends UpdateEventTypeInput_2024_06_14 {
|
||||
export class UpdateTeamEventTypeInput_2024_06_14 extends BaseUpdateEventTypeInput {
|
||||
@ValidateNested({ each: true })
|
||||
@Type(() => Host)
|
||||
@IsArray()
|
||||
@@ -426,4 +429,24 @@ export class UpdateTeamEventTypeInput_2024_06_14 extends UpdateEventTypeInput_20
|
||||
description: "If true, all current and future team members will be assigned to this event type",
|
||||
})
|
||||
assignAllTeamMembers?: boolean;
|
||||
|
||||
@IsOptional()
|
||||
@ValidateTeamLocations_2024_06_14()
|
||||
@DocsPropertyOptional({
|
||||
description:
|
||||
"Locations where the event will take place. If not provided, cal video link will be used as the location.",
|
||||
oneOf: [
|
||||
{ $ref: getSchemaPath(InputAddressLocation_2024_06_14) },
|
||||
{ $ref: getSchemaPath(InputLinkLocation_2024_06_14) },
|
||||
{ $ref: getSchemaPath(InputIntegrationLocation_2024_06_14) },
|
||||
{ $ref: getSchemaPath(InputPhoneLocation_2024_06_14) },
|
||||
{ $ref: getSchemaPath(InputAttendeeAddressLocation_2024_06_14) },
|
||||
{ $ref: getSchemaPath(InputAttendeePhoneLocation_2024_06_14) },
|
||||
{ $ref: getSchemaPath(InputAttendeeDefinedLocation_2024_06_14) },
|
||||
{ $ref: getSchemaPath(InputOrganizersDefaultApp_2024_06_14) },
|
||||
],
|
||||
type: "array",
|
||||
})
|
||||
@Type(() => Object)
|
||||
locations?: InputTeamLocation_2024_06_14[];
|
||||
}
|
||||
|
||||
+3
-3
@@ -59,7 +59,7 @@ import { ValidateOutputBookingFields_2024_06_14 } from "./booking-fields.output"
|
||||
import type { OutputLocation_2024_06_14 } from "./locations.output";
|
||||
import {
|
||||
OutputAddressLocation_2024_06_14,
|
||||
OutputConferencingLocation_2024_06_14,
|
||||
OutputOrganizersDefaultAppLocation_2024_06_14,
|
||||
OutputIntegrationLocation_2024_06_14,
|
||||
OutputLinkLocation_2024_06_14,
|
||||
OutputPhoneLocation_2024_06_14,
|
||||
@@ -160,7 +160,7 @@ class EventTypeTeam {
|
||||
OutputLinkLocation_2024_06_14,
|
||||
OutputIntegrationLocation_2024_06_14,
|
||||
OutputPhoneLocation_2024_06_14,
|
||||
OutputConferencingLocation_2024_06_14,
|
||||
OutputOrganizersDefaultAppLocation_2024_06_14,
|
||||
OutputUnknownLocation_2024_06_14,
|
||||
EmailDefaultFieldOutput_2024_06_14,
|
||||
NameDefaultFieldOutput_2024_06_14,
|
||||
@@ -232,7 +232,7 @@ class BaseEventTypeOutput_2024_06_14 {
|
||||
{ $ref: getSchemaPath(OutputLinkLocation_2024_06_14) },
|
||||
{ $ref: getSchemaPath(OutputIntegrationLocation_2024_06_14) },
|
||||
{ $ref: getSchemaPath(OutputPhoneLocation_2024_06_14) },
|
||||
{ $ref: getSchemaPath(OutputConferencingLocation_2024_06_14) },
|
||||
{ $ref: getSchemaPath(OutputOrganizersDefaultAppLocation_2024_06_14) },
|
||||
{ $ref: getSchemaPath(OutputUnknownLocation_2024_06_14) },
|
||||
],
|
||||
type: "array",
|
||||
|
||||
+8
-5
@@ -87,10 +87,13 @@ export class OutputIntegrationLocation_2024_06_14 {
|
||||
credentialId?: number;
|
||||
}
|
||||
|
||||
export class OutputConferencingLocation_2024_06_14 {
|
||||
export class OutputOrganizersDefaultAppLocation_2024_06_14 {
|
||||
@IsIn(outputLocations)
|
||||
@DocsProperty({ example: "conferencing", description: "only allowed value for type is `conferencing`" })
|
||||
type!: "conferencing";
|
||||
@DocsProperty({
|
||||
example: "organizersDefaultApp",
|
||||
description: "only allowed value for type is `organizersDefaultApp`",
|
||||
})
|
||||
type!: "organizersDefaultApp";
|
||||
}
|
||||
|
||||
export class OutputUnknownLocation_2024_06_14 {
|
||||
@@ -111,7 +114,7 @@ export type OutputLocation_2024_06_14 =
|
||||
| OutputAttendeeAddressLocation_2024_06_14
|
||||
| OutputAttendeePhoneLocation_2024_06_14
|
||||
| OutputAttendeeDefinedLocation_2024_06_14
|
||||
| OutputConferencingLocation_2024_06_14
|
||||
| OutputOrganizersDefaultAppLocation_2024_06_14
|
||||
| OutputUnknownLocation_2024_06_14;
|
||||
|
||||
@ValidatorConstraint({ async: true })
|
||||
@@ -124,7 +127,7 @@ class OutputLocationValidator_2024_06_14 implements ValidatorConstraintInterface
|
||||
attendeePhone: OutputAttendeePhoneLocation_2024_06_14,
|
||||
attendeeAddress: OutputAttendeeAddressLocation_2024_06_14,
|
||||
attendeeDefined: OutputAttendeeDefinedLocation_2024_06_14,
|
||||
conferencing: OutputConferencingLocation_2024_06_14,
|
||||
conferencing: OutputOrganizersDefaultAppLocation_2024_06_14,
|
||||
unknown: OutputUnknownLocation_2024_06_14,
|
||||
};
|
||||
|
||||
|
||||
@@ -3526,7 +3526,7 @@ __metadata:
|
||||
"@axiomhq/winston": ^1.2.0
|
||||
"@calcom/platform-constants": "*"
|
||||
"@calcom/platform-enums": "*"
|
||||
"@calcom/platform-libraries": "npm:@calcom/platform-libraries@0.0.123"
|
||||
"@calcom/platform-libraries": "npm:@calcom/platform-libraries@0.0.124"
|
||||
"@calcom/platform-libraries-0.0.2": "npm:@calcom/platform-libraries@0.0.2"
|
||||
"@calcom/platform-types": "*"
|
||||
"@calcom/platform-utils": "*"
|
||||
@@ -4571,13 +4571,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@calcom/platform-libraries@npm:@calcom/platform-libraries@0.0.123":
|
||||
version: 0.0.123
|
||||
resolution: "@calcom/platform-libraries@npm:0.0.123"
|
||||
"@calcom/platform-libraries@npm:@calcom/platform-libraries@0.0.124":
|
||||
version: 0.0.124
|
||||
resolution: "@calcom/platform-libraries@npm:0.0.124"
|
||||
dependencies:
|
||||
"@calcom/features": "*"
|
||||
"@calcom/lib": "*"
|
||||
checksum: ef755b7fa3a650ccc802d28e982d0f25e344d11613444771ef26923fdb25d7a9cea85c4f00f01d2c36f8c54f3de2cd0d729c883810345621f55fb8ec316c40fc
|
||||
checksum: e18a22d3c4004e8a33eb01d9412916dd98cff96bccb56c3a082e37e8801c9900d08471a716758d4b15cd5f1c2bfcbe83afa6f2452743a8d57f4ac7978622ec59
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
|
||||
Reference in New Issue
Block a user