Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(lib): turn dependencies into js #8846

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
98 changes: 98 additions & 0 deletions packages/lib/constants.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
const VERCEL_URL = process.env.NEXT_PUBLIC_VERCEL_URL ? `https://${process.env.NEXT_PUBLIC_VERCEL_URL}` : "";
const RAILWAY_STATIC_URL = process.env.RAILWAY_STATIC_URL ? `https://${process.env.RAILWAY_STATIC_URL}` : "";
const HEROKU_URL = process.env.HEROKU_APP_NAME ? `https://${process.env.HEROKU_APP_NAME}.herokuapp.com` : "";
const RENDER_URL = process.env.RENDER_EXTERNAL_URL ? `https://${process.env.RENDER_EXTERNAL_URL}` : "";
const WEBAPP_URL =
process.env.NEXT_PUBLIC_WEBAPP_URL ||
VERCEL_URL ||
RAILWAY_STATIC_URL ||
HEROKU_URL ||
RENDER_URL ||
"http://localhost:3000";
/** @deprecated use `WEBAPP_URL` */
const BASE_URL = WEBAPP_URL;
const WEBSITE_URL = process.env.NEXT_PUBLIC_WEBSITE_URL || "https://cal.com";
const APP_NAME = process.env.NEXT_PUBLIC_APP_NAME || "Cal.com";
const SUPPORT_MAIL_ADDRESS = process.env.NEXT_PUBLIC_SUPPORT_MAIL_ADDRESS || "[email protected]";
const COMPANY_NAME = process.env.NEXT_PUBLIC_COMPANY_NAME || "Cal.com, Inc.";
const SENDER_ID = process.env.NEXT_PUBLIC_SENDER_ID || "Cal";
const SENDER_NAME = process.env.NEXT_PUBLIC_SENDGRID_SENDER_NAME || "Cal.com";

// This is the URL from which all Cal Links and their assets are served.
// Use website URL to make links shorter(cal.com and not app.cal.com)
// As website isn't setup for preview environments, use the webapp url instead
const CAL_URL = new URL(WEBAPP_URL).hostname.endsWith(".vercel.app") ? WEBAPP_URL : WEBSITE_URL;

const CONSOLE_URL =
new URL(WEBAPP_URL).hostname.endsWith(".cal.dev") || process.env.NODE_ENV !== "production"
? `https://console.cal.dev`
: `https://console.cal.com`;
const IS_SELF_HOSTED = !(
new URL(WEBAPP_URL).hostname.endsWith(".cal.dev") || new URL(WEBAPP_URL).hostname.endsWith(".cal.com")
);
const EMBED_LIB_URL = process.env.NEXT_PUBLIC_EMBED_LIB_URL || `${WEBAPP_URL}/embed/embed.js`;
const IS_PRODUCTION = process.env.NODE_ENV === "production";
const TRIAL_LIMIT_DAYS = 14;

const HOSTED_CAL_FEATURES = process.env.NEXT_PUBLIC_HOSTED_CAL_FEATURES || !IS_SELF_HOSTED;

/** @deprecated use `WEBAPP_URL` */
const NEXT_PUBLIC_BASE_URL = process.env.NEXT_PUBLIC_WEBAPP_URL || `https://${process.env.VERCEL_URL}`;
const LOGO = "/calcom-logo-white-word.svg";
const LOGO_ICON = "/cal-com-icon-white.svg";
const ROADMAP = "https://cal.com/roadmap";
const DESKTOP_APP_LINK = "https://cal.com/download";
const JOIN_SLACK = "https://cal.com/slack";
const POWERED_BY_URL = `${WEBSITE_URL}/?utm_source=embed&utm_medium=powered-by-button`;
const DOCS_URL = "https://cal.com/docs";
const DEVELOPER_DOCS = "https://developer.cal.com";
const SEO_IMG_DEFAULT = `${WEBSITE_URL}/og-image.png`;
// The Dynamic OG Image is passed through Next's Image API to further optimize it.
// This results in a 80% smaller image 🤯. It is however important that for the query
// parameters you pass to the /api/social/og/image endpoint, you wrap them in encodeURIComponent
// as well, otherwise the URL won't be valid.
const SEO_IMG_OGIMG = `${CAL_URL}/_next/image?w=1200&q=100&url=${encodeURIComponent("/api/social/og/image")}`;
const SEO_IMG_OGIMG_VIDEO = `${WEBSITE_URL}/video-og-image.png`;
const IS_STRIPE_ENABLED = !!(
process.env.STRIPE_CLIENT_ID &&
process.env.NEXT_PUBLIC_STRIPE_PUBLIC_KEY &&
process.env.STRIPE_PRIVATE_KEY
);
/** Self hosted shouldn't checkout when creating teams unless required */
const IS_TEAM_BILLING_ENABLED = IS_STRIPE_ENABLED && (!IS_SELF_HOSTED || HOSTED_CAL_FEATURES);
const FULL_NAME_LENGTH_MAX_LIMIT = 50;
const MINUTES_TO_BOOK = process.env.NEXT_PUBLIC_MINUTES_TO_BOOK || "5";

