Narrow argument type to the specific event being listened to (#16714)
This commit is contained in:
1 parent
3ae53a4b6e
commit
6d133c26f8
7 files changed
+71
-12
No files matched your search
@@ -1,7 +1,8 @@
|
||||
import type { GlobalCal } from "./src/embed";
|
||||
import type { GlobalCal, EmbedEvent } from "./src/embed";
|
||||
|
||||
const Cal = window.Cal as GlobalCal;
|
||||
const callback = function (e) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const callback = function (e: any) {
|
||||
const detail = e.detail;
|
||||
console.log("Event: ", e.type, detail);
|
||||
};
|
||||
@@ -27,6 +28,7 @@ const only = searchParams.get("only");
|
||||
const colorScheme = searchParams.get("color-scheme");
|
||||
const prerender = searchParams.get("prerender");
|
||||
|
||||
// @ts-expect-error We haven't defined ENABLE_FUTURE_ROUTES as it is a playground specific variable.
|
||||
window.ENABLE_FUTURE_ROUTES = searchParams.get("future-routes") === "true";
|
||||
|
||||
if (colorScheme) {
|
||||
@@ -469,10 +471,6 @@ if (only === "all" || only == "ns:monthView") {
|
||||
},
|
||||
}
|
||||
);
|
||||
Cal.ns.monthView("on", {
|
||||
action: "*",
|
||||
callback,
|
||||
});
|
||||
}
|
||||
|
||||
if (only === "all" || only == "ns:weekView") {
|
||||
@@ -532,3 +530,24 @@ if (only === "all" || only == "ns:columnView") {
|
||||
callback,
|
||||
});
|
||||
}
|
||||
|
||||
// Verifies that the type of e.detail.data is valid. type-check will fail if we accidentally break it.
|
||||
const bookingSuccessfulV2Callback = (e: EmbedEvent<"bookingSuccessfulV2">) => {
|
||||
const data = e.detail.data;
|
||||
console.log("bookingSuccessfulV2", {
|
||||
endTime: data.endTime,
|
||||
startTime: data.startTime,
|
||||
title: data.title,
|
||||
});
|
||||
|
||||
// Remove the event listener after it is fired once
|
||||
Cal("off", {
|
||||
action: "bookingSuccessfulV2",
|
||||
callback: bookingSuccessfulV2Callback,
|
||||
});
|
||||
};
|
||||
|
||||
Cal("on", {
|
||||
action: "bookingSuccessfulV2",
|
||||
callback: bookingSuccessfulV2Callback,
|
||||
});
|
||||
@@ -10,6 +10,10 @@ import allCss from "./tailwind.generated.css?inline";
|
||||
import type { UiConfig } from "./types";
|
||||
|
||||
export type { PrefillAndIframeAttrsConfig } from "./embed-iframe";
|
||||
|
||||
// Exporting for consumption by @calcom/embed-core user
|
||||
export type { EmbedEvent } from "./sdk-action-manager";
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
type Rest<T extends any[]> = T extends [any, ...infer U] ? U : never;
|
||||
export type Message = {
|
||||
@@ -141,10 +145,20 @@ function withColorScheme(
|
||||
return queryObject;
|
||||
}
|
||||
|
||||
type allPossibleCallbacksAndActions = {
|
||||
[K in keyof EventDataMap]: {
|
||||
action: K;
|
||||
callback: (arg0: CustomEvent<EventData<K>>) => void;
|
||||
};
|
||||
}[keyof EventDataMap];
|
||||
|
||||
type SingleInstructionMap = {
|
||||
// TODO: This makes api("on", {}) loose it's generic type. Find a way to fix it.
|
||||
// e.g. api("on", { action: "__dimensionChanged", callback: (e) => { /* `e.detail.data` has all possible values for all events/actions */} });
|
||||
[K in keyof CalApi]: CalApi[K] extends (...args: never[]) => void ? [K, ...Parameters<CalApi[K]>] : never;
|
||||
on: ["on", allPossibleCallbacksAndActions];
|
||||
off: ["off", allPossibleCallbacksAndActions];
|
||||
} & {
|
||||
[K in Exclude<keyof CalApi, "on" | "off">]: CalApi[K] extends (...args: never[]) => void
|
||||
? [K, ...Parameters<CalApi[K]>]
|
||||
: never;
|
||||
};
|
||||
|
||||
type SingleInstruction = SingleInstructionMap[keyof SingleInstructionMap];
|
||||
|
||||
@@ -117,6 +117,8 @@ export type EventData<T extends keyof EventDataMap> = {
|
||||
};
|
||||
}[T];
|
||||
|
||||
export type EmbedEvent<T extends keyof EventDataMap> = CustomEvent<EventData<T>>;
|
||||
|
||||
export class SdkActionManager {
|
||||
namespace: Namespace;
|
||||
|
||||
|
||||
@@ -12,6 +12,6 @@
|
||||
"@calcom/embed-snippet": ["../embed-snippet/src"]
|
||||
}
|
||||
},
|
||||
"include": ["src", "env.d.ts", "index.ts"],
|
||||
"include": ["src", "env.d.ts", "index.ts", "*.ts"],
|
||||
"exclude": ["dist", "build", "node_modules"]
|
||||
}
|
||||
@@ -8,7 +8,7 @@ import ReactDom from "react-dom";
|
||||
|
||||
// Because we don't import from @calcom/embed-react, this file isn't able to test if the build is successful or not and thus npm package would work or not correctly.
|
||||
// There are tests in test/built which verifiy that the types from built package are correctly generated and exported correctly.
|
||||
import Cal, { getCalApi } from "./src/index";
|
||||
import Cal, { getCalApi, type EmbedEvent } from "./src/index";
|
||||
|
||||
const api = getCalApi({
|
||||
namespace: "inline",
|
||||
@@ -49,6 +49,27 @@ function App() {
|
||||
action: "*",
|
||||
callback,
|
||||
});
|
||||
|
||||
// Also, validates the type of e.detail.data as TS runs on this file
|
||||
const bookingSuccessfulV2Callback = (e: EmbedEvent<"bookingSuccessfulV2">) => {
|
||||
const data = e.detail.data;
|
||||
console.log("bookingSuccessfulV2", {
|
||||
endTime: data.endTime,
|
||||
startTime: data.startTime,
|
||||
title: data.title,
|
||||
});
|
||||
|
||||
// Remove the event listener after it is fired once as I don't need it.
|
||||
api("off", {
|
||||
action: "bookingSuccessfulV2",
|
||||
callback: bookingSuccessfulV2Callback,
|
||||
});
|
||||
};
|
||||
|
||||
api("on", {
|
||||
action: "bookingSuccessfulV2",
|
||||
callback: bookingSuccessfulV2Callback,
|
||||
});
|
||||
});
|
||||
};
|
||||
}, []);
|
||||
|
||||
@@ -5,6 +5,9 @@ import EmbedSnippet from "@calcom/embed-snippet";
|
||||
|
||||
import Cal from "./Cal";
|
||||
|
||||
// Exporting for consumption by @calcom/embed-react user
|
||||
export type { EmbedEvent } from "@calcom/embed-core";
|
||||
|
||||
export function getCalApi(options?: {
|
||||
embedJsUrl?: string;
|
||||
namespace?: string;
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
"@calcom/embed-snippet": ["../embed-snippet/src"]
|
||||
}
|
||||
},
|
||||
"include": ["src/**/*.ts", "src/**/*.tsx", "env.d.ts"],
|
||||
"include": ["src/**/*.ts", "src/**/*.tsx", "env.d.ts", "*.tsx", "*.ts"],
|
||||
// Exclude "test" because that has `api.test.ts` which imports @calcom/embed-react which needs it to be built using this tsconfig.json first. Excluding it here prevents type-check from validating test folder
|
||||
"exclude": ["node_modules", "test"]
|
||||
}
|
||||
Reference in new issue
Block a user