Files
calendar/apps/web/getNextjsOrgRewriteConfig.ts
Volnei MunhozGitHubDevin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
76b53eb3d4 chore: remove webpack config and convert next.config to TypeScript (#26126)
* chore: remove webpack experimental flags from apps/web

- Remove webpackMemoryOptimizations and webpackBuildWorker from experimental config
- Remove unused DefinePlugin for process.env.BUILD_ID (not used anywhere in codebase)
- Remove unused buildId parameter from webpack function signature

These webpack-specific experimental flags were showing up during dev mode
even though Turbopack is used for development. The flags only apply to
production webpack builds and their presence in the config was confusing.

Co-Authored-By: Volnei Munhoz <[email protected]>

* chore: remove webpack function for full Turbopack build

- Remove entire webpack function (IgnorePlugin, PrismaPlugin, resolve.fallback, sideEffects)
- Remove unused PrismaPlugin import
- Turbopack handles all bundling without webpack configuration

Benchmark shows no performance regression:
- Main (with webpack): 67s compile
- Full webpack removal: 69s compile

Both fail at same pre-existing TypeScript error on main branch.

Co-Authored-By: Volnei Munhoz <[email protected]>

* chore: convert next.config.js to TypeScript

- Convert CommonJS require() to ES6 imports
- Add proper TypeScript types for config and plugins
- Remove /* eslint-disable */ comment
- Keep all existing functionality intact

Co-Authored-By: Volnei Munhoz <[email protected]>

* conditional load axiom

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-12-22 12:23:00 -03:00

59 lines
2.6 KiB
TypeScript

const isSingleOrgModeEnabled = !!process.env.NEXT_PUBLIC_SINGLE_ORG_SLUG;
const orgSlugCaptureGroupName = "orgSlug";
/**
* Returns the leftmost subdomain from a given URL.
* It needs the URL domain to have atleast two dots.
* app.cal.com -> app
* app.company.cal.com -> app
* app.company.com -> app
*/
const getLeftMostSubdomain = (url: string): string | null => {
let normalizedUrl = url;
if (!normalizedUrl.startsWith("http:") && !normalizedUrl.startsWith("https:")) {
// Make it a valid URL. Maybe we can simply return null and opt-out from orgs support till the use a URL scheme.
normalizedUrl = `https://${normalizedUrl}`;
}
const _url = new URL(normalizedUrl);
// Using positional capture instead of named capture group for ES2017 compatibility
// Group 1: protocol (optional), Group 2: full domain, Group 3: subdomain
const regex = /^([a-z]+:\/{2})?(([\w-.]+)\.[\w-]+\.\w+)$/;
return _url.hostname.match(regex)?.[3] ?? null;
};
const getRegExpNotMatchingLeftMostSubdomain = (url: string): string => {
const leftMostSubdomain = getLeftMostSubdomain(url);
const subdomain = leftMostSubdomain ? `(?!${leftMostSubdomain})[^.]+` : "[^.]+";
return subdomain;
};
export interface NextJsOrgRewriteConfig {
orgSlug: string;
orgHostPath: string;
disableRootPathRewrite: boolean;
disableRootEmbedPathRewrite: boolean;
}
// For app.cal.com, it will match all domains that are not starting with "app". Technically we would want to match domains like acme.cal.com, dunder.cal.com and not app.cal.com
export const getRegExpThatMatchesAllOrgDomains = ({ webAppUrl }: { webAppUrl: string }): string => {
if (isSingleOrgModeEnabled) {
console.log("Single-Org-Mode enabled - Consider all domains to be org domains");
// It works in combination with next.config.js where in this case we use orgSlug=NEXT_PUBLIC_SINGLE_ORG_SLUG
return `.*`;
}
const subdomainRegExp = getRegExpNotMatchingLeftMostSubdomain(webAppUrl);
return `^(?<${orgSlugCaptureGroupName}>${subdomainRegExp})\\.(?!vercel\\.app).*`;
};
export const nextJsOrgRewriteConfig: NextJsOrgRewriteConfig = {
// :orgSlug is special value which would get matching group from the regex in orgHostPath
orgSlug: process.env.NEXT_PUBLIC_SINGLE_ORG_SLUG || `:${orgSlugCaptureGroupName}`,
orgHostPath: getRegExpThatMatchesAllOrgDomains({
webAppUrl: process.env.NEXT_PUBLIC_WEBAPP_URL || `https://${process.env.VERCEL_URL}`,
}),
// We disable root path rewrite because we want to serve dashboard on root path
disableRootPathRewrite: isSingleOrgModeEnabled,
// We disable root embed path rewrite in single org mode as well
disableRootEmbedPathRewrite: isSingleOrgModeEnabled,
};