module.exports = {
WEBAPP_URL,
BASE_URL,
WEBSITE_URL,
APP_NAME,
SUPPORT_MAIL_ADDRESS,
COMPANY_NAME,
SENDER_ID,
SENDER_NAME,
CAL_URL,
CONSOLE_URL,
IS_SELF_HOSTED,
EMBED_LIB_URL,
IS_PRODUCTION,
TRIAL_LIMIT_DAYS,
HOSTED_CAL_FEATURES,
NEXT_PUBLIC_BASE_URL,
LOGO,
LOGO_ICON,
ROADMAP,
DESKTOP_APP_LINK,
JOIN_SLACK,
POWERED_BY_URL,
DOCS_URL,
DEVELOPER_DOCS,
SEO_IMG_DEFAULT,
SEO_IMG_OGIMG,
SEO_IMG_OGIMG_VIDEO,
IS_STRIPE_ENABLED,
IS_TEAM_BILLING_ENABLED,
FULL_NAME_LENGTH_MAX_LIMIT,
MINUTES_TO_BOOK,
};
66 changes: 0 additions & 66 deletions packages/lib/constants.ts

This file was deleted.

87 changes: 66 additions & 21 deletions packages/lib/telemetry.ts → packages/lib/telemetry.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,36 @@
import type { NextApiRequest, NextApiResponse } from "next";
import type { CollectOpts, EventHandler } from "next-collect";
import { useCollector } from "next-collect/client";
// Importing types so we're not directly importing next/server
import type { NextRequest, NextResponse } from "next/server";
/**
* @typedef {import("next").NextApiRequest} NextApiRequest
* @typedef {import("next").NextApiResponse} NextApiResponse
* @typedef {import("next-collect").CollectOpts} CollectOpts
* @typedef {import("next-collect").EventHandler} EventHandler
* @typedef {import("next/server").NextRequest} NextRequest
* @typedef {import("next/server").NextResponse} NextResponse
*/
const useCollector = require("next-collect/client");

import { CONSOLE_URL } from "./constants";
const CONSOLE_URL = require("./constants");

export const telemetryEventTypes = {
/**
* @type {{
* pageView: string;
* apiCall: string;
* bookingConfirmed: string;
* bookingCancelled: string;
* importSubmitted: string;
* login: string;
* embedView: string;
* embedBookingConfirmed: string;
* onboardingFinished: string;
* onboardingStarted: string;
* signup: string;
* team_created: string;
* website: {
* pageView: string;
* };
* slugReplacementAction: string;
* }}
*/
const telemetryEventTypes = {
pageView: "page_view",
apiCall: "api_call",
bookingConfirmed: "booking_confirmed",
Expand All @@ -25,10 +49,12 @@ export const telemetryEventTypes = {
slugReplacementAction: "slug_replacement_action",
};

export function collectPageParameters(
route?: string,
extraData: Record<string, unknown> = {}
): Record<string, unknown> {
/**
* @param {string} [route]
* @param {Record<string, unknown>} [extraData]
* @returns {Record<string, unknown>}
*/
function collectPageParameters(route, extraData = {}) {
const host = document.location.host;
const docPath = route ?? "";
return {
Expand All @@ -39,7 +65,10 @@ export function collectPageParameters(
};
}

const reportUsage: EventHandler = async (event, { fetch }) => {
/**
* @type {EventHandler}
*/
const reportUsage = async (event, { fetch }) => {
const ets = telemetryEventTypes;
if ([ets.bookingConfirmed, ets.embedBookingConfirmed].includes(event.eventType)) {
const key = process.env.CALCOM_LICENSE_KEY;
Expand All @@ -55,7 +84,10 @@ const reportUsage: EventHandler = async (event, { fetch }) => {
}
};

export const nextCollectBasicSettings: CollectOpts = {
/**
* @type {CollectOpts}
*/
const nextCollectBasicSettings = {
drivers: [
process.env.CALCOM_LICENSE_KEY && process.env.NEXT_PUBLIC_IS_E2E !== "1" ? reportUsage : undefined,
process.env.CALCOM_TELEMETRY_DISABLED === "1" || process.env.NEXT_PUBLIC_IS_E2E === "1"
Expand Down Expand Up @@ -85,17 +117,19 @@ export const nextCollectBasicSettings: CollectOpts = {
],
};

export const extendEventData = (
req: NextRequest | NextApiRequest,
res: NextResponse | NextApiResponse,
original: any
) => {
/**
* @param {NextRequest | NextApiRequest} req
* @param {NextResponse | NextApiResponse} res
* @param {any} original
* @returns {Record<string, unknown>}
*/
const extendEventData = (req, res, original) => {
const onVercel =
typeof req.headers?.get === "function"
? !!req.headers.get("x-vercel-id")
: !!(req.headers as any)?.["x-vercel-id"];
: !!req.headers?.["x-vercel-id"];
const pageUrl = original?.page_url || req.url || undefined;
const cookies = req.cookies as { [key: string]: any };
const cookies = req.cookies;
return {
title: "",
ipAddress: "",
Expand All @@ -113,4 +147,15 @@ export const extendEventData = (
};
};

export const useTelemetry = useCollector;
/**
* @type {typeof useCollector}
*/
const useTelemetry = useCollector;

module.exports = {
telemetryEventTypes,
collectPageParameters,
nextCollectBasicSettings,
extendEventData,
useTelemetry,
};