From 5d84179345176702d00cff0d886f26fe9b16157b Mon Sep 17 00:00:00 2001 From: Morgan <33722304+ThyMinimalDev@users.noreply.github.com> Date: Mon, 10 Mar 2025 15:25:01 +0200 Subject: [PATCH] refactor: circular dependencies platform packages (#19903) * refactor: circular dependencies platform packages * fixup! refactor: circular dependencies platform packages * fixup! fixup! refactor: circular dependencies platform packages * fix: circular deps in BaseCalProvider --- packages/platform/atoms/booker/types.ts | 50 + .../atoms/cal-provider/BaseCalProvider.tsx | 22 +- .../atoms/cal-provider/CalProvider.tsx | 78 +- .../platform/atoms/cal-provider/languages.ts | 61 ++ .../hooks/usePlatformTabsNavigations.tsx | 2 +- .../wrappers/EventTypePlatformWrapper.tsx | 5 +- .../atoms/event-types/wrappers/types.ts | 3 + .../platform/atoms/hooks/useAtomsContext.ts | 2 +- packages/platform/sdk/.release-it.js | 7 - packages/platform/sdk/README.md | 69 -- packages/platform/sdk/example/index.ts | 54 -- packages/platform/sdk/package.json | 35 - packages/platform/sdk/rollup.config.js | 30 - packages/platform/sdk/src/cal.ts | 78 -- .../sdk/src/endpoints/bookings/index.ts | 8 - .../sdk/src/endpoints/endpoint-handler.ts | 34 - .../src/endpoints/events/event-types/index.ts | 38 - .../src/endpoints/events/event-types/types.ts | 66 -- .../sdk/src/endpoints/events/index.ts | 21 - .../sdk/src/endpoints/events/types.ts | 86 -- .../sdk/src/endpoints/managed-users/index.ts | 54 -- .../sdk/src/endpoints/managed-users/types.ts | 23 - .../sdk/src/endpoints/oauth-flow/index.ts | 32 - .../sdk/src/endpoints/oauth-flow/types.ts | 12 - .../sdk/src/endpoints/schedules/index.ts | 106 --- .../sdk/src/endpoints/schedules/types.ts | 63 -- .../platform/sdk/src/endpoints/slots/index.ts | 46 - .../platform/sdk/src/endpoints/slots/types.ts | 38 - packages/platform/sdk/src/index.ts | 2 - packages/platform/sdk/src/lib/endpoints.ts | 184 ---- .../sdk/src/lib/errors/cal-api-error.ts | 6 - .../lib/errors/sdk-initialization-error.ts | 6 - packages/platform/sdk/src/lib/http-caller.ts | 166 ---- packages/platform/sdk/src/lib/sdk-secrets.ts | 64 -- packages/platform/sdk/src/swagger-types.d.ts | 877 ------------------ packages/platform/sdk/src/types.ts | 38 - packages/platform/sdk/tsconfig.build.json | 7 - packages/platform/sdk/tsconfig.json | 109 --- 38 files changed, 139 insertions(+), 2443 deletions(-) create mode 100644 packages/platform/atoms/booker/types.ts create mode 100644 packages/platform/atoms/cal-provider/languages.ts create mode 100644 packages/platform/atoms/event-types/wrappers/types.ts delete mode 100644 packages/platform/sdk/.release-it.js delete mode 100644 packages/platform/sdk/README.md delete mode 100644 packages/platform/sdk/example/index.ts delete mode 100644 packages/platform/sdk/package.json delete mode 100644 packages/platform/sdk/rollup.config.js delete mode 100644 packages/platform/sdk/src/cal.ts delete mode 100644 packages/platform/sdk/src/endpoints/bookings/index.ts delete mode 100644 packages/platform/sdk/src/endpoints/endpoint-handler.ts delete mode 100644 packages/platform/sdk/src/endpoints/events/event-types/index.ts delete mode 100644 packages/platform/sdk/src/endpoints/events/event-types/types.ts delete mode 100644 packages/platform/sdk/src/endpoints/events/index.ts delete mode 100644 packages/platform/sdk/src/endpoints/events/types.ts delete mode 100644 packages/platform/sdk/src/endpoints/managed-users/index.ts delete mode 100644 packages/platform/sdk/src/endpoints/managed-users/types.ts delete mode 100644 packages/platform/sdk/src/endpoints/oauth-flow/index.ts delete mode 100644 packages/platform/sdk/src/endpoints/oauth-flow/types.ts delete mode 100644 packages/platform/sdk/src/endpoints/schedules/index.ts delete mode 100644 packages/platform/sdk/src/endpoints/schedules/types.ts delete mode 100644 packages/platform/sdk/src/endpoints/slots/index.ts delete mode 100644 packages/platform/sdk/src/endpoints/slots/types.ts delete mode 100644 packages/platform/sdk/src/index.ts delete mode 100644 packages/platform/sdk/src/lib/endpoints.ts delete mode 100644 packages/platform/sdk/src/lib/errors/cal-api-error.ts delete mode 100644 packages/platform/sdk/src/lib/errors/sdk-initialization-error.ts delete mode 100644 packages/platform/sdk/src/lib/http-caller.ts delete mode 100644 packages/platform/sdk/src/lib/sdk-secrets.ts delete mode 100644 packages/platform/sdk/src/swagger-types.d.ts delete mode 100644 packages/platform/sdk/src/types.ts delete mode 100644 packages/platform/sdk/tsconfig.build.json delete mode 100644 packages/platform/sdk/tsconfig.json diff --git a/packages/platform/atoms/booker/types.ts b/packages/platform/atoms/booker/types.ts new file mode 100644 index 0000000000..d560f5b19b --- /dev/null +++ b/packages/platform/atoms/booker/types.ts @@ -0,0 +1,50 @@ +import type { BookerProps } from "@calcom/features/bookings/Booker"; +import type { BookingResponse } from "@calcom/platform-libraries"; +import type { + ApiSuccessResponse, + ApiErrorResponse, + ApiSuccessResponseWithoutData, +} from "@calcom/platform-types"; +import type { BookerLayouts } from "@calcom/prisma/zod-utils"; + +import type { UseCreateBookingInput } from "../hooks/bookings/useCreateBooking"; + +export type BookerPlatformWrapperAtomProps = Omit< + BookerProps, + "username" | "entity" | "isTeamEvent" | "teamId" +> & { + rescheduleUid?: string; + rescheduledBy?: string; + bookingUid?: string; + entity?: BookerProps["entity"]; + // values for the booking form and booking fields + defaultFormValues?: { + firstName?: string; + lastName?: string; + guests?: string[]; + name?: string; + email?: string; + notes?: string; + rescheduleReason?: string; + } & Record; + handleCreateBooking?: (input: UseCreateBookingInput) => void; + onCreateBookingSuccess?: (data: ApiSuccessResponse) => void; + onCreateBookingError?: (data: ApiErrorResponse | Error) => void; + onCreateRecurringBookingSuccess?: (data: ApiSuccessResponse) => void; + onCreateRecurringBookingError?: (data: ApiErrorResponse | Error) => void; + onCreateInstantBookingSuccess?: (data: ApiSuccessResponse) => void; + onCreateInstantBookingError?: (data: ApiErrorResponse | Error) => void; + onReserveSlotSuccess?: (data: ApiSuccessResponse) => void; + onReserveSlotError?: (data: ApiErrorResponse) => void; + onDeleteSlotSuccess?: (data: ApiSuccessResponseWithoutData) => void; + onDeleteSlotError?: (data: ApiErrorResponse) => void; + locationUrl?: string; + view?: VIEW_TYPE; + metadata?: Record; + bannerUrl?: string; + onDryRunSuccess?: () => void; + hostsLimit?: number; + preventEventTypeRedirect?: boolean; +}; + +type VIEW_TYPE = keyof typeof BookerLayouts; diff --git a/packages/platform/atoms/cal-provider/BaseCalProvider.tsx b/packages/platform/atoms/cal-provider/BaseCalProvider.tsx index 479a290c35..01e50da4cd 100644 --- a/packages/platform/atoms/cal-provider/BaseCalProvider.tsx +++ b/packages/platform/atoms/cal-provider/BaseCalProvider.tsx @@ -1,7 +1,9 @@ import { TooltipProvider } from "@radix-ui/react-tooltip"; +import type { ReactNode } from "react"; import { useState } from "react"; import { useCallback } from "react"; +import type { API_VERSIONS_ENUM } from "@calcom/platform-constants"; import { IconSprites } from "@calcom/ui"; import deTranslations from "@calcom/web/public/static/locales/de/common.json"; import enTranslations from "@calcom/web/public/static/locales/en/common.json"; @@ -18,18 +20,30 @@ import { useTimezone } from "../hooks/useTimezone"; import { useUpdateUserTimezone } from "../hooks/useUpdateUserTimezone"; import http from "../lib/http"; import { Toaster } from "../src/components/ui/toaster"; -import { EN } from "./CalProvider"; import type { - CalProviderProps, - CalProviderLanguagesType, translationKeys, + CalProviderLanguagesType, enTranslationKeys, frTranslationKeys, ptBrTranslationKeys, deTranslationKeys, esTranslationKeys, nlTranslationKeys, -} from "./CalProvider"; + i18nProps, +} from "./languages"; +import { EN } from "./languages"; + +export type CalProviderProps = { + children?: ReactNode; + clientId: string; + accessToken?: string; + options: { refreshUrl?: string; apiUrl: string; readingDirection?: "ltr" | "rtl" }; + autoUpdateTimezone?: boolean; + onTimezoneChange?: () => void; + version?: API_VERSIONS_ENUM; + organizationId?: number; + isEmbed?: boolean; +} & i18nProps; export function BaseCalProvider({ clientId, diff --git a/packages/platform/atoms/cal-provider/CalProvider.tsx b/packages/platform/atoms/cal-provider/CalProvider.tsx index 7f3477f95c..5d1dca821d 100644 --- a/packages/platform/atoms/cal-provider/CalProvider.tsx +++ b/packages/platform/atoms/cal-provider/CalProvider.tsx @@ -1,89 +1,17 @@ "use client"; import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; -import { useEffect, type ReactNode } from "react"; +import { useEffect } from "react"; -import type { API_VERSIONS_ENUM } from "@calcom/platform-constants"; import { VERSION_2024_06_14 } from "@calcom/platform-constants"; -import type deTranslations from "@calcom/web/public/static/locales/de/common.json"; -import type enTranslations from "@calcom/web/public/static/locales/en/common.json"; -import type esTranslations from "@calcom/web/public/static/locales/es/common.json"; -import type frTranslations from "@calcom/web/public/static/locales/fr/common.json"; -import type nlTranslations from "@calcom/web/public/static/locales/nl/common.json"; -import type ptBrTranslations from "@calcom/web/public/static/locales/pt-BR/common.json"; import http from "../lib/http"; +import type { CalProviderProps } from "./BaseCalProvider"; import { BaseCalProvider } from "./BaseCalProvider"; - -export type enTranslationKeys = keyof typeof enTranslations; -export type frTranslationKeys = keyof typeof frTranslations; -export type deTranslationKeys = keyof typeof deTranslations; -export type esTranslationKeys = keyof typeof esTranslations; -export type ptBrTranslationKeys = keyof typeof ptBrTranslations; -export type nlTranslationKeys = keyof typeof nlTranslations; -export type translationKeys = - | enTranslationKeys - | frTranslationKeys - | deTranslationKeys - | esTranslationKeys - | ptBrTranslationKeys - | nlTranslationKeys; - -const FR = "fr"; -export const EN = "en"; -const PT_BR = "pt-BR"; -const DE = "de"; -const ES = "es"; -const NL = "nl"; -export const CAL_PROVIDER_LANGUAUES = [FR, EN, PT_BR, DE, ES, NL] as const; -export type CalProviderLanguagesType = (typeof CAL_PROVIDER_LANGUAUES)[number]; +import type { translationKeys } from "./languages"; const queryClient = new QueryClient(); -type i18nFrProps = { - labels?: Partial>; - language?: "fr"; -}; - -type i18nEnProps = { - labels?: Partial>; - language?: "en"; -}; - -type i18nPtBrProps = { - labels?: Partial>; - language?: "pt-BR"; -}; - -type i18nDeProps = { - labels?: Partial>; - language?: "de"; -}; - -type i18nEsProps = { - labels?: Partial>; - language?: "es"; -}; - -type i18nNlProps = { - labels?: Partial>; - language?: "nl"; -}; - -export type i18nProps = i18nFrProps | i18nEnProps | i18nPtBrProps | i18nDeProps | i18nEsProps | i18nNlProps; - -export type CalProviderProps = { - children?: ReactNode; - clientId: string; - accessToken?: string; - options: { refreshUrl?: string; apiUrl: string; readingDirection?: "ltr" | "rtl" }; - autoUpdateTimezone?: boolean; - onTimezoneChange?: () => void; - version?: API_VERSIONS_ENUM; - organizationId?: number; - isEmbed?: boolean; -} & i18nProps; - /** * Renders a CalProvider component. * diff --git a/packages/platform/atoms/cal-provider/languages.ts b/packages/platform/atoms/cal-provider/languages.ts new file mode 100644 index 0000000000..5828b65191 --- /dev/null +++ b/packages/platform/atoms/cal-provider/languages.ts @@ -0,0 +1,61 @@ +import type deTranslations from "@calcom/web/public/static/locales/de/common.json"; +import type enTranslations from "@calcom/web/public/static/locales/en/common.json"; +import type esTranslations from "@calcom/web/public/static/locales/es/common.json"; +import type frTranslations from "@calcom/web/public/static/locales/fr/common.json"; +import type nlTranslations from "@calcom/web/public/static/locales/nl/common.json"; +import type ptBrTranslations from "@calcom/web/public/static/locales/pt-BR/common.json"; + +export type enTranslationKeys = keyof typeof enTranslations; +export type frTranslationKeys = keyof typeof frTranslations; +export type deTranslationKeys = keyof typeof deTranslations; +export type esTranslationKeys = keyof typeof esTranslations; +export type ptBrTranslationKeys = keyof typeof ptBrTranslations; +export type nlTranslationKeys = keyof typeof nlTranslations; +export type translationKeys = + | enTranslationKeys + | frTranslationKeys + | deTranslationKeys + | esTranslationKeys + | ptBrTranslationKeys + | nlTranslationKeys; + +export const FR = "fr"; +export const EN = "en"; +export const PT_BR = "pt-BR"; +export const DE = "de"; +export const ES = "es"; +export const NL = "nl"; +export const CAL_PROVIDER_LANGUAUES = [FR, EN, PT_BR, DE, ES, NL] as const; +export type CalProviderLanguagesType = (typeof CAL_PROVIDER_LANGUAUES)[number]; + +type i18nFrProps = { + labels?: Partial>; + language?: "fr"; +}; + +type i18nEnProps = { + labels?: Partial>; + language?: "en"; +}; + +type i18nPtBrProps = { + labels?: Partial>; + language?: "pt-BR"; +}; + +type i18nDeProps = { + labels?: Partial>; + language?: "de"; +}; + +type i18nEsProps = { + labels?: Partial>; + language?: "es"; +}; + +type i18nNlProps = { + labels?: Partial>; + language?: "nl"; +}; + +export type i18nProps = i18nFrProps | i18nEnProps | i18nPtBrProps | i18nDeProps | i18nEsProps | i18nNlProps; diff --git a/packages/platform/atoms/event-types/hooks/usePlatformTabsNavigations.tsx b/packages/platform/atoms/event-types/hooks/usePlatformTabsNavigations.tsx index fa9e55e32b..a25dbd0b59 100644 --- a/packages/platform/atoms/event-types/hooks/usePlatformTabsNavigations.tsx +++ b/packages/platform/atoms/event-types/hooks/usePlatformTabsNavigations.tsx @@ -12,7 +12,7 @@ import { getPaymentAppData } from "@calcom/lib/getPaymentAppData"; import { useLocale } from "@calcom/lib/hooks/useLocale"; import type { VerticalTabItemProps } from "@calcom/ui"; -import type { PlatformTabs } from "../wrappers/EventTypePlatformWrapper"; +import type { PlatformTabs } from "../../event-types/wrappers/types"; type Props = { formMethods: UseFormReturn; diff --git a/packages/platform/atoms/event-types/wrappers/EventTypePlatformWrapper.tsx b/packages/platform/atoms/event-types/wrappers/EventTypePlatformWrapper.tsx index badf5fa97a..ad4bd54672 100644 --- a/packages/platform/atoms/event-types/wrappers/EventTypePlatformWrapper.tsx +++ b/packages/platform/atoms/event-types/wrappers/EventTypePlatformWrapper.tsx @@ -12,7 +12,7 @@ import type { EventAvailabilityTabCustomClassNames } from "@calcom/features/even import type { EventLimitsTabCustomClassNames } from "@calcom/features/eventtypes/components/tabs/limits/EventLimitsTab"; import type { EventRecurringTabCustomClassNames } from "@calcom/features/eventtypes/components/tabs/recurring/RecurringEventController"; import type { EventSetupTabCustomClassNames } from "@calcom/features/eventtypes/components/tabs/setup/EventSetupTab"; -import type { EventTypeSetupProps, FormValues, TabMap } from "@calcom/features/eventtypes/lib/types"; +import type { EventTypeSetupProps, FormValues } from "@calcom/features/eventtypes/lib/types"; import { useLocale } from "@calcom/lib/hooks/useLocale"; import { SchedulingType } from "@calcom/prisma/enums"; @@ -34,8 +34,7 @@ import EventPaymentsTabPlatformWrapper from "./EventPaymentsTabPlatformWrapper"; import EventRecurringTabPlatformWrapper from "./EventRecurringTabPlatformWrapper"; import SetupTab from "./EventSetupTabPlatformWrapper"; import EventTeamAssignmentTabPlatformWrapper from "./EventTeamAssignmentTabPlatformWrapper"; - -export type PlatformTabs = keyof Omit; +import type { PlatformTabs } from "./types"; export type EventTypeCustomClassNames = { atomsWrapper?: string; diff --git a/packages/platform/atoms/event-types/wrappers/types.ts b/packages/platform/atoms/event-types/wrappers/types.ts new file mode 100644 index 0000000000..67ad4c3e81 --- /dev/null +++ b/packages/platform/atoms/event-types/wrappers/types.ts @@ -0,0 +1,3 @@ +import type { TabMap } from "@calcom/features/eventtypes/lib/types"; + +export type PlatformTabs = keyof Omit; diff --git a/packages/platform/atoms/hooks/useAtomsContext.ts b/packages/platform/atoms/hooks/useAtomsContext.ts index e252089483..9e589d1696 100644 --- a/packages/platform/atoms/hooks/useAtomsContext.ts +++ b/packages/platform/atoms/hooks/useAtomsContext.ts @@ -2,7 +2,7 @@ import { createContext, useContext } from "react"; -import type { translationKeys, CalProviderLanguagesType } from "../cal-provider/CalProvider"; +import type { CalProviderLanguagesType, translationKeys } from "../cal-provider/languages"; import type http from "../lib/http"; export interface IAtomsContextOptions { diff --git a/packages/platform/sdk/.release-it.js b/packages/platform/sdk/.release-it.js deleted file mode 100644 index b677ad6ff0..0000000000 --- a/packages/platform/sdk/.release-it.js +++ /dev/null @@ -1,7 +0,0 @@ -module.exports = { - git: { - commitMessage: "chore: SDK Release v${version}", - requireUpstream: true, - requireCommits: true, - }, -}; diff --git a/packages/platform/sdk/README.md b/packages/platform/sdk/README.md deleted file mode 100644 index c6eff4d7f6..0000000000 --- a/packages/platform/sdk/README.md +++ /dev/null @@ -1,69 +0,0 @@ -

- - Logo - -
- Cal.com SDK -

- -![SDK Version](https://img.shields.io/github/package-json/v/calcom/cal.com/main?filename=packages%2Fplatform%2Fsdk%2Fpackage.json) - -## Install - -```bash -yarn add @calcom/sdk -``` - -## Usage - -To use the Cal.com SDK you need to have an OAuth Client set up, which you can obtain [here](https://app.cal.com/settings/organizations/platform/oauth-clients/). - -```typescript -import { Cal } from "@calcom/sdk"; - -const sdk = new Cal("your_client_id", { - clientSecret: "your_client_secret", -}); -``` - -### Authenticating as a User - -The SDK is also meant to be used as an authenticated user, to do that, you need to pass the `accessToken` to the `authOptions` in the SDK constructor. - -```typescript -const authedSdk = new Cal("your_client_id", { - clientSecret: "your_client_secret", - accessToken: "your_user_access_token", -}); - -const schedule = await authedSdk.schedules.createSchedule({ - availabilities: [ - { - days: [1, 2, 3, 4, 5, 6], - startTime: "09:00:00", - endTime: "17:00:00", - }, - ], - isDefault: true, - name: "Default Schedule", - timeZone: "America/Argentina/Buenos_Aires", -}); -``` - -You can manually refresh access tokens, or you can let the SDK handle token refreshes via the `handleRefresh` option. - -To manually update an access token, you can use the following snippet: - -```typescript -sdk.secrets().updateAccessToken(oauth.accessToken, oauth.refreshToken); -``` - -## Configuration - -| Option | Required | Description | -| -------------------------- | -------- | --------------------------------------------------------------------------------------------------- | -| `authOptions.clientSecret` | `TRUE` | The Client Secret corresponding to the client ID passed as the first parameter. | -| `authOptions.accessToken` | `FALSE` | `Optional` Access token when authenticating as a specific user. | -| `authOptions.refreshToken` | `FALSE` | `Optional` If provided, the SDK can handle refreshing access tokens automatically when they expire. | -| `options.baseUrl` | `FALSE` | `Defaults to https://api.cal.com`. The base URI for the Cal.com platform API | -| `options.handleRefresh` | `FALSE` | Whether the SDK should handle automatic refreshes for expired access tokens. | diff --git a/packages/platform/sdk/example/index.ts b/packages/platform/sdk/example/index.ts deleted file mode 100644 index f5828f435e..0000000000 --- a/packages/platform/sdk/example/index.ts +++ /dev/null @@ -1,54 +0,0 @@ -import { CalSdk } from "../src/cal"; - -(async () => { - const sdk = new CalSdk( - "cltd1rit60001p51en7z0sq75", - { - accessToken: - "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0eXBlIjoiYWNjZXNzX3Rva2VuIiwiY2xpZW50SWQiOiJjbHRkMXJpdDYwMDAxcDUxZW43ejBzcTc1Iiwib3duZXJJZCI6OSwiaWF0IjoxNzA5NTYzNTMyfQ.tpUSk0gREAZPJA2aXnHPpVc-9Bbcj2w90kVH2Qii6RE", - clientSecret: - "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoidGVzdCBjbGllbnQiLCJwZXJtaXNzaW9ucyI6MjU1LCJyZWRpcmVjdFVyaXMiOlsiaHR0cDovL2xvY2FsaG9zdDozMDAwL2F1dGgvcGxhdGZvcm0vYXV0aG9yaXplIl0sImlhdCI6MTcwOTU2MzE1N30.j8cxam5pfPG45BAMCuXt7bm3GM7JO_UnWL9wPVGcr5U", - refreshToken: - "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0eXBlIjoicmVmcmVzaF90b2tlbiIsImNsaWVudElkIjoiY2x0ZDFyaXQ2MDAwMXA1MWVuN3owc3E3NSIsIm93bmVySWQiOjksImlhdCI6MTcwOTU2MzUzMn0.SHMikF_9uJvqJFAiWAnI0BsRQSJCTbaAXPi1B99sWNk", - }, - { - baseUrl: "http://localhost:5555/api", - handleRefresh: true, - httpRetries: { - maxAmount: 5, - }, - } - ); - - try { - const oauth = await sdk.oauth.exchange({ - authorizationCode: "cltd1wlqn0002p51ektm2byp6", - }); - - console.log("finalized oauth", oauth.accessToken); - - // force updating - sdk.secrets().updateAccessToken(oauth.accessToken, oauth.refreshToken); - - const schedule = await sdk.schedules.createSchedule({ - availabilities: [ - { - days: [1, 2, 3, 4, 5, 6], - startTime: "10:00:00", - endTime: "14:00:00", - }, - ], - isDefault: true, - name: "Default Schedule Test", - timeZone: "America/Argentina/Buenos_Aires", - }); - - console.log(schedule); - - const deleted = await sdk.schedules.deleteSchedule(schedule.id); - - console.log(deleted); - } catch (err) { - console.log("error", err); - } -})(); diff --git a/packages/platform/sdk/package.json b/packages/platform/sdk/package.json deleted file mode 100644 index 11b58905e7..0000000000 --- a/packages/platform/sdk/package.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "name": "@calcom/sdk", - "version": "1.0.1", - "description": "Cal.com platform SDK.", - "main": "dist/index.cjs.js", - "module": "dist/index.esm.js", - "types": "dist/index.d.ts", - "files": [ - "dist" - ], - "scripts": { - "build": "rollup -c --bundleConfigAsCjs", - "release": "release-it --only-version", - "generate-types": "openapi-typescript http://localhost:5555/docs-yaml -o ./src/swagger-types.d.ts" - }, - "packageManager": "yarn@3.4.1", - "devDependencies": { - "@rollup/plugin-commonjs": "^25.0.7", - "@rollup/plugin-json": "^6.1.0", - "@rollup/plugin-node-resolve": "^15.2.3", - "@rollup/plugin-typescript": "^11.1.6", - "openapi-typescript": "^6.7.5", - "release-it": "^17.1.1", - "rollup": "^4.12.0", - "rollup-plugin-bundle-size": "^1.0.3", - "ts-essentials": "^9.4.1", - "typescript": "^5.3.3" - }, - "dependencies": { - "axios": "^1.6.7", - "axios-retry": "^4.0.0", - "lodash": "^4.17.21", - "zod": "^3.22.4" - } -} diff --git a/packages/platform/sdk/rollup.config.js b/packages/platform/sdk/rollup.config.js deleted file mode 100644 index c3b13df4b4..0000000000 --- a/packages/platform/sdk/rollup.config.js +++ /dev/null @@ -1,30 +0,0 @@ -import commonjs from "@rollup/plugin-commonjs"; -import json from "@rollup/plugin-json"; -import { nodeResolve } from "@rollup/plugin-node-resolve"; -import typescript from "@rollup/plugin-typescript"; -import bundleSize from "rollup-plugin-bundle-size"; - -import pkg from "./package.json"; - -/** @type {import('rollup').RollupOptions} */ -// eslint-disable-next-line import/no-anonymous-default-export -export default { - input: "src/index.ts", - output: [ - { - file: pkg.main, - format: "cjs", - }, - { - file: pkg.module, - format: "es", - }, - ], - plugins: [ - json(), - commonjs(), - nodeResolve(), - typescript({ tsconfig: "./tsconfig.build.json" }), - bundleSize(), - ], -}; diff --git a/packages/platform/sdk/src/cal.ts b/packages/platform/sdk/src/cal.ts deleted file mode 100644 index bf27f4a26f..0000000000 --- a/packages/platform/sdk/src/cal.ts +++ /dev/null @@ -1,78 +0,0 @@ -import axios from "axios"; -import axiosRetry from "axios-retry"; - -import { Bookings } from "./endpoints/bookings"; -import { Events } from "./endpoints/events"; -import { EventTypes } from "./endpoints/events/event-types"; -import { ManagedUsers } from "./endpoints/managed-users"; -import { OAuthFlow } from "./endpoints/oauth-flow"; -import { Schedules } from "./endpoints/schedules"; -import { Slots } from "./endpoints/slots"; -import { SdkInitializationError } from "./lib/errors/sdk-initialization-error"; -import { HttpCaller } from "./lib/http-caller"; -import { SdkSecrets } from "./lib/sdk-secrets"; -import type { CalSdkConstructorOptions, SdkAuthOptions } from "./types"; - -export class CalSdk { - public httpCaller: HttpCaller; - - slots: Slots; - bookings: Bookings; - events: Events; - oauth: OAuthFlow; - eventTypes: EventTypes; - schedules: Schedules; - users: ManagedUsers; - - private readonly _secrets: SdkSecrets; - - constructor( - public readonly clientId: string, - protected readonly authOptions: SdkAuthOptions, - protected readonly options: CalSdkConstructorOptions = { - baseUrl: "https://api.cal.com/", // don't set api version here as endpoints may have version-neutral or specific values. - } - ) { - if (!authOptions.accessToken && !authOptions.clientSecret) { - throw new SdkInitializationError("Either 'accessToken' or 'clientSecret' are required in authOptions"); - } - - this.httpCaller = new HttpCaller(this.clientId, this._createAxiosClientBase()); - this._secrets = new SdkSecrets( - authOptions.clientSecret ?? "", - authOptions.accessToken ?? "", - authOptions.refreshToken ?? "", - this.httpCaller - ); - - // avoid cyclic referencing. - this.httpCaller.secrets = this._secrets; - - this.slots = new Slots(this); - this.bookings = new Bookings(this); - this.events = new Events(this); - this.oauth = new OAuthFlow(this); - this.eventTypes = new EventTypes(this); - this.schedules = new Schedules(this); - this.users = new ManagedUsers(this); - } - - private _createAxiosClientBase() { - const axiosClient = axios.create({ - baseURL: this.options.baseUrl, - }); - - // implement retry logic with an exponential back-off delay - axiosRetry(axiosClient, { - retries: this.options.httpRetries?.maxAmount ?? 3, - retryDelay: axiosRetry.exponentialDelay, - retryCondition: axiosRetry.isNetworkOrIdempotentRequestError, - }); - - return axiosClient; - } - - public secrets() { - return this._secrets; - } -} diff --git a/packages/platform/sdk/src/endpoints/bookings/index.ts b/packages/platform/sdk/src/endpoints/bookings/index.ts deleted file mode 100644 index 9ec93873b2..0000000000 --- a/packages/platform/sdk/src/endpoints/bookings/index.ts +++ /dev/null @@ -1,8 +0,0 @@ -import type { CalSdk } from "../../cal"; -import { EndpointHandler } from "../endpoint-handler"; - -export class Bookings extends EndpointHandler { - constructor(private readonly sdk: CalSdk) { - super("bookings", sdk); - } -} diff --git a/packages/platform/sdk/src/endpoints/endpoint-handler.ts b/packages/platform/sdk/src/endpoints/endpoint-handler.ts deleted file mode 100644 index caf7680c7a..0000000000 --- a/packages/platform/sdk/src/endpoints/endpoint-handler.ts +++ /dev/null @@ -1,34 +0,0 @@ -import type { AxiosRequestConfig } from "axios"; -// eslint-disable-next-line no-restricted-imports -import merge from "lodash/merge"; -import { assert } from "ts-essentials"; - -import type { CalSdk } from "../cal"; - -export abstract class EndpointHandler { - protected constructor(private readonly key: string, private readonly calSdk: CalSdk) {} - - withForAtomParam(forAtom: boolean, config?: AxiosRequestConfig) { - if (!forAtom) return config; - - return merge(config, { - params: { - for: "atom", - }, - }); - } - - protected assertAccessToken(methodName: string) { - assert( - this.calSdk.secrets().isAccessTokenSet(), - `Access token must be set to call the ${this.key}/${methodName} function.` - ); - } - - protected assertClientSecret(methodName: string) { - assert( - !!this.calSdk.secrets().getClientSecret(), - `Client secret must be set to use the ${this.key}/${methodName} function.` - ); - } -} diff --git a/packages/platform/sdk/src/endpoints/events/event-types/index.ts b/packages/platform/sdk/src/endpoints/events/event-types/index.ts deleted file mode 100644 index f86d5efb53..0000000000 --- a/packages/platform/sdk/src/endpoints/events/event-types/index.ts +++ /dev/null @@ -1,38 +0,0 @@ -import type { CalSdk } from "../../../cal"; -import { Endpoints } from "../../../lib/endpoints"; -import type { BasicPlatformResponse } from "../../../types"; -import { EndpointHandler } from "../../endpoint-handler"; -import type { CreateEventTypeArgs, EventType, GetEventTypeByIdArgs } from "./types"; - -export class EventTypes extends EndpointHandler { - constructor(private readonly sdk: CalSdk) { - super("event-types", sdk); - } - - async createEventType(args: CreateEventTypeArgs): Promise { - this.assertAccessToken("createEventType"); - - const { data } = await this.sdk.httpCaller.post>( - Endpoints.CREATE_EVENT_TYPE, - { - body: args, - } - ); - - return data; - } - - async getEventType(args: GetEventTypeByIdArgs): Promise { - this.assertAccessToken("getEventType"); - - const { data } = await this.sdk.httpCaller.get>( - Endpoints.GET_EVENT_TYPE_BY_ID, - { - urlParams: [args.id], - config: this.withForAtomParam(args.forAtom ?? false), - } - ); - - return data; - } -} diff --git a/packages/platform/sdk/src/endpoints/events/event-types/types.ts b/packages/platform/sdk/src/endpoints/events/event-types/types.ts deleted file mode 100644 index 3c1eba5000..0000000000 --- a/packages/platform/sdk/src/endpoints/events/event-types/types.ts +++ /dev/null @@ -1,66 +0,0 @@ -import { z } from "zod"; - -const CreateEventTypesSchema = z.object({ - length: z.number().min(1), - slug: z.string(), - title: z.string(), -}); - -const GetEventTypeByIdSchema = z.object({ - id: z.string(), - forAtom: z.boolean().optional(), -}); - -export type CreateEventTypeArgs = z.infer; -export type GetEventTypeByIdArgs = z.infer; - -export type EventType = { - id: string; - title: string; - slug: string; - description: string | null; - position: number; - locations: string[] | null; - length: number; - offsetStart: number; - hidden: boolean; - userId: number; - profileId: number | null; - teamId: number | null; - eventName: string | null; - parentId: number | null; - bookingFields: unknown | null; - timeZone: string | null; - periodType: "UNLIMITED" | "ROLLING" | "RANGE"; - periodStartDate: string | null; - periodEndDate: string | null; - periodDays: number | null; - periodCountCalendarDays: boolean | null; - lockTimeZoneToggleOnBookingPage: boolean; - requiresConfirmation: boolean; - requiresBookerEmailVerification: boolean; - recurringEvent?: boolean; - disableGuests: boolean; - hideCalendarNotes: boolean; - minimumBookingNotice: number; - beforeEventBuffer: number; - afterEventBuffer: number; - seatsPerTimeSlot: number | null; - onlyShowFirstAvailableSlot: boolean; - seatsShowAttendees: boolean; - seatsShowAvailabilityCount: boolean; - schedulingType: unknown | null; - scheduleId: number | null; - price: number; - currency: "usd"; - slotInterval: number | null; - metadata: Record | null; - successRedirectUrl: string | null; - bookingLimits: number | null; - durationLimits: number | null; - isInstantEvent: boolean; - instantMeetingParameters: string[]; - instantMeetingExpiryTimeOffsetInSeconds: number; - assignAllTeamMembers: boolean; - useEventTypeDestinationCalendarEmail: boolean; -}; diff --git a/packages/platform/sdk/src/endpoints/events/index.ts b/packages/platform/sdk/src/endpoints/events/index.ts deleted file mode 100644 index 3b4deee66b..0000000000 --- a/packages/platform/sdk/src/endpoints/events/index.ts +++ /dev/null @@ -1,21 +0,0 @@ -import type { CalSdk } from "../../cal"; -import { Endpoints } from "../../lib/endpoints"; -import type { BasicPlatformResponse } from "../../types"; -import { EndpointHandler } from "../endpoint-handler"; -import type { Event, GetPublicEventArgs } from "./types"; - -export class Events extends EndpointHandler { - constructor(private readonly sdk: CalSdk) { - super("events", sdk); - } - - async getPublicEvent(input: GetPublicEventArgs): Promise { - const { data } = await this.sdk.httpCaller.get>(Endpoints.GET_PUBLIC_EVENT, { - config: { - params: input, - }, - }); - - return data; - } -} diff --git a/packages/platform/sdk/src/endpoints/events/types.ts b/packages/platform/sdk/src/endpoints/events/types.ts deleted file mode 100644 index 04d21e20b5..0000000000 --- a/packages/platform/sdk/src/endpoints/events/types.ts +++ /dev/null @@ -1,86 +0,0 @@ -import { z } from "zod"; - -const GetPublicEventSchema = z.object({ - username: z.string().transform((s) => s.toLowerCase()), - eventSlug: z.string(), - isTeamEvent: z.boolean().optional(), - org: z.string().optional(), -}); - -export type GetPublicEventArgs = z.infer; - -type User = { - // todo expand -}; - -type TeamParent = { - slug: string; - name: string; -}; - -type Team = { - parentId: string; - metadata: Record; - brandColor: string; - darkBrandColor: string; - slug: string; - name: string; - logo: string; - theme: string; - parent: TeamParent; -}; - -type WorkflowStep = { - // todo expand -}; - -type Workflow = { - steps: WorkflowStep[]; -}; - -export type Event = { - id: string; - title: string; - description: string; - eventName: string; - slug: string; - isInstantEvent: boolean; - instantMeetingParameters: string[]; - instantMeetingExpiryTimeOffsetInSeconds: number; - aiPhoneCallConfig: { - eventTypeId: number; - enabled: boolean; - generalPrompt: string; - beginMessage: string | null; - yourPhoneNumber: string; - numberToCall: string; - guestName?: string; - guestEmail?: string; - guestCompany?: string; - templateType: string; - schedulerName?: string; - }; - schedulingType: string; - length: number; - locations: string[]; // Define more specifically if possible - customInputs: unknown; // Define more specifically if possible - disableGuests: boolean; - lockTimeZoneToggleOnBookingPage: boolean; - requiresConfirmation: boolean; - requiresBookerEmailVerification: boolean; - recurringEvent: boolean; - price: number; - currency: string; - seatsPerTimeSlot: number; - seatsShowAvailabilityCount: boolean; - bookingFields: unknown; // Define more specifically if possible - team: Team; - successRedirectUrl: string; - workflows: Workflow[]; - hosts: { - user: User; - }[]; - owner: User; - hidden: boolean; - assignAllTeamMembers: boolean; -}; diff --git a/packages/platform/sdk/src/endpoints/managed-users/index.ts b/packages/platform/sdk/src/endpoints/managed-users/index.ts deleted file mode 100644 index 3d35789f1d..0000000000 --- a/packages/platform/sdk/src/endpoints/managed-users/index.ts +++ /dev/null @@ -1,54 +0,0 @@ -import type { CalSdk } from "../../cal"; -import { Endpoints } from "../../lib/endpoints"; -import type { BasicPlatformResponse, PaginationOptions } from "../../types"; -import { EndpointHandler } from "../endpoint-handler"; -import type { CreateUserArgs, CreateUserResponse, User } from "./types"; - -export class ManagedUsers extends EndpointHandler { - constructor(private readonly sdk: CalSdk) { - super("users", sdk); - } - - async getManagedUsers(pagination?: PaginationOptions): Promise { - this.assertClientSecret("getManagedUsers"); - - const { data } = await this.sdk.httpCaller.get>( - Endpoints.GET_MANAGED_USERS_BY_CLIENT_ID, - { - urlParams: [this.sdk.clientId], - config: { - params: pagination, - }, - } - ); - - return data; - } - - async createManagedUser(input: CreateUserArgs): Promise { - this.assertClientSecret("createManagedUser"); - - const { data } = await this.sdk.httpCaller.post>( - Endpoints.CREATE_MANAGED_USER, - { - urlParams: [this.sdk.clientId], - body: input, - } - ); - - return data; - } - - async getManagedUser(userId: number): Promise { - this.assertClientSecret("getManagedUser"); - - const { data } = await this.sdk.httpCaller.get>( - Endpoints.GET_MANAGED_USER_BY_ID, - { - urlParams: [this.sdk.clientId, userId.toString()], - } - ); - - return data; - } -} diff --git a/packages/platform/sdk/src/endpoints/managed-users/types.ts b/packages/platform/sdk/src/endpoints/managed-users/types.ts deleted file mode 100644 index 85fb7cebd0..0000000000 --- a/packages/platform/sdk/src/endpoints/managed-users/types.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { z } from "zod"; - -export type User = { - id: number; - email: string; - username: string; -}; - -const CreateUserSchema = z.object({ - email: z.string(), - name: z.string().optional(), - timeFormat: z.number().optional(), - isWeekStart: z.string().optional(), - timeZone: z.string().optional(), -}); - -export type CreateUserArgs = z.infer; - -export type CreateUserResponse = { - user: User; - accessToken: string; - refreshToken: string; -}; diff --git a/packages/platform/sdk/src/endpoints/oauth-flow/index.ts b/packages/platform/sdk/src/endpoints/oauth-flow/index.ts deleted file mode 100644 index b224363a57..0000000000 --- a/packages/platform/sdk/src/endpoints/oauth-flow/index.ts +++ /dev/null @@ -1,32 +0,0 @@ -import type { CalSdk } from "../../cal"; -import { Endpoints } from "../../lib/endpoints"; -import type { BasicPlatformResponse } from "../../types"; -import { EndpointHandler } from "../endpoint-handler"; -import type { ExchangeCodeParams, ExchangeCodeResponse } from "./types"; - -export class OAuthFlow extends EndpointHandler { - constructor(private readonly sdk: CalSdk) { - super("oauth", sdk); - } - - async exchange(params: ExchangeCodeParams): Promise { - this.assertClientSecret("exchange"); - - const { data } = await this.sdk.httpCaller.post>( - Endpoints.EXCHANGE_OAUTH_AUTH_TOKEN, - { - urlParams: [this.sdk.clientId], - body: { - clientSecret: this.sdk.secrets().getClientSecret(), - }, - config: { - headers: { - Authorization: `Bearer ${params.authorizationCode}`, - }, - }, - } - ); - - return data; - } -} diff --git a/packages/platform/sdk/src/endpoints/oauth-flow/types.ts b/packages/platform/sdk/src/endpoints/oauth-flow/types.ts deleted file mode 100644 index 478b19c19f..0000000000 --- a/packages/platform/sdk/src/endpoints/oauth-flow/types.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { z } from "zod"; - -const ExchangeCodeSchema = z.object({ - authorizationCode: z.string(), -}); - -export type ExchangeCodeParams = z.infer; - -export type ExchangeCodeResponse = { - accessToken: string; - refreshToken: string; -}; diff --git a/packages/platform/sdk/src/endpoints/schedules/index.ts b/packages/platform/sdk/src/endpoints/schedules/index.ts deleted file mode 100644 index d24c30fc86..0000000000 --- a/packages/platform/sdk/src/endpoints/schedules/index.ts +++ /dev/null @@ -1,106 +0,0 @@ -import type { CalSdk } from "../../cal"; -import { Endpoints } from "../../lib/endpoints"; -import type { BasicPlatformResponse } from "../../types"; -import { EndpointHandler } from "../endpoint-handler"; -import type { - CreateScheduleArgs, - FormattedSchedule, - GetScheduleByIdArgs, - Schedule, - SupportedTimezone, - UpdateScheduleArgs, -} from "./types"; - -export class Schedules extends EndpointHandler { - constructor(private readonly sdk: CalSdk) { - super("schedules", sdk); - } - - async createSchedule(args: CreateScheduleArgs): Promise { - this.assertAccessToken("createSchedule"); - - const { data } = await this.sdk.httpCaller.post>( - Endpoints.CREATE_SCHEDULE, - { - body: args, - config: this.withForAtomParam(args.forAtom ?? false), - } - ); - - return data; - } - - async getDefaultSchedule(forAtom?: boolean): Promise { - this.assertAccessToken("getDefaultSchedule"); - - const { data } = await this.sdk.httpCaller.get>( - Endpoints.GET_DEFAULT_SCHEDULE, - { - config: this.withForAtomParam(forAtom ?? false), - } - ); - - return data; - } - - async getSchedules(forAtom?: boolean): Promise { - this.assertAccessToken("getSchedules"); - - const { data } = await this.sdk.httpCaller.get>( - Endpoints.GET_ALL_SCHEDULES, - { - config: this.withForAtomParam(forAtom ?? false), - } - ); - - return data; - } - - async getScheduleById(args: GetScheduleByIdArgs): Promise { - this.assertAccessToken("getScheduleById"); - - const { data } = await this.sdk.httpCaller.get>( - Endpoints.GET_SCHEDULE_BY_ID, - { - urlParams: [args.id.toString()], - config: this.withForAtomParam(args.forAtom ?? false), - } - ); - - return data; - } - - async getSupportedTimezones(): Promise { - const { data } = await this.sdk.httpCaller.get>( - Endpoints.GET_SUPPORTED_TIMEZONES - ); - - return data; - } - - async updateSchedule(scheduleId: number, args: UpdateScheduleArgs) { - this.assertAccessToken("updateSchedule"); - - const { data } = await this.sdk.httpCaller.patch>( - Endpoints.UPDATE_SCHEDULE_BY_ID, - { - urlParams: [scheduleId.toString()], - body: args, - } - ); - - return data; - } - async deleteSchedule(scheduleId: number): Promise { - this.assertAccessToken("deleteSchedule"); - - const { status } = await this.sdk.httpCaller.delete( - Endpoints.DELETE_SCHEDULE_BY_ID, - { - urlParams: [scheduleId.toString()], - } - ); - - return status === "success"; - } -} diff --git a/packages/platform/sdk/src/endpoints/schedules/types.ts b/packages/platform/sdk/src/endpoints/schedules/types.ts deleted file mode 100644 index e16de9e52a..0000000000 --- a/packages/platform/sdk/src/endpoints/schedules/types.ts +++ /dev/null @@ -1,63 +0,0 @@ -import type { ElementOf } from "ts-essentials"; -import { z } from "zod"; - -const CreateScheduleSchema = z.object({ - name: z.string(), - timeZone: z.string(), - isDefault: z.boolean().default(true), - availabilities: z - .object({ - days: z.number().array(), - startTime: z.string(), - endTime: z.string(), - }) - .array(), - forAtom: z.boolean().optional(), -}); - -const GetScheduleByIdSchema = z.object({ - id: z.number(), - forAtom: z.boolean().optional(), -}); - -const UpdateScheduleSchema = z.object({ - timeZone: z.string().optional(), - name: z.string().optional(), - isDefault: z.boolean().optional(), - schedule: z - .object({ - start: z.date(), - end: z.date(), - }) - .array() - .optional(), - dateOverrides: z.object({ - ranges: z.object({}), - }), -}); - -export type CreateScheduleArgs = z.infer; -export type GetScheduleByIdArgs = z.infer; -export type UpdateScheduleArgs = z.infer; - -export type Schedule = CreateScheduleArgs & { - id: number; - userId: number; -}; - -export type FormattedSchedule = { - id: number; - name: string; - isManaged: boolean; - schedule: ElementOf; - timeZone: string; - isDefault: boolean; - isLastSchedule: boolean; - readOnly: boolean; -}; - -export type SupportedTimezone = { - city: string; - timezone: string; - pop: number; -}; diff --git a/packages/platform/sdk/src/endpoints/slots/index.ts b/packages/platform/sdk/src/endpoints/slots/index.ts deleted file mode 100644 index 9dc8bc88ca..0000000000 --- a/packages/platform/sdk/src/endpoints/slots/index.ts +++ /dev/null @@ -1,46 +0,0 @@ -import type { CalSdk } from "../../cal"; -import { Endpoints } from "../../lib/endpoints"; -import { type BasicPlatformResponse, type ResponseStatus } from "../../types"; -import { EndpointHandler } from "../endpoint-handler"; -import type { - AvailableSlots, - GetAvaialbleSlotsArgs, - RemoveSelectedSlotArgs, - ReserveSlotArgs, - SlotUID, -} from "./types"; - -export class Slots extends EndpointHandler { - constructor(private readonly sdk: CalSdk) { - super("slots", sdk); - } - - async reserveSlot(args: ReserveSlotArgs): Promise { - const { data } = await this.sdk.httpCaller.post>(Endpoints.RESERVE_SLOT, { - body: args, - }); - return data; - } - - async removeSelectedSlot(args: RemoveSelectedSlotArgs): Promise { - const { status } = await this.sdk.httpCaller.delete( - Endpoints.DELETE_SELECTED_SLOT, - { - config: { params: args }, - } - ); - return status === "success" ? "success" : "error"; - } - - async getAvailableSlots(args: GetAvaialbleSlotsArgs): Promise { - const { data } = await this.sdk.httpCaller.get>( - Endpoints.AVAILABLE_SLOTS, - { - config: { - params: args, - }, - } - ); - return data; - } -} diff --git a/packages/platform/sdk/src/endpoints/slots/types.ts b/packages/platform/sdk/src/endpoints/slots/types.ts deleted file mode 100644 index 825c497183..0000000000 --- a/packages/platform/sdk/src/endpoints/slots/types.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { z } from "zod"; - -export type SlotUID = string; - -type Slot = Record< - SlotUID, - { - time: string; - attendees?: number; - bookingUid?: string; - } ->; - -export type AvailableSlots = Slot[]; - -const ReserveSlotSchema = z.object({ - eventTypeId: z.number(), - slotUtcStartDate: z.date(), - slotUtcEndDate: z.date(), - bookingUid: z.string().optional(), -}); - -const RemoveSelectedSlotSchema = z.object({ - uid: z.string().optional(), -}); - -const GetAvailableSlotsSchema = z.object({ - startTime: z.date(), - endTime: z.date(), - eventTypeId: z.number().optional(), - usernameList: z.string().array().optional(), - debug: z.boolean().optional(), - duration: z.number().optional(), -}); - -export type ReserveSlotArgs = z.infer; -export type RemoveSelectedSlotArgs = z.infer; -export type GetAvaialbleSlotsArgs = z.infer; diff --git a/packages/platform/sdk/src/index.ts b/packages/platform/sdk/src/index.ts deleted file mode 100644 index d90bb324b8..0000000000 --- a/packages/platform/sdk/src/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export { CalSdk as Cal } from "./cal"; -export * from "./types"; diff --git a/packages/platform/sdk/src/lib/endpoints.ts b/packages/platform/sdk/src/lib/endpoints.ts deleted file mode 100644 index b40c6b7ec2..0000000000 --- a/packages/platform/sdk/src/lib/endpoints.ts +++ /dev/null @@ -1,184 +0,0 @@ -/* eslint-disable @typescript-eslint/no-non-null-assertion */ -import { ApiVersion } from "../types"; - -type BaseEndpointDeclaration = { - auth: "public" | "access_token" | "secret"; - apiVersion: ApiVersion; -}; - -// Define a type for static URIs -type StaticUriEndpoint = BaseEndpointDeclaration & { - uri: string; - constructUriFromObject?: never; - constructUriFromArray?: never; -}; - -// Introduce a generic type for dynamic URIs, allowing for explicit parameter type declaration -type DynamicUriEndpoint = BaseEndpointDeclaration & { - uri?: never; // Ensure uri is not used here - constructUriFromArray?: (params: string[]) => string; - constructUriFromObject?: (params: Record) => string; -}; - -// Create a discriminated union of the two types, incorporating generics -type EndpointDeclaration = StaticUriEndpoint | DynamicUriEndpoint; - -export enum Endpoints { - RESERVE_SLOT = "RESERVE_SLOT", - DELETE_SELECTED_SLOT = "DELETE_SELECTED_SLOT", - AVAILABLE_SLOTS = "AVAILABLE_SLOTS", - GET_PUBLIC_EVENT = "GET_PUBLIC_EVENT", - EXCHANGE_OAUTH_AUTH_TOKEN = "EXCHANGE_OAUTH_AUTH_TOKEN", - REFRESH_OAUTH_TOKEN = "REFRESH_OAUTH_TOKEN", - CREATE_EVENT_TYPE = "CREATE_EVENT_TYPE", - GET_EVENT_TYPE_BY_ID = "GET_EVENT_TYPE_BY_ID", - CREATE_SCHEDULE = "CREATE_SCHEDULE", - GET_DEFAULT_SCHEDULE = "GET_DEFAULT_SCHEDULE", - GET_ALL_SCHEDULES = "GET_ALL_SCHEDULES", - GET_SCHEDULE_BY_ID = "GET_SCHEDULE_BY_ID", - GET_SUPPORTED_TIMEZONES = "GET_SUPPORTED_TIMEZONES", - UPDATE_SCHEDULE_BY_ID = "UPDATE_SCHEDULE_BY_ID", - DELETE_SCHEDULE_BY_ID = "DELETE_SCHEDULE_BY_ID", - GET_MANAGED_USERS_BY_CLIENT_ID = "GET_MANAGED_USERS_BY_CLIENT_ID", - CREATE_MANAGED_USER = "CREATE_MANAGED_USER", - GET_MANAGED_USER_BY_ID = "GET_MANAGED_USER_BY_ID", -} - -const publicEndpoint = (uri: string, version = ApiVersion.NEUTRAL): EndpointDeclaration => ({ - uri, - auth: "public", - apiVersion: version, -}); - -const constructUri = ( - endpointData: { - constructUriFromArray?: (params: string[]) => string; - constructUriFromObject?: (params: Record) => string; - }, - params: string[] | Record -) => { - if (endpointData.constructUriFromObject && isParamsRecord(params)) { - return endpointData.constructUriFromObject(params); - } - if (endpointData.constructUriFromArray && Array.isArray(params)) { - return endpointData.constructUriFromArray(params); - } - throw new Error("Invalid parameter type for dynamic endpoint."); -}; - -const ENDPOINTS: Record = { - RESERVE_SLOT: publicEndpoint("slots/reserve", ApiVersion.V2), - AVAILABLE_SLOTS: publicEndpoint("slots/available", ApiVersion.V2), - DELETE_SELECTED_SLOT: publicEndpoint("slots/delete", ApiVersion.V2), - GET_PUBLIC_EVENT: publicEndpoint("events/"), - EXCHANGE_OAUTH_AUTH_TOKEN: { - auth: "public", - constructUriFromArray: ([clientId]) => `oauth/${clientId}/exchange`, - apiVersion: ApiVersion.V2, - }, - REFRESH_OAUTH_TOKEN: { - auth: "public", - constructUriFromArray: ([clientId]) => `oauth/${clientId}/refresh`, - apiVersion: ApiVersion.V2, - }, - CREATE_EVENT_TYPE: { - apiVersion: ApiVersion.V2, - auth: "access_token", - uri: `event-types`, - }, - GET_EVENT_TYPE_BY_ID: { - apiVersion: ApiVersion.V2, - auth: "access_token", - constructUriFromArray: ([eventTypeId]) => `event-types/${eventTypeId}`, - }, - CREATE_SCHEDULE: { - apiVersion: ApiVersion.V2, - auth: "access_token", - uri: "schedules", - }, - GET_DEFAULT_SCHEDULE: { - apiVersion: ApiVersion.V2, - auth: "access_token", - uri: "schedules/default", - }, - GET_ALL_SCHEDULES: { - apiVersion: ApiVersion.V2, - auth: "access_token", - uri: "schedules", - }, - GET_SCHEDULE_BY_ID: { - apiVersion: ApiVersion.V2, - auth: "access_token", - constructUriFromArray: ([scheduleId]) => `schedules/${scheduleId}`, - }, - GET_SUPPORTED_TIMEZONES: publicEndpoint("schedules/time-zones", ApiVersion.V2), - UPDATE_SCHEDULE_BY_ID: { - apiVersion: ApiVersion.V2, - auth: "access_token", - constructUriFromArray: ([scheduleId]) => `schedules/${scheduleId}`, - }, - DELETE_SCHEDULE_BY_ID: { - apiVersion: ApiVersion.V2, - auth: "access_token", - constructUriFromArray: ([scheduleId]) => `schedules/${scheduleId}`, - }, - GET_MANAGED_USERS_BY_CLIENT_ID: { - apiVersion: ApiVersion.V2, - auth: "secret", - constructUriFromArray: ([clientId]) => `oauth-clients/${clientId}/users`, - }, - CREATE_MANAGED_USER: { - apiVersion: ApiVersion.V2, - auth: "secret", - constructUriFromArray: ([clientId]) => `oauth-clients/${clientId}/users`, - }, - GET_MANAGED_USER_BY_ID: { - apiVersion: ApiVersion.V2, - auth: "secret", - constructUriFromArray: ([clientId, userId]) => `oauth-clients/${clientId}/users/${userId}`, - }, -} as const; - -const isParamsRecord = (params: unknown): params is Record => { - return params !== null && typeof params === "object" && !Array.isArray(params); -}; - -export const getEndpointDefinition = (endpoint: Endpoints): BaseEndpointDeclaration => { - return ENDPOINTS[endpoint]; -}; - -export const getEndpointData = ( - endpoint: Endpoints, - params?: Record | string[] -): { - uri: string; - version: ApiVersion; - auth: EndpointDeclaration["auth"]; -} => { - const endpointData = ENDPOINTS[endpoint]; - - if (endpointData.uri) { - return { - version: endpointData.apiVersion, - uri: endpointData.uri, - auth: endpointData.auth, - }; - } - - if (!params) { - throw new Error(`Parameters are required for dynamic ${endpoint} endpoint.`); - } - - if ( - typeof endpointData.constructUriFromArray !== "function" && - typeof endpointData.constructUriFromObject !== "function" - ) { - throw new Error(`Endpoint configuration error for ${endpoint}`); - } - - return { - version: endpointData.apiVersion, - uri: constructUri(endpointData, params), - auth: endpointData.auth, - }; -}; diff --git a/packages/platform/sdk/src/lib/errors/cal-api-error.ts b/packages/platform/sdk/src/lib/errors/cal-api-error.ts deleted file mode 100644 index fb991b0443..0000000000 --- a/packages/platform/sdk/src/lib/errors/cal-api-error.ts +++ /dev/null @@ -1,6 +0,0 @@ -export class CalApiError extends Error { - constructor(public message: string, public statusCode: number) { - super(message); - this.name = "CalApiError"; - } -} diff --git a/packages/platform/sdk/src/lib/errors/sdk-initialization-error.ts b/packages/platform/sdk/src/lib/errors/sdk-initialization-error.ts deleted file mode 100644 index 06a775a487..0000000000 --- a/packages/platform/sdk/src/lib/errors/sdk-initialization-error.ts +++ /dev/null @@ -1,6 +0,0 @@ -export class SdkInitializationError extends Error { - constructor(message: string) { - super(`Failed to initialize SDK: ${message}`); - this.name = "SdkInitializationError"; - } -} diff --git a/packages/platform/sdk/src/lib/http-caller.ts b/packages/platform/sdk/src/lib/http-caller.ts deleted file mode 100644 index c55bb7f33c..0000000000 --- a/packages/platform/sdk/src/lib/http-caller.ts +++ /dev/null @@ -1,166 +0,0 @@ -import type { AxiosError, AxiosRequestConfig } from "axios"; -import { type AxiosInstance } from "axios"; -// eslint-disable-next-line no-restricted-imports -import merge from "lodash/merge"; - -import type { Endpoints } from "./endpoints"; -import { getEndpointData, getEndpointDefinition } from "./endpoints"; -import { CalApiError } from "./errors/cal-api-error"; -import type { SdkSecrets } from "./sdk-secrets"; - -interface HttpCallerOptions { - shouldHandleRefresh?: boolean; -} - -export const X_CAL_SECRET_KEY = "x-cal-secret-key"; - -type CallOptions = { - urlParams?: Record | string[]; - config?: AxiosRequestConfig; -}; - -type CallOptionsWithBody = CallOptions & { - body: T; -}; - -export class HttpCaller { - private awaitingRefresh = false; - - secrets: SdkSecrets | null = null; - - private requestQueue: Array<() => void> = []; - - constructor( - private readonly clientId: string, - private readonly axiosClient: AxiosInstance, - private readonly options?: HttpCallerOptions - ) { - if (options?.shouldHandleRefresh) { - this.setupInterceptors(); - } - } - - private async retryQueuedRequests() { - while (this.requestQueue.length > 0) { - const retryRequest = this.requestQueue.shift(); - if (retryRequest) { - retryRequest(); - } - } - } - - private setupInterceptors() { - this.axiosClient.interceptors.request.use(async (config) => { - if (this.awaitingRefresh) { - // Return a new promise that resolves when the refresh is complete - // and then retries the request. - return new Promise((resolve) => { - this.requestQueue.push(() => resolve(config)); - }); - } - return config; - }); - - this.axiosClient.interceptors.response.use( - (response) => response, - async (error: AxiosError) => { - if (error.response?.status === 498) { - if (!this.awaitingRefresh) { - this.awaitingRefresh = true; - - try { - await this.secrets?.refreshAccessToken(this.clientId); - await this.retryQueuedRequests(); - } catch (refreshError) { - console.error("Failed to refresh token:", refreshError); - // Optionally, clear the queue on failure to prevent hanging requests - this.requestQueue = []; - } finally { - this.awaitingRefresh = false; - } - } - - // Re-queue the failed request for retry after refresh - return new Promise((resolve, reject) => { - this.requestQueue.push(() => { - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - this.axiosClient.request(error.config!).then(resolve).catch(reject); - }); - }); - } - - if (error.response) { - throw new CalApiError(error.response.statusText, error.response.status); - } else if (error.request) { - throw new Error("The request was made but no response was received"); - } else { - throw new Error("An error occurred during the request setup"); - } - } - ); - } - - async post(endpoint: Endpoints, options: CallOptionsWithBody): Promise { - const { data } = await this.axiosClient.post( - this.createCallUrl(endpoint, options.urlParams), - options.body, - this.wrapConfigWithAuth(endpoint, options.config) - ); - return data; - } - - async get(endpoint: Endpoints, options?: CallOptions): Promise { - const { data } = await this.axiosClient.get( - this.createCallUrl(endpoint, options?.urlParams), - this.wrapConfigWithAuth(endpoint, options?.config) - ); - return data; - } - - async delete(endpoint: Endpoints, options?: CallOptions): Promise { - const { data } = await this.axiosClient.delete( - this.createCallUrl(endpoint, options?.urlParams), - this.wrapConfigWithAuth(endpoint, options?.config) - ); - return data; - } - - async patch(endpoint: Endpoints, options: CallOptionsWithBody): Promise { - const { data } = await this.axiosClient.patch( - this.createCallUrl(endpoint, options.urlParams), - options.body, - this.wrapConfigWithAuth(endpoint, options.config) - ); - - return data; - } - - private createCallUrl(endpoint: Endpoints, params?: Record | string[]): string { - const { version, uri } = getEndpointData(endpoint, params); - return `${version}${uri}`; - } - - private wrapConfigWithAuth( - endpoint: Endpoints, - config?: AxiosRequestConfig - ): AxiosRequestConfig { - const { auth } = getEndpointDefinition(endpoint); - - const headers: Record = {}; - const params: Record = {}; - - if (this.secrets?.getAccessToken() && auth === "access_token") { - headers["Authorization"] = `Bearer ${this.secrets.getAccessToken()}`; - } - - if (this.secrets?.getClientSecret() && auth === "secret") { - headers[X_CAL_SECRET_KEY] = this.secrets.getClientSecret(); - params["clientId"] = this.clientId; - } - - return merge(config, { - headers, - params, - }); - } -} diff --git a/packages/platform/sdk/src/lib/sdk-secrets.ts b/packages/platform/sdk/src/lib/sdk-secrets.ts deleted file mode 100644 index 44059e29a4..0000000000 --- a/packages/platform/sdk/src/lib/sdk-secrets.ts +++ /dev/null @@ -1,64 +0,0 @@ -import type { ExchangeCodeResponse } from "../endpoints/oauth-flow/types"; -import type { BasicPlatformResponse } from "../types"; -import { Endpoints } from "./endpoints"; -import type { HttpCaller } from "./http-caller"; -import { X_CAL_SECRET_KEY } from "./http-caller"; - -export class SdkSecrets { - private refreshedAt: Date | null; - - constructor( - private readonly clientSecret: string, - private accessToken: string, - private refreshToken: string, - private readonly httpCaller: HttpCaller - ) { - this.refreshedAt = null; - } - - updateAccessToken(accessToken: string, refreshToken?: string) { - this.accessToken = accessToken; - - if (refreshToken) { - this.refreshToken = refreshToken; - } - } - - async refreshAccessToken(clientId: string) { - const { data } = await this.httpCaller.post>( - Endpoints.REFRESH_OAUTH_TOKEN, - { - urlParams: [clientId], - body: { - refreshToken: this.refreshToken, - }, - config: { - headers: { - [X_CAL_SECRET_KEY]: this.clientSecret, - }, - }, - } - ); - - this.accessToken = data.accessToken; - this.refreshToken = data.refreshToken; - - this.refreshedAt = new Date(); - } - - public getAccessToken(): Readonly { - return this.accessToken; - } - - public getClientSecret(): Readonly { - return this.clientSecret; - } - - public isAccessTokenSet(): boolean { - return !!this.accessToken; - } - - public getRefreshedAt(): Date | null { - return this.refreshedAt; - } -} diff --git a/packages/platform/sdk/src/swagger-types.d.ts b/packages/platform/sdk/src/swagger-types.d.ts deleted file mode 100644 index cc8f48f7b9..0000000000 --- a/packages/platform/sdk/src/swagger-types.d.ts +++ /dev/null @@ -1,877 +0,0 @@ -/** - * This file was auto-generated by openapi-typescript. - * Do not make direct changes to the file. - */ - -export interface paths { - "/health": { - get: operations["AppController_getHealth"]; - }; - "/v2/events/public": { - get: operations["EventsController_getPublicEvent"]; - }; - "/v2/oauth-clients/{clientId}/users": { - post: operations["OAuthClientUsersController_createUser"]; - }; - "/v2/oauth-clients/{clientId}/users/{userId}": { - get: operations["OAuthClientUsersController_getUserById"]; - delete: operations["OAuthClientUsersController_deleteUser"]; - patch: operations["OAuthClientUsersController_updateUser"]; - }; - "/v2/oauth-clients": { - /** - * @description ⚠️ First, this endpoint requires `Cookie: next-auth.session-token=eyJhbGciOiJ` header. Log into Cal web app using owner of organization that was created after visiting `/settings/organizations/new`, refresh swagger docs, and the cookie will be added to requests automatically to pass the NextAuthGuard. - * Second, make sure that the logged in user has organizationId set to pass the OrganizationRolesGuard guard. - */ - get: operations["OAuthClientsController_getOAuthClients"]; - /** - * @description ⚠️ First, this endpoint requires `Cookie: next-auth.session-token=eyJhbGciOiJ` header. Log into Cal web app using owner of organization that was created after visiting `/settings/organizations/new`, refresh swagger docs, and the cookie will be added to requests automatically to pass the NextAuthGuard. - * Second, make sure that the logged in user has organizationId set to pass the OrganizationRolesGuard guard. - */ - post: operations["OAuthClientsController_createOAuthClient"]; - }; - "/v2/oauth-clients/{clientId}": { - /** - * @description ⚠️ First, this endpoint requires `Cookie: next-auth.session-token=eyJhbGciOiJ` header. Log into Cal web app using owner of organization that was created after visiting `/settings/organizations/new`, refresh swagger docs, and the cookie will be added to requests automatically to pass the NextAuthGuard. - * Second, make sure that the logged in user has organizationId set to pass the OrganizationRolesGuard guard. - */ - get: operations["OAuthClientsController_getOAuthClientById"]; - /** - * @description ⚠️ First, this endpoint requires `Cookie: next-auth.session-token=eyJhbGciOiJ` header. Log into Cal web app using owner of organization that was created after visiting `/settings/organizations/new`, refresh swagger docs, and the cookie will be added to requests automatically to pass the NextAuthGuard. - * Second, make sure that the logged in user has organizationId set to pass the OrganizationRolesGuard guard. - */ - delete: operations["OAuthClientsController_deleteOAuthClient"]; - /** - * @description ⚠️ First, this endpoint requires `Cookie: next-auth.session-token=eyJhbGciOiJ` header. Log into Cal web app using owner of organization that was created after visiting `/settings/organizations/new`, refresh swagger docs, and the cookie will be added to requests automatically to pass the NextAuthGuard. - * Second, make sure that the logged in user has organizationId set to pass the OrganizationRolesGuard guard. - */ - patch: operations["OAuthClientsController_updateOAuthClient"]; - }; - "/v2/oauth/{clientId}/authorize": { - /** - * Authorize an OAuth client - * @description Redirects the user to the specified 'redirect_uri' with an authorization code in query parameter if the client is authorized successfully. The code is then exchanged for access and refresh tokens via the `/exchange` endpoint. - */ - post: operations["OAuthFlowController_authorize"]; - }; - "/v2/oauth/{clientId}/exchange": { - /** - * Exchange authorization code for access tokens - * @description Exchanges the authorization code received from the `/authorize` endpoint for access and refresh tokens. The authorization code should be provided in the 'Authorization' header prefixed with 'Bearer '. - */ - post: operations["OAuthFlowController_exchange"]; - }; - "/v2/oauth/{clientId}/refresh": { - post: operations["OAuthFlowController_refreshAccessToken"]; - }; - "/v2/event-types": { - get: operations["EventTypesController_getEventTypes"]; - post: operations["EventTypesController_createEventType"]; - }; - "/v2/event-types/{eventTypeId}": { - get: operations["EventTypesController_getEventType"]; - }; - "/v2/event-types/{username}/public": { - get: operations["EventTypesController_getPublicEventTypes"]; - }; - "/v2/gcal/oauth/auth-url": { - get: operations["GcalController_redirect"]; - }; - "/v2/gcal/oauth/save": { - get: operations["GcalController_save"]; - }; - "/v2/gcal/check": { - get: operations["GcalController_check"]; - }; - "/v2/provider/{clientId}": { - get: operations["CalProviderController_verifyClientId"]; - }; - "/v2/provider/{clientId}/access-token": { - get: operations["CalProviderController_verifyAccessToken"]; - }; - "/v2/schedules": { - get: operations["SchedulesController_getSchedules"]; - post: operations["SchedulesController_createSchedule"]; - }; - "/v2/schedules/default": { - get: operations["SchedulesController_getDefaultSchedule"]; - }; - "/v2/schedules/time-zones": { - get: operations["SchedulesController_getTimeZones"]; - }; - "/v2/schedules/{scheduleId}": { - get: operations["SchedulesController_getSchedule"]; - delete: operations["SchedulesController_deleteSchedule"]; - patch: operations["SchedulesController_updateSchedule"]; - }; - "/v2/me": { - get: operations["MeController_getMe"]; - patch: operations["MeController_updateMe"]; - }; - "/v2/calendars/busy-times": { - get: operations["CalendarsController_getBusyTimes"]; - }; - "/v2/calendars": { - get: operations["CalendarsController_getCalendars"]; - }; - "/v2/bookings": { - post: operations["BookingsController_createBooking"]; - }; - "/v2/bookings/recurring": { - post: operations["BookingsController_createRecurringBooking"]; - }; - "/v2/bookings/instant": { - post: operations["BookingsController_createInstantBooking"]; - }; - "/v2/slots/reserve": { - post: operations["SlotsController_reserveSlot"]; - }; - "/v2/slots/selected-slot": { - delete: operations["SlotsController_deleteSelectedSlot"]; - }; - "/v2/slots/available": { - get: operations["SlotsController_getAvailableSlots"]; - }; -} - -export type webhooks = Record; - -export interface components { - schemas: { - CreateManagedPlatformUserInput: { - email: string; - name?: string; - timeFormat?: number; - weekStart?: string; - timeZone?: string; - }; - UpdateManagedPlatformUserInput: { - email?: string; - name?: string; - timeFormat?: number; - defaultScheduleId?: number; - weekStart?: string; - timeZone?: string; - }; - CreateOAuthClientInput: Record; - DataDto: { - /** @example clsx38nbl0001vkhlwin9fmt0 */ - clientId: string; - /** @example eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoib2F1dGgtY2xpZW50Iiwi */ - clientSecret: string; - }; - CreateOAuthClientResponseDto: { - /** - * @example success - * @enum {string} - */ - status: "success" | "error"; - /** - * @example { - * "clientId": "clsx38nbl0001vkhlwin9fmt0", - * "clientSecret": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoib2F1dGgtY2xpZW50Iiwi" - * } - */ - data: components["schemas"]["DataDto"]; - }; - PlatformOAuthClientDto: { - /** @example clsx38nbl0001vkhlwin9fmt0 */ - id: string; - /** @example MyClient */ - name: string; - /** @example secretValue */ - secret: string; - /** @example 3 */ - permissions: number; - /** @example https://example.com/logo.png */ - logo?: Record; - /** - * @example [ - * "https://example.com/callback" - * ] - */ - redirectUris: string[]; - /** @example 1 */ - organizationId: number; - /** - * Format: date-time - * @example 2024-03-23T08:33:21.851Z - */ - createdAt: string; - }; - GetOAuthClientsResponseDto: { - /** - * @example success - * @enum {string} - */ - status: "success" | "error"; - data: components["schemas"]["PlatformOAuthClientDto"][]; - }; - GetOAuthClientResponseDto: { - /** - * @example success - * @enum {string} - */ - status: "success" | "error"; - data: components["schemas"]["PlatformOAuthClientDto"]; - }; - UpdateOAuthClientInput: { - logo?: string; - name?: string; - /** @default [] */ - redirectUris?: string[]; - }; - OAuthAuthorizeInput: { - redirectUri: string; - }; - ExchangeAuthorizationCodeInput: { - clientSecret: string; - }; - KeysDto: { - /** @example eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9 */ - accessToken: string; - /** @example eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9 */ - refreshToken: string; - }; - KeysResponseDto: { - /** - * @example success - * @enum {string} - */ - status: "success" | "error"; - data: components["schemas"]["KeysDto"]; - }; - RefreshTokenInput: { - refreshToken: string; - }; - CreateEventTypeInput: { - length: number; - slug: string; - title: string; - }; - CreateAvailabilityInput: { - days: number[]; - /** Format: date-time */ - startTime: string; - /** Format: date-time */ - endTime: string; - }; - CreateScheduleInput: { - name: string; - timeZone: string; - availabilities?: components["schemas"]["CreateAvailabilityInput"][]; - /** @default true */ - isDefault: Record; - }; - UpdateScheduleInput: Record; - CreateBookingInput: { - end?: string; - start: string; - eventTypeId: number; - eventTypeSlug?: string; - rescheduleUid?: string; - recurringEventId?: string; - timeZone: string; - user?: string[]; - language: string; - bookingUid?: string; - metadata: Record; - hasHashedBookingLink?: boolean; - hashedLink: string | null; - seatReferenceUid?: string; - }; - ReserveSlotInput: Record; - }; - responses: never; - parameters: never; - requestBodies: never; - headers: never; - pathItems: never; -} - -export type $defs = Record; - -export type external = Record; - -export interface operations { - AppController_getHealth: { - responses: { - 200: { - content: { - "application/json": string; - }; - }; - }; - }; - EventsController_getPublicEvent: { - parameters: { - query: { - username: string; - eventSlug: string; - isTeamEvent?: boolean; - org?: string; - }; - }; - responses: { - 200: { - content: { - "application/json": Record; - }; - }; - }; - }; - OAuthClientUsersController_createUser: { - parameters: { - path: { - clientId: string; - }; - }; - requestBody: { - content: { - "application/json": components["schemas"]["CreateManagedPlatformUserInput"]; - }; - }; - responses: { - 201: { - content: { - "application/json": Record; - }; - }; - }; - }; - OAuthClientUsersController_getUserById: { - parameters: { - path: { - clientId: string; - userId: number; - }; - }; - responses: { - 200: { - content: { - "application/json": Record; - }; - }; - }; - }; - OAuthClientUsersController_deleteUser: { - parameters: { - path: { - clientId: string; - userId: number; - }; - }; - responses: { - 200: { - content: { - "application/json": Record; - }; - }; - }; - }; - OAuthClientUsersController_updateUser: { - parameters: { - path: { - clientId: string; - userId: number; - }; - }; - requestBody: { - content: { - "application/json": components["schemas"]["UpdateManagedPlatformUserInput"]; - }; - }; - responses: { - 200: { - content: { - "application/json": Record; - }; - }; - }; - }; - /** - * @description ⚠️ First, this endpoint requires `Cookie: next-auth.session-token=eyJhbGciOiJ` header. Log into Cal web app using owner of organization that was created after visiting `/settings/organizations/new`, refresh swagger docs, and the cookie will be added to requests automatically to pass the NextAuthGuard. - * Second, make sure that the logged in user has organizationId set to pass the OrganizationRolesGuard guard. - */ - OAuthClientsController_getOAuthClients: { - responses: { - 200: { - content: { - "application/json": components["schemas"]["GetOAuthClientsResponseDto"]; - }; - }; - }; - }; - /** - * @description ⚠️ First, this endpoint requires `Cookie: next-auth.session-token=eyJhbGciOiJ` header. Log into Cal web app using owner of organization that was created after visiting `/settings/organizations/new`, refresh swagger docs, and the cookie will be added to requests automatically to pass the NextAuthGuard. - * Second, make sure that the logged in user has organizationId set to pass the OrganizationRolesGuard guard. - */ - OAuthClientsController_createOAuthClient: { - requestBody: { - content: { - "application/json": components["schemas"]["CreateOAuthClientInput"]; - }; - }; - responses: { - /** @description Create an OAuth client */ - 201: { - content: { - "application/json": components["schemas"]["CreateOAuthClientResponseDto"]; - }; - }; - }; - }; - /** - * @description ⚠️ First, this endpoint requires `Cookie: next-auth.session-token=eyJhbGciOiJ` header. Log into Cal web app using owner of organization that was created after visiting `/settings/organizations/new`, refresh swagger docs, and the cookie will be added to requests automatically to pass the NextAuthGuard. - * Second, make sure that the logged in user has organizationId set to pass the OrganizationRolesGuard guard. - */ - OAuthClientsController_getOAuthClientById: { - parameters: { - path: { - clientId: string; - }; - }; - responses: { - 200: { - content: { - "application/json": components["schemas"]["GetOAuthClientResponseDto"]; - }; - }; - }; - }; - /** - * @description ⚠️ First, this endpoint requires `Cookie: next-auth.session-token=eyJhbGciOiJ` header. Log into Cal web app using owner of organization that was created after visiting `/settings/organizations/new`, refresh swagger docs, and the cookie will be added to requests automatically to pass the NextAuthGuard. - * Second, make sure that the logged in user has organizationId set to pass the OrganizationRolesGuard guard. - */ - OAuthClientsController_deleteOAuthClient: { - parameters: { - path: { - clientId: string; - }; - }; - responses: { - 200: { - content: { - "application/json": components["schemas"]["GetOAuthClientResponseDto"]; - }; - }; - }; - }; - /** - * @description ⚠️ First, this endpoint requires `Cookie: next-auth.session-token=eyJhbGciOiJ` header. Log into Cal web app using owner of organization that was created after visiting `/settings/organizations/new`, refresh swagger docs, and the cookie will be added to requests automatically to pass the NextAuthGuard. - * Second, make sure that the logged in user has organizationId set to pass the OrganizationRolesGuard guard. - */ - OAuthClientsController_updateOAuthClient: { - parameters: { - path: { - clientId: string; - }; - }; - requestBody: { - content: { - "application/json": components["schemas"]["UpdateOAuthClientInput"]; - }; - }; - responses: { - 200: { - content: { - "application/json": components["schemas"]["GetOAuthClientResponseDto"]; - }; - }; - }; - }; - /** - * Authorize an OAuth client - * @description Redirects the user to the specified 'redirect_uri' with an authorization code in query parameter if the client is authorized successfully. The code is then exchanged for access and refresh tokens via the `/exchange` endpoint. - */ - OAuthFlowController_authorize: { - parameters: { - path: { - clientId: string; - }; - }; - requestBody: { - content: { - "application/json": components["schemas"]["OAuthAuthorizeInput"]; - }; - }; - responses: { - /** @description The user is redirected to the 'redirect_uri' with an authorization code in query parameter e.g. `redirectUri?code=secretcode.` */ - 200: { - content: never; - }; - /** @description Bad request if the OAuth client is not found, if the redirect URI is invalid, or if the user has already authorized the client. */ - 400: { - content: never; - }; - }; - }; - /** - * Exchange authorization code for access tokens - * @description Exchanges the authorization code received from the `/authorize` endpoint for access and refresh tokens. The authorization code should be provided in the 'Authorization' header prefixed with 'Bearer '. - */ - OAuthFlowController_exchange: { - parameters: { - header: { - Authorization: string; - }; - path: { - clientId: string; - }; - }; - requestBody: { - content: { - "application/json": components["schemas"]["ExchangeAuthorizationCodeInput"]; - }; - }; - responses: { - /** @description Successfully exchanged authorization code for access and refresh tokens. */ - 200: { - content: { - "application/json": components["schemas"]["KeysResponseDto"]; - }; - }; - /** @description Bad request if the authorization code is missing, invalid, or if the client ID and secret do not match. */ - 400: { - content: never; - }; - }; - }; - OAuthFlowController_refreshAccessToken: { - parameters: { - header: { - "x-cal-secret-key": string; - }; - path: { - clientId: string; - }; - }; - requestBody: { - content: { - "application/json": components["schemas"]["RefreshTokenInput"]; - }; - }; - responses: { - 200: { - content: { - "application/json": components["schemas"]["KeysResponseDto"]; - }; - }; - }; - }; - EventTypesController_getEventTypes: { - responses: { - 200: { - content: { - "application/json": Record; - }; - }; - }; - }; - EventTypesController_createEventType: { - requestBody: { - content: { - "application/json": components["schemas"]["CreateEventTypeInput"]; - }; - }; - responses: { - 201: { - content: { - "application/json": Record; - }; - }; - }; - }; - EventTypesController_getEventType: { - parameters: { - path: { - eventTypeId: string; - }; - }; - responses: { - 200: { - content: { - "application/json": Record; - }; - }; - }; - }; - EventTypesController_getPublicEventTypes: { - parameters: { - path: { - username: string; - }; - }; - responses: { - 200: { - content: { - "application/json": Record; - }; - }; - }; - }; - GcalController_redirect: { - parameters: { - header: { - Authorization: string; - }; - }; - responses: { - 200: { - content: { - "application/json": Record; - }; - }; - }; - }; - GcalController_save: { - parameters: { - query: { - state: string; - code: string; - }; - }; - responses: { - 200: { - content: { - "application/json": Record; - }; - }; - }; - }; - GcalController_check: { - responses: { - 200: { - content: { - "application/json": Record; - }; - }; - }; - }; - CalProviderController_verifyClientId: { - parameters: { - path: { - clientId: string; - }; - }; - responses: { - 200: { - content: { - "application/json": Record; - }; - }; - }; - }; - CalProviderController_verifyAccessToken: { - parameters: { - path: { - clientId: string; - }; - }; - responses: { - 200: { - content: { - "application/json": Record; - }; - }; - }; - }; - SchedulesController_getSchedules: { - responses: { - 200: { - content: { - "application/json": Record; - }; - }; - }; - }; - SchedulesController_createSchedule: { - requestBody: { - content: { - "application/json": components["schemas"]["CreateScheduleInput"]; - }; - }; - responses: { - 201: { - content: { - "application/json": Record; - }; - }; - }; - }; - SchedulesController_getDefaultSchedule: { - responses: { - 200: { - content: { - "application/json": Record; - }; - }; - }; - }; - SchedulesController_getTimeZones: { - responses: { - 200: { - content: { - "application/json": Record; - }; - }; - }; - }; - SchedulesController_getSchedule: { - parameters: { - path: { - scheduleId: number; - }; - }; - responses: { - 200: { - content: { - "application/json": Record; - }; - }; - }; - }; - SchedulesController_deleteSchedule: { - parameters: { - path: { - scheduleId: number; - }; - }; - responses: { - 200: { - content: { - "application/json": Record; - }; - }; - }; - }; - SchedulesController_updateSchedule: { - requestBody: { - content: { - "application/json": components["schemas"]["UpdateScheduleInput"]; - }; - }; - responses: { - 200: { - content: { - "application/json": Record; - }; - }; - }; - }; - MeController_getMe: { - responses: { - 200: { - content: { - "application/json": Record; - }; - }; - }; - }; - MeController_updateMe: { - requestBody: { - content: { - "application/json": components["schemas"]["UpdateManagedPlatformUserInput"]; - }; - }; - responses: { - 200: { - content: { - "application/json": Record; - }; - }; - }; - }; - CalendarsController_getBusyTimes: { - responses: { - 200: { - content: { - "application/json": Record; - }; - }; - }; - }; - CalendarsController_getCalendars: { - responses: { - 200: { - content: { - "application/json": Record; - }; - }; - }; - }; - BookingsController_createBooking: { - requestBody: { - content: { - "application/json": components["schemas"]["CreateBookingInput"]; - }; - }; - responses: { - 201: { - content: { - "application/json": Record; - }; - }; - }; - }; - BookingsController_createRecurringBooking: { - requestBody: { - content: { - "application/json": string[]; - }; - }; - responses: { - 201: { - content: { - "application/json": Record; - }; - }; - }; - }; - BookingsController_createInstantBooking: { - requestBody: { - content: { - "application/json": components["schemas"]["CreateBookingInput"]; - }; - }; - responses: { - 201: { - content: { - "application/json": Record; - }; - }; - }; - }; - SlotsController_reserveSlot: { - requestBody: { - content: { - "application/json": components["schemas"]["ReserveSlotInput"]; - }; - }; - responses: { - 201: { - content: { - "application/json": Record; - }; - }; - }; - }; - SlotsController_deleteSelectedSlot: { - responses: { - 200: { - content: { - "application/json": Record; - }; - }; - }; - }; - SlotsController_getAvailableSlots: { - responses: { - 200: { - content: { - "application/json": Record; - }; - }; - }; - }; -} diff --git a/packages/platform/sdk/src/types.ts b/packages/platform/sdk/src/types.ts deleted file mode 100644 index 4677cf342d..0000000000 --- a/packages/platform/sdk/src/types.ts +++ /dev/null @@ -1,38 +0,0 @@ -export interface CalSdkConstructorOptions { - baseUrl?: string; - handleRefresh?: boolean; - httpRetries?: CalSdkHttpRetries; -} - -interface CalSdkHttpRetries { - maxAmount: number; -} - -export type ResponseStatus = "success" | "error"; - -export interface BasicPlatformResponse { - status: ResponseStatus; - data: T; -} - -export enum ApiVersion { - V1 = "v1/", - V2 = "v2/", - NEUTRAL = "/", -} - -export type SdkAuthOptions = { - clientSecret?: string; - accessToken?: string; - refreshToken?: string; -}; - -export type PaginationOptions = { - limit?: number; - skip?: number; -}; - -export * from "./endpoints/slots/types"; -export * from "./endpoints/schedules/types"; -export * from "./endpoints/events/types"; -export * from "./endpoints/oauth-flow/types"; diff --git a/packages/platform/sdk/tsconfig.build.json b/packages/platform/sdk/tsconfig.build.json deleted file mode 100644 index 2cffef6fdf..0000000000 --- a/packages/platform/sdk/tsconfig.build.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "module": "ESNext" - }, - "exclude": ["src/__tests__/**/*", "example/*"] -} diff --git a/packages/platform/sdk/tsconfig.json b/packages/platform/sdk/tsconfig.json deleted file mode 100644 index bb2f7f6625..0000000000 --- a/packages/platform/sdk/tsconfig.json +++ /dev/null @@ -1,109 +0,0 @@ -{ - "compilerOptions": { - /* Visit https://aka.ms/tsconfig to read more about this file */ - - /* Projects */ - // "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */ - // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ - // "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */ - // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */ - // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ - // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ - - /* Language and Environment */ - "target": "es2016" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */, - // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ - // "jsx": "preserve", /* Specify what JSX code is generated. */ - // "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */ - // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ - // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */ - // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ - // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */ - // "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */ - // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ - // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ - // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */ - - /* Modules */ - "module": "commonjs" /* Specify what module code is generated. */, - // "rootDir": "./", /* Specify the root folder within your source files. */ - // "moduleResolution": "node10", /* Specify how TypeScript looks up a file from a given module specifier. */ - // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ - // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ - // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ - // "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */ - // "types": [], /* Specify type package names to be included without being referenced in a source file. */ - // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ - // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */ - // "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */ - // "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */ - // "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */ - // "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */ - // "resolveJsonModule": true, /* Enable importing .json files. */ - // "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */ - // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */ - - /* JavaScript Support */ - // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */ - // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ - // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */ - - /* Emit */ - // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ - // "declarationMap": true, /* Create sourcemaps for d.ts files. */ - // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ - // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ - // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ - // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */ - // "outDir": "./", /* Specify an output folder for all emitted files. */ - // "removeComments": true, /* Disable emitting comments. */ - // "noEmit": true, /* Disable emitting files from a compilation. */ - // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ - // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */ - // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ - // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ - // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ - // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ - // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ - // "newLine": "crlf", /* Set the newline character for emitting files. */ - // "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */ - // "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */ - // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ - // "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */ - // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ - // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */ - - /* Interop Constraints */ - // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ - // "verbatimModuleSyntax": true, /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */ - // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ - "esModuleInterop": true /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */, - // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ - "forceConsistentCasingInFileNames": true /* Ensure that casing is correct in imports. */, - - /* Type Checking */ - "strict": true /* Enable all strict type-checking options. */, - // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */ - // "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */ - // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ - // "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */ - // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ - // "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */ - // "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */ - // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ - // "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */ - // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */ - // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ - // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ - // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ - // "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */ - // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ - // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */ - // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ - // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ - - /* Completeness */ - // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ - "skipLibCheck": true /* Skip type checking all .d.ts files. */ - } -}