@vercel/microfrontends 0.12.0 → 0.12.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/next/middleware/index.ts","../../src/next/middleware/middleware.ts","../../src/config/edge/microfrontend-config.ts","../../src/config/errors.ts","../../src/routing/url.ts","../../src/config/overrides/config.ts","../../src/config/common/host.ts","../../src/config/common/application.ts","../../src/config/common/microfrontend-config.ts","../../src/routing/get-domain-for-current-environment.ts"],"sourcesContent":["export * from './middleware';\nexport * from './types';\n","/// <reference types=\"@edge-runtime/types\" />\n\nimport type { NextRequest } from 'next/server';\nimport { NextResponse } from 'next/server';\nimport { pathToRegexp } from 'path-to-regexp';\nimport { MicrofrontendConfigEdge } from '../../config/edge/microfrontend-config';\nimport { getDomainForCurrentEnvironment } from '../../routing/get-domain-for-current-environment';\nimport type { Application } from '../../config/common/application';\nimport type { HostConfig } from '../../config/schema';\nimport type {\n MicrofrontendsMiddleware,\n MicrofrontendsMiddlewareHandler,\n} from './types';\n\ninterface GetHandlerParams {\n application: Application;\n flagFn?: () => Promise<boolean>;\n pattern: RegExp;\n}\n\ninterface InternalRouting {\n routing: HostConfig;\n}\n\nasync function verifyPreviewDomain(\n req: NextRequest,\n rewriteDomain: string,\n): Promise<boolean> {\n const jwtCookie = req.cookies.get('_vercel_jwt')?.value;\n const deploymentProtectionBypassHeader = req.headers.get(\n 'x-vercel-protection-bypass',\n );\n\n // We make a `HEAD` request with `x-vercel-micro-frontends-check: 1` which will get handled in the proxy without reaching the deployment\n const previewResponse = await fetch(rewriteDomain, {\n method: 'HEAD',\n headers: {\n 'x-vercel-micro-frontends-check': '1',\n ...(jwtCookie ? { cookie: `_vercel_jwt=${jwtCookie}` } : {}),\n ...(deploymentProtectionBypassHeader\n ? {\n 'x-vercel-protection-bypass': deploymentProtectionBypassHeader,\n }\n : {}),\n },\n });\n\n const vercelError = previewResponse.headers.get('x-vercel-error');\n return !(\n previewResponse.status === 404 &&\n (vercelError === 'DEPLOYMENT_NOT_FOUND' || vercelError === 'NOT_FOUND')\n );\n}\n\nfunction microfrontendInternalRoutingHandler({\n config,\n}: { config: MicrofrontendConfigEdge }): MicrofrontendsMiddlewareHandler {\n return async (req: NextRequest): Promise<NextResponse> => {\n const payload: Record<string, InternalRouting> = Object.fromEntries(\n await Promise.all(\n config.getAllApplications().map(async (application) => {\n let rewriteDomain = getDomainForCurrentEnvironment(application);\n const isPreviewDomainAvailable = await verifyPreviewDomain(\n req,\n rewriteDomain,\n );\n\n if (!isPreviewDomainAvailable) {\n rewriteDomain = application.production.toString();\n }\n\n const url = new URL(rewriteDomain);\n return [application.name, { routing: { host: url.host } }] as const;\n }),\n ),\n );\n\n return NextResponse.json(payload);\n };\n}\n\nfunction getHandler({\n application,\n flagFn,\n pattern,\n}: GetHandlerParams): MicrofrontendsMiddlewareHandler {\n return async (req: NextRequest): Promise<NextResponse | undefined> => {\n const pathname = req.nextUrl.pathname;\n const search = req.nextUrl.search;\n\n // If this header is present, it means the proxy handled the routing.\n // Eventually the middleware should use proxy logic for all deployed envs (all except local)\n const proxyRouting = req.headers.get('X-Vercel-Mfe-Proxy') === '1';\n\n let rewriteDomain = proxyRouting\n ? null\n : getDomainForCurrentEnvironment(application);\n const patchedHeaders = new Headers(req.headers);\n\n const responseCallbacks: ((response: NextResponse) => void)[] = [];\n const onRewrite: (response: NextResponse) => NextResponse = (response) => {\n for (const callback of responseCallbacks) {\n callback(response);\n }\n\n return response;\n };\n\n // If this is a preview environment, we check the domain to make sure the project was deployed\n if (process.env.VERCEL_ENV === 'preview' && rewriteDomain) {\n const zoneFallbackCookieName = `__zone_${application.name}_production_fallback`;\n const assetPrefix = application.routing?.assetPrefix;\n\n if (\n assetPrefix &&\n pathname.startsWith(`/${assetPrefix}`) &&\n req.cookies.get(zoneFallbackCookieName)?.value === '1'\n ) {\n // If this is an asset request and we have the cookie, we can safely route to production without fetching\n rewriteDomain = application.production.toString();\n } else {\n try {\n let deploymentFound: boolean;\n if (req.headers.get('x-vercel-skip-deployment-existence-check')) {\n deploymentFound = true;\n } else {\n deploymentFound = await verifyPreviewDomain(req, rewriteDomain);\n }\n\n if (!deploymentFound) {\n // If the deployment is not found, we rewrite to the production domain\n rewriteDomain = application.production.toString();\n\n // We set a 1 minute cookie for the application to avoid checking again for every request\n responseCallbacks.push((response) => {\n response.cookies.set(zoneFallbackCookieName, '1', {\n httpOnly: true,\n sameSite: 'lax',\n secure: true,\n maxAge: 60, // 1 minute\n });\n });\n\n // When routing to a production url, we need to enable the toolbar manually,\n // since production deployments rely on the extension to do that, but the extension can't match the top-level domain\n try {\n const existingCookie = patchedHeaders.get('cookie');\n\n // If the request doesn't contain the toolbar cookie, we add it to support the middleware injection\n if (!existingCookie?.includes('__vercel_toolbar')) {\n patchedHeaders.set(\n 'cookie',\n [`__vercel_toolbar=1`, existingCookie].join('; '),\n );\n\n // We also return a `set-cookie` header to set the cookie locally, to support the Next.js injection which checks the document\n responseCallbacks.push((response) => {\n response.cookies.set('__vercel_toolbar', '1', {\n httpOnly: false,\n sameSite: 'lax',\n secure: true,\n maxAge: 29030400,\n });\n });\n }\n } catch (error) {\n // Do Nothing\n }\n } else if (req.cookies.get(zoneFallbackCookieName)?.value === '1') {\n // If the preview exists and we have the fallback cookie, we make sure to clear the cookie to route subsequent assets to the preview\n responseCallbacks.push((response) => {\n response.cookies.set(zoneFallbackCookieName, '', {\n httpOnly: true,\n sameSite: 'lax',\n secure: true,\n maxAge: 0,\n });\n });\n }\n } catch {\n // Do Nothing\n }\n }\n }\n\n const isFlagEnabled = async (): Promise<boolean> =>\n flagFn ? flagFn() : true;\n\n // If the pattern doesn't match, we don't need to execute the flag\n if (pattern.test(pathname) && (await isFlagEnabled())) {\n if (proxyRouting) {\n const headers = new Headers(req.headers);\n /**\n * This header informs the proxy which zone the route the request to.\n * It will override any provided redirect / rewrite host.\n *\n * If a rewrite / redirect includes this header, the proxy will perform the\n * action, but will also replace the host with corresponding host for the zone.\n */\n headers.set('x-vercel-mfe-zone', application.name);\n return onRewrite(\n NextResponse.next({\n request: {\n headers,\n },\n headers: {\n // temporary, can delete when proxyRouting flag is removed\n 'x-vercel-mfe-middleware-sent-proxy': application.name,\n },\n }),\n );\n }\n return onRewrite(\n NextResponse.rewrite(`${rewriteDomain}${pathname}${search}`, {\n request: {\n headers: patchedHeaders,\n },\n }),\n );\n }\n };\n // If the path does not match the pattern, we don't do anything and let the request continue\n}\n\n/**\n * Returns an array of middleware functions that will handle routing to the\n * right microfrontends for the provided configuration.\n *\n * @param config - The microfrontends configuration object.\n * @param flagValues - An object that maps flag names to functions that return the flag value.\n */\nexport function getMicrofrontendsMiddleware({\n request,\n flagValues,\n}: {\n request: NextRequest;\n flagValues?: Record<string, () => Promise<boolean>>;\n}): MicrofrontendsMiddleware[] {\n const config = MicrofrontendConfigEdge.fromEnv({\n cookies: request.cookies.getAll(),\n });\n const middlewares: MicrofrontendsMiddleware[] = [];\n\n middlewares.push({\n src: '/.well-known/vercel/microfrontend-routing',\n fn: microfrontendInternalRoutingHandler({ config }),\n });\n\n for (const application of config.getAllApplications()) {\n if (application.name === process.env.NEXT_PUBLIC_MFE_CURRENT_APPLICATION) {\n continue;\n }\n if (application.routing) {\n if (\n process.env.VERCEL_ENV === 'preview' &&\n application.routing.assetPrefix\n ) {\n const pattern = pathToRegexp(\n `/${application.routing.assetPrefix}/:path+`,\n );\n middlewares.push({\n src: pattern,\n fn: getHandler({\n application,\n pattern,\n }),\n });\n }\n for (const pathGroup of application.routing.matches) {\n if (process.env.VERCEL_ENV === 'preview' || pathGroup.options?.flag) {\n const flagName = pathGroup.options?.flag;\n // biome-ignore lint/suspicious/noImplicitAnyLet: Ignored using `--suppress`\n let flagFn;\n if (flagName) {\n flagFn = flagValues?.[flagName];\n if (!flagFn) {\n throw new Error(\n `Flag \"${flagName}\" was specified to control routing for path group \"${pathGroup.group}\" in application ${application.name} but not found in provided flag values.`,\n );\n }\n }\n for (const path of pathGroup.paths) {\n const pattern = pathToRegexp(path);\n middlewares.push({\n src: pattern,\n fn: getHandler({\n application,\n flagFn,\n pattern,\n }),\n });\n }\n }\n }\n }\n }\n return middlewares;\n}\n\n/**\n * Executes the middlewares returned by `getMicrofrontendsMiddleware` and\n * returns a `Response` if any of the microfrontends middlewares match or\n * `undefined` if none match. If a `Response` object is returned, the calling\n * code should return that Response from the Next.js middleware in order to\n * stop execution of the middleware and perform the rewrite.\n */\nexport async function runMicrofrontendsMiddleware(\n request: NextRequest,\n flagValues?: Record<string, () => Promise<boolean>>,\n): Promise<Response | undefined> {\n const pathname = request.nextUrl.pathname;\n const middlewares = getMicrofrontendsMiddleware({\n request,\n flagValues,\n });\n\n for (const mware of middlewares) {\n if (\n typeof mware.src === 'string'\n ? pathname === mware.src\n : mware.src.test(pathname)\n ) {\n // eslint-disable-next-line no-await-in-loop\n const response = await mware.fn(request);\n if (response) {\n return response;\n }\n }\n }\n}\n","/// <reference types=\"@edge-runtime/types\" />\n\nimport { parse } from 'jsonc-parser';\nimport { MicrofrontendConfigCommon } from '../common/microfrontend-config';\nimport type { Config } from '../schema';\nimport { Overrides } from '../overrides';\n\n/**\n * Edge Runtime does not support ajv validation, or fs access.\n * This version of the MicrofrontendConfig does not validate the config shape,\n * and requires the config to be set on the environment.\n *\n * It should be used for Next.js middleware which runs in the Edge Runtime.\n */\nexport class MicrofrontendConfigEdge extends MicrofrontendConfigCommon {\n static fromEnv({\n cookies,\n }: {\n cookies: { name: string; value: string }[];\n }): MicrofrontendConfigEdge {\n return new MicrofrontendConfigCommon({\n config: parse(MicrofrontendConfigCommon.getConfigFromEnv()) as Config,\n overrides: Overrides.parseOverrides(cookies),\n });\n }\n}\n","export type MicrofrontendErrorType =\n | 'config'\n | 'packageJson'\n | 'vercelJson'\n | 'zone'\n | 'unknown';\n\nexport type MicrofrontendErrorSubtype =\n | 'not_found'\n | 'not_found_in_env'\n | 'invalid_asset_prefix'\n | 'invalid_main_path'\n | 'does_not_match_schema'\n | 'unable_to_read_file'\n | 'unsupported_validation_env'\n | 'unsupported_version'\n | 'invalid_path'\n | 'invalid_permissions'\n | 'invalid_syntax'\n | 'missing_microfrontend_config_path'\n | 'unsupported_operation';\n\n// A mapping of error types to their subtypes.\ninterface TypeToSubtype {\n zone:\n | 'invalid_asset_prefix'\n | 'invalid_path'\n | 'multiple_package_managers'\n | 'not_found';\n config:\n | 'conflicting_paths'\n | 'does_not_match_schema'\n | 'invalid_main_path'\n | 'invalid_preview_deployment_suffix'\n | 'multiple_default_applications'\n | 'no_default_application'\n | 'not_found_in_env'\n | 'not_found'\n | 'unable_to_read_file'\n | 'invalid_syntax'\n | 'invalid_permissions'\n | 'unsupported_operation'\n | 'unsupported_validation_env'\n | 'unsupported_version';\n packageJson:\n | 'missing_field_name'\n | 'unable_to_read_file'\n | 'invalid_permissions'\n | 'invalid_syntax';\n vercelJson:\n | 'missing_field_microFrontend_config_path'\n | 'unable_to_read_file'\n | 'invalid_permissions'\n | 'invalid_syntax';\n unknown: never;\n}\n\nexport type MicrofrontendErrorSource =\n | '@vercel/microfrontends'\n | '@vercel/microfrontends/next'\n | 'fs'\n | 'ajv';\n\nexport interface MicrofrontendErrorOptions<T extends MicrofrontendErrorType> {\n source?: MicrofrontendErrorSource;\n type?: T;\n subtype?: TypeToSubtype[T];\n}\n\ninterface HandleOptions {\n fileName?: string;\n}\n\nexport class MicrofrontendError<\n T extends MicrofrontendErrorType = 'unknown',\n> extends Error {\n public source: MicrofrontendErrorSource;\n public type: T;\n public subtype?: TypeToSubtype[T];\n\n constructor(message: string, opts?: MicrofrontendErrorOptions<T>) {\n super(message);\n this.name = 'MicrofrontendsError';\n this.source = opts?.source ?? '@vercel/microfrontends';\n this.type = opts?.type ?? ('unknown' as T);\n this.subtype = opts?.subtype;\n Error.captureStackTrace(this, MicrofrontendError);\n }\n\n isKnown(): boolean {\n return this.type !== 'unknown';\n }\n\n isUnknown(): boolean {\n return !this.isKnown();\n }\n\n /**\n * Converts an error to a MicrofrontendsError.\n * @param original - The original error to convert.\n * @returns The converted MicrofrontendsError.\n */\n static convert(\n original: Error,\n opts?: HandleOptions,\n ): MicrofrontendError<MicrofrontendErrorType> {\n if (opts?.fileName) {\n const err = MicrofrontendError.convertFSError(original, opts.fileName);\n if (err) {\n return err;\n }\n }\n\n if (\n original.message.includes(\n 'Code generation from strings disallowed for this context',\n )\n ) {\n return new MicrofrontendError(original.message, {\n type: 'config',\n subtype: 'unsupported_validation_env',\n source: 'ajv',\n });\n }\n\n // unknown catch-all\n return new MicrofrontendError(original.message);\n }\n\n static convertFSError(\n original: Error,\n fileName: string,\n ): MicrofrontendError<MicrofrontendErrorType> | null {\n if (original instanceof Error && 'code' in original) {\n if (original.code === 'ENOENT') {\n return new MicrofrontendError(`Could not find \"${fileName}\"`, {\n type: 'config',\n subtype: 'unable_to_read_file',\n source: 'fs',\n });\n }\n if (original.code === 'EACCES') {\n return new MicrofrontendError(\n `Permission denied while accessing \"${fileName}\"`,\n {\n type: 'config',\n subtype: 'invalid_permissions',\n source: 'fs',\n },\n );\n }\n }\n\n if (original instanceof SyntaxError) {\n return new MicrofrontendError(\n `Failed to parse \"${fileName}\": Invalid JSON format.`,\n {\n type: 'config',\n subtype: 'invalid_syntax',\n source: 'fs',\n },\n );\n }\n\n return null;\n }\n\n /**\n * Handles an unknown error and returns a MicrofrontendsError instance.\n * @param err - The error to handle.\n * @returns A MicrofrontendsError instance.\n */\n static handle(\n err: unknown,\n opts?: HandleOptions,\n ): MicrofrontendError<MicrofrontendErrorType> {\n if (err instanceof MicrofrontendError) {\n return err as MicrofrontendError<MicrofrontendErrorType>;\n }\n\n // handle Error instances\n if (err instanceof Error) {\n return MicrofrontendError.convert(err, opts);\n }\n\n // handle object errors\n if (typeof err === 'object' && err !== null) {\n if ('message' in err && typeof err.message === 'string') {\n return MicrofrontendError.convert(new Error(err.message), opts);\n }\n }\n\n return new MicrofrontendError('An unknown error occurred');\n }\n}\n","// NOTE: This is copied from https://github.com/vercel/api/blob/main/packages/util-func/src/url-safe-string.ts.\n// See https://linear.app/vercel/issue/FDRTN-199/spike-move-preview-domain-generation-logic-into-build-and-deploy\n// for cleaning this up before release.\n\ninterface Options {\n joinString?: string;\n lowercaseOnly?: boolean;\n maxLen?: number;\n regexRemovePattern?: RegExp;\n trimWhitespace?: boolean;\n}\n\n/**\n * This function allows to convert single string to URL-safe tags to use for routing,\n * SEO purposes, etc. It is taken from https://www.npmjs.com/package/url-safe-string\n * and implemented here to be typed and skip the dependency.\n */\nfunction buildUrlSafeString(givenOpts: Options = {}): {\n generate: (...args: string[]) => string;\n} {\n const options = {\n joinString: '-',\n lowercaseOnly: true,\n maxLen: 100,\n regexRemovePattern: /(?:(?!(?:[a-z0-9])).)/gi,\n trimWhitespace: true,\n ...givenOpts,\n };\n\n return {\n generate: (...args: string[]) => {\n const reJoinString = new RegExp(`${options.joinString}+`, 'g');\n\n // biome-ignore lint/suspicious/noImplicitAnyLet: Ignored using `--suppress`\n let tag;\n\n if (args.length === 0) {\n throw new Error('generate method must be passed at least one argument');\n }\n\n // Validate, trim all arguments:\n for (let i = 0; i < args.length; i++) {\n const arg = args[i];\n if (typeof arg !== 'string')\n throw new Error('all supplied arguments must be Strings');\n\n if (options.trimWhitespace) {\n args[i] = arg.trim();\n }\n }\n\n // Join strings and convert whitespace between words to join string\n tag = args.join(options.joinString);\n tag = tag.replace(/\\s/g, options.joinString);\n if (options.lowercaseOnly) tag = tag.toLowerCase();\n // Regex away anything \"unsafe\", but ignore the join string!\n tag = tag.replace(options.regexRemovePattern, (match) => {\n if (match === options.joinString) return match;\n\n return '';\n });\n\n // Truncate in excess of maxLen\n if (tag.length > options.maxLen) tag = tag.substring(0, options.maxLen);\n\n // Remove any duplicates of the join string using this pattern: /<join string>+/g\n tag = tag.replace(reJoinString, options.joinString);\n\n return tag;\n },\n };\n}\n\n/**\n * Export a preconfigured version for convenience.\n */\nexport const urlSafeString = buildUrlSafeString().generate;\n\nexport function makeUrlSafe(name: string): string {\n return urlSafeString(name.replace(/\\//g, '-'))\n .replace(/^-*/g, '')\n .replace(/-*$/g, '');\n}\n","import { makeUrlSafe } from '../../routing/url';\nimport type { MicrofrontendConfig } from '../microfrontend-config';\nimport type { OverridesConfig } from './types';\n\nexport const OVERRIDES_COOKIE_PREFIX = 'vercel-micro-frontends-override';\n\nexport class Overrides {\n config: OverridesConfig;\n\n constructor(config: OverridesConfig) {\n this.config = config;\n }\n\n static overrideEnvCookiePrefix = `${OVERRIDES_COOKIE_PREFIX}:env:`;\n\n static getAppEnvOverrideCookieName(zone: string): string {\n return `${Overrides.overrideEnvCookiePrefix}${zone}`;\n }\n\n static isOverrideCookie(cookie: { name?: string }): boolean {\n return Boolean(cookie.name?.startsWith(OVERRIDES_COOKIE_PREFIX));\n }\n\n static getOverrideFromCookie(cookie: {\n name: string;\n value?: string | null;\n }): { zone: string; host: string } | undefined {\n if (!Overrides.isOverrideCookie(cookie) || !cookie.value) return;\n return {\n zone: cookie.name.replace(Overrides.overrideEnvCookiePrefix, ''),\n host: cookie.value,\n };\n }\n\n static parseOverrides(\n cookies: { name: string; value?: string | null }[],\n ): OverridesConfig {\n const overridesConfig: OverridesConfig = { applications: {} };\n\n cookies.forEach((cookie) => {\n const override = Overrides.getOverrideFromCookie(cookie);\n if (!override) return;\n overridesConfig.applications[override.zone] = {\n environment: { host: override.host },\n };\n });\n\n return overridesConfig;\n }\n\n static validOverrideDomainsForZone(\n microfrontendConfig: MicrofrontendConfig,\n zone: string,\n ): string[] {\n const projectName = microfrontendConfig.getZone(zone).vercel?.projectName;\n if (!projectName) {\n return [microfrontendConfig.getZone(zone).production.host];\n }\n const parsedProjectName = makeUrlSafe(projectName);\n const previewDeploymentSuffix =\n microfrontendConfig.options?.vercel?.previewDeploymentSuffix;\n const teamSlug = microfrontendConfig.options?.vercel?.teamSlug;\n if (!teamSlug && !previewDeploymentSuffix) {\n return [microfrontendConfig.getZone(zone).production.host];\n }\n\n const suffix = previewDeploymentSuffix\n ? `.${previewDeploymentSuffix}`\n : `-${teamSlug}.vercel.app`;\n\n // <project-name>-git-<branch-name>-<scope-slug>.vercel.app\n // <project-name>-git-<branch-name>.<custom-suffix>\n return [\n `${parsedProjectName}-git-([a-zA-Z0-9-]+)${suffix}`,\n microfrontendConfig.getZone(zone).production.host,\n ];\n }\n\n static validateOverrideDomain(\n microfrontendConfig: MicrofrontendConfig,\n zone: string,\n domain: string,\n ): boolean {\n return new RegExp(\n `^${Overrides.validOverrideDomainsForZone(microfrontendConfig, zone).join(\n '|',\n )}$`,\n ).test(domain);\n }\n\n serialize(): OverridesConfig {\n return this.config;\n }\n}\n","import type { HostConfig } from '../schema';\n\ninterface HostDisplayOptions {\n includeDefaultPort?: boolean;\n}\n\nexport class Host {\n protocol: 'http' | 'https';\n host: HostConfig['host'];\n port: number;\n serialized: HostConfig;\n\n constructor({ protocol, host, port }: HostConfig) {\n this.protocol = protocol || 'https';\n this.host = host;\n this.port = Host.getPort({ port, protocol: this.protocol });\n this.serialized = {\n protocol,\n host,\n ...(port ? { port } : undefined),\n };\n }\n\n isLocal(): boolean {\n return this.host === 'localhost' || this.host === '127.0.0.1';\n }\n\n static getPort({\n protocol,\n port,\n }: { protocol: HostConfig['protocol']; port?: HostConfig['port'] }): number {\n if (!port) {\n if (protocol === 'http') {\n return 80;\n }\n return 443;\n }\n\n return port;\n }\n\n isDefaultPort(): boolean {\n return this.port === Host.getPort({ protocol: this.protocol });\n }\n\n toString(opts: HostDisplayOptions = {}): string {\n const url = this.toUrl(opts);\n // strip the trailing slash\n return url.toString().replace(/\\/$/, '');\n }\n\n toUrl(opts: HostDisplayOptions = {}): URL {\n const { includeDefaultPort } = opts;\n const url = `${this.protocol}://${this.host}${this.isDefaultPort() && !includeDefaultPort ? '' : `:${this.port}`}`;\n\n return new URL(url);\n }\n\n serialize(): HostConfig {\n return this.serialized;\n }\n}\n","import type { ApplicationConfig, Routing, Vercel } from '../schema';\nimport type { ApplicationOverrideConfig } from '../overrides';\nimport { MicrofrontendError } from '../errors';\nimport { Host } from './host';\n\nexport class Application {\n default: boolean;\n routing?: Routing;\n name: string;\n development: {\n local: Host;\n fallback?: Host;\n };\n production: Host;\n vercel?: Vercel;\n overrides?: {\n environment?: Host;\n };\n\n constructor(\n name: string,\n {\n app,\n overrides,\n }: { app: ApplicationConfig; overrides?: ApplicationOverrideConfig },\n ) {\n // validate\n Application.validate(name, app);\n\n this.name = name;\n this.default = app.default;\n this.routing = app.routing;\n this.development = {\n local: new Host(app.development.local),\n fallback: app.development.fallback\n ? new Host(app.development.fallback)\n : undefined,\n };\n this.production = new Host(app.production);\n this.vercel = app.vercel;\n this.overrides = overrides?.environment\n ? {\n environment: new Host(overrides.environment),\n }\n : undefined;\n }\n\n isDefault(): boolean {\n return this.default;\n }\n\n static validate(name: string, app: ApplicationConfig): void {\n // validate assetPrefix\n if (\n app.routing?.assetPrefix?.startsWith('/') ||\n app.routing?.assetPrefix?.endsWith('/')\n ) {\n throw new MicrofrontendError(\n `Invalid assetPrefix for application \"${name}\". Must not start or end with a slash.`,\n { type: 'zone', subtype: 'invalid_asset_prefix' },\n );\n }\n\n // validate routes\n for (const group of app.routing?.matches ?? []) {\n for (const p of group.paths) {\n if (p === '/') {\n continue;\n }\n if (p.endsWith('/')) {\n throw new MicrofrontendError(\n `Invalid path for application \"${name}\". ${p} must not end with a slash.`,\n { type: 'zone', subtype: 'invalid_path' },\n );\n }\n\n if (!p.startsWith('/')) {\n throw new MicrofrontendError(\n `Invalid path for application \"${name}\". ${p} must start with a slash.`,\n { type: 'zone', subtype: 'invalid_path' },\n );\n }\n }\n }\n }\n\n serialize(): ApplicationConfig {\n if (this.routing === undefined || this.default) {\n return {\n default: true,\n development: {\n local: this.development.local.serialize(),\n fallback: this.development.fallback?.serialize(),\n },\n production: this.production.serialize(),\n vercel: this.vercel,\n };\n }\n\n return {\n default: false,\n routing: this.routing,\n development: {\n local: this.development.local.serialize(),\n fallback: this.development.fallback?.serialize(),\n },\n production: this.production.serialize(),\n vercel: this.vercel,\n };\n }\n}\n","import type { ApplicationConfig, Config, Options } from '../schema';\nimport { MicrofrontendError } from '../errors';\nimport type { OverridesConfig } from '../overrides';\nimport { Overrides } from '../overrides/config';\nimport { Application } from './application';\n\nconst SUPPORTED_VERSIONS = ['1'];\nconst DEFAULT_LOCAL_PROXY_PORT = 3024;\n\n/**\n * A class to manage the microfrontends configuration.\n *\n * This class should not be used directly. Instead, use the `MicrofrontendConfig` or `MicrofrontendConfigEdgeRuntime` classes.\n */\nexport class MicrofrontendConfigCommon {\n config: Config;\n name?: string;\n zones: Record<string, Application> = {};\n version: string;\n overrides?: Overrides;\n options?: Options;\n $schema: string | undefined;\n\n constructor({\n config,\n overrides,\n }: { config: Config; overrides?: OverridesConfig }) {\n if (!SUPPORTED_VERSIONS.includes(config.version)) {\n throw new MicrofrontendError(\n `Unsupported version: ${config.version}. Supported versions are: ${SUPPORTED_VERSIONS.join(\n ', ',\n )}`,\n { type: 'config', subtype: 'unsupported_version' },\n );\n }\n const disableOverrides = config.options?.vercel?.disableOverrides ?? false;\n\n this.overrides =\n overrides && !disableOverrides ? new Overrides(overrides) : undefined;\n\n // create zones\n for (const [zoneName, zoneConfig] of Object.entries(config.applications)) {\n this.zones[zoneName] = new Application(zoneName, {\n app: zoneConfig,\n overrides: !disableOverrides\n ? this.overrides?.config.applications[zoneName]\n : undefined,\n });\n }\n\n this.config = config;\n this.name = config.name;\n this.version = config.version;\n this.options = config.options;\n this.$schema = config.$schema;\n }\n\n isOverridesDisabled(): boolean {\n return this.options?.vercel?.disableOverrides ?? false;\n }\n\n protected static getConfigFromEnv(): string {\n const config = process.env.MFE_CONFIG;\n if (!config) {\n throw new MicrofrontendError(`Missing \"MFE_CONFIG\" in environment.`, {\n type: 'config',\n subtype: 'not_found_in_env',\n });\n }\n return config;\n }\n\n static fromEnv(_: {\n cookies: { name: string; value: string }[];\n }): MicrofrontendConfigCommon | Promise<MicrofrontendConfigCommon> {\n throw new Error('Not implemented');\n }\n\n getConfig(): Config {\n return this.config;\n }\n\n getAllApplications(): Application[] {\n return Object.values(this.zones);\n }\n\n getZone(name: string): Application {\n const zone = this.zones[name];\n if (!zone) {\n throw new MicrofrontendError(\n `Could not find microfrontends configuration for application \"${name}\"`,\n {\n type: 'zone',\n subtype: 'not_found',\n },\n );\n }\n\n return zone;\n }\n\n getApplicationByProjectId(projectId: string): Application | undefined {\n return Object.values(this.zones).find(\n (zone) => zone.vercel?.projectId === projectId,\n );\n }\n\n getDefaultZone(): Application {\n const zone = Object.values(this.zones).find((z) => z.default);\n if (!zone) {\n throw new MicrofrontendError(\n `Could not find default zone in microfrontends configuration`,\n {\n type: 'zone',\n subtype: 'not_found',\n },\n );\n }\n\n return zone;\n }\n\n /**\n * Returns the configured port for the local proxy\n */\n getLocalProxyPort(): number {\n return this.config.options?.localProxy?.port ?? DEFAULT_LOCAL_PROXY_PORT;\n }\n\n /**\n * Serializes the class back to the Schema type.\n *\n * NOTE: This is used when writing the config to disk and must always match the input Schema\n */\n toSchemaJson(): Config {\n const applications: Record<string, ApplicationConfig> = {};\n for (const [name, zone] of Object.entries(this.zones)) {\n applications[name] = zone.serialize();\n }\n\n return {\n $schema: this.$schema,\n name: this.name,\n version: this.version,\n options: this.options,\n applications,\n };\n }\n\n serialize(): { config: Config; overrides?: OverridesConfig } {\n const applications: Record<string, ApplicationConfig> = {};\n for (const [name, zone] of Object.entries(this.zones)) {\n applications[name] = zone.serialize();\n }\n\n return {\n config: {\n name: this.name,\n version: this.version,\n applications,\n options: this.options,\n $schema: this.$schema,\n },\n overrides: this.overrides?.serialize(),\n };\n }\n\n write(_: string): void {\n throw new MicrofrontendError(\n `Writing to file to disk requires using an instance of \"MicrofrontendConfig\".`,\n { type: 'config', subtype: 'unsupported_operation' },\n );\n }\n}\n","/// <reference types=\"@edge-runtime/types\" />\n\nimport type { Application } from '../config/common/application';\n\nfunction debugDomains(zone: string, env: string, domain: string): void {\n if (process.env.MFE_DEBUG === 'true') {\n const indent = ' '.repeat(4);\n const header = 'domains (zone (env) -> domain)';\n const separator = '⎯'.repeat(header.length);\n const line = `${indent} 1. ${zone} (${env}) -> ${domain}`;\n\n // eslint-disable-next-line no-console\n console.log(`${indent}${header}\\n${indent}${separator}\\n${line}\\n`);\n }\n}\n\n/**\n * Returns the Vercel domain for the given application based on the current\n * environment (local, preview, production).\n */\nexport function getDomainForCurrentEnvironment(zone: Application): string {\n if (zone.overrides?.environment) {\n return zone.overrides.environment.toString();\n }\n const zoneName = zone.name;\n if (!process.env.VERCEL_ENV || process.env.VERCEL_ENV === 'development') {\n // TODO(mknichel): Convert this back to the local development domain once\n // there is local development proxy support.\n const domain =\n process.env.NODE_ENV === 'test'\n ? zone.development.local.toString()\n : zone.production.toString();\n debugDomains(zoneName, 'development', domain);\n return domain;\n } else if (process.env.VERCEL_ENV === 'production') {\n const domain = zone.production.toString();\n debugDomains(zoneName, 'production', domain);\n return domain;\n } else if (process.env.VERCEL_ENV === 'preview') {\n const MFE_PREVIEW_DOMAINS = JSON.parse(\n process.env.MFE_PREVIEW_DOMAINS ?? '{}',\n ) as Record<string, string>;\n if (MFE_PREVIEW_DOMAINS[zoneName]) {\n debugDomains(zoneName, 'preview', MFE_PREVIEW_DOMAINS[zoneName]);\n return MFE_PREVIEW_DOMAINS[zoneName];\n }\n\n throw new Error(\n `Could not find preview domain for application \"${zoneName}\"`,\n );\n }\n // TODO(mknichel): Add support in this function for custom environments.\n // Custom Vercel environments may have an arbitrary string for `VERCEL_ENV`.\n debugDomains(zoneName, process.env.VERCEL_ENV, zone.production.toString());\n return zone.production.toString();\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/next/middleware/index.ts","../../src/next/middleware/middleware.ts","../../src/config/edge/microfrontend-config.ts","../../src/config/errors.ts","../../src/routing/url.ts","../../src/config/overrides/config.ts","../../src/config/common/host.ts","../../src/config/common/application.ts","../../src/config/common/microfrontend-config.ts","../../src/routing/get-domain-for-current-environment.ts"],"sourcesContent":["export * from './middleware';\nexport * from './types';\n","/// <reference types=\"@edge-runtime/types\" />\n\nimport type { NextRequest } from 'next/server';\nimport { NextResponse } from 'next/server';\nimport { pathToRegexp } from 'path-to-regexp';\nimport { MicrofrontendConfigEdge } from '../../config/edge/microfrontend-config';\nimport { getDomainForCurrentEnvironment } from '../../routing/get-domain-for-current-environment';\nimport type { Application } from '../../config/common/application';\nimport type { HostConfig } from '../../config/schema';\nimport type {\n MicrofrontendsMiddleware,\n MicrofrontendsMiddlewareHandler,\n} from './types';\n\ninterface GetHandlerParams {\n application: Application;\n flagFn?: () => Promise<boolean>;\n pattern: RegExp;\n}\n\ninterface InternalRouting {\n routing: HostConfig;\n}\n\nasync function verifyPreviewDomain(\n req: NextRequest,\n rewriteDomain: string,\n): Promise<boolean> {\n const jwtCookie = req.cookies.get('_vercel_jwt')?.value;\n const deploymentProtectionBypassHeader = req.headers.get(\n 'x-vercel-protection-bypass',\n );\n\n // We make a `HEAD` request with `x-vercel-micro-frontends-check: 1` which will get handled in the proxy without reaching the deployment\n const previewResponse = await fetch(rewriteDomain, {\n method: 'HEAD',\n headers: {\n 'x-vercel-micro-frontends-check': '1',\n ...(jwtCookie ? { cookie: `_vercel_jwt=${jwtCookie}` } : {}),\n ...(deploymentProtectionBypassHeader\n ? {\n 'x-vercel-protection-bypass': deploymentProtectionBypassHeader,\n }\n : {}),\n },\n });\n\n const vercelError = previewResponse.headers.get('x-vercel-error');\n return !(\n previewResponse.status === 404 &&\n (vercelError === 'DEPLOYMENT_NOT_FOUND' || vercelError === 'NOT_FOUND')\n );\n}\n\nfunction microfrontendInternalRoutingHandler({\n config,\n}: { config: MicrofrontendConfigEdge }): MicrofrontendsMiddlewareHandler {\n return async (req: NextRequest): Promise<NextResponse> => {\n const payload: Record<string, InternalRouting> = Object.fromEntries(\n await Promise.all(\n config.getAllApplications().map(async (application) => {\n let rewriteDomain = getDomainForCurrentEnvironment(application, {\n ignoreOverride: true,\n });\n const isPreviewDomainAvailable = await verifyPreviewDomain(\n req,\n rewriteDomain,\n );\n\n if (!isPreviewDomainAvailable) {\n rewriteDomain = application.production.toString();\n }\n\n const url = new URL(rewriteDomain);\n return [application.name, { routing: { host: url.host } }] as const;\n }),\n ),\n );\n\n return NextResponse.json(payload);\n };\n}\n\nfunction getHandler({\n application,\n flagFn,\n pattern,\n}: GetHandlerParams): MicrofrontendsMiddlewareHandler {\n return async (req: NextRequest): Promise<NextResponse | undefined> => {\n const pathname = req.nextUrl.pathname;\n const search = req.nextUrl.search;\n\n // If this header is present, it means the proxy handled the routing.\n // Eventually the middleware should use proxy logic for all deployed envs (all except local)\n const proxyRouting = req.headers.get('X-Vercel-Mfe-Proxy') === '1';\n\n let rewriteDomain = proxyRouting\n ? null\n : getDomainForCurrentEnvironment(application);\n const patchedHeaders = new Headers(req.headers);\n\n const responseCallbacks: ((response: NextResponse) => void)[] = [];\n const onRewrite: (response: NextResponse) => NextResponse = (response) => {\n for (const callback of responseCallbacks) {\n callback(response);\n }\n\n return response;\n };\n\n // If this is a preview environment, we check the domain to make sure the project was deployed\n if (process.env.VERCEL_ENV === 'preview' && rewriteDomain) {\n const zoneFallbackCookieName = `__zone_${application.name}_production_fallback`;\n const assetPrefix = application.routing?.assetPrefix;\n\n if (\n assetPrefix &&\n pathname.startsWith(`/${assetPrefix}`) &&\n req.cookies.get(zoneFallbackCookieName)?.value === '1'\n ) {\n // If this is an asset request and we have the cookie, we can safely route to production without fetching\n rewriteDomain = application.production.toString();\n } else {\n try {\n let deploymentFound: boolean;\n if (req.headers.get('x-vercel-skip-deployment-existence-check')) {\n deploymentFound = true;\n } else {\n deploymentFound = await verifyPreviewDomain(req, rewriteDomain);\n }\n\n if (!deploymentFound) {\n // If the deployment is not found, we rewrite to the production domain\n rewriteDomain = application.production.toString();\n\n // We set a 1 minute cookie for the application to avoid checking again for every request\n responseCallbacks.push((response) => {\n response.cookies.set(zoneFallbackCookieName, '1', {\n httpOnly: true,\n sameSite: 'lax',\n secure: true,\n maxAge: 60, // 1 minute\n });\n });\n\n // When routing to a production url, we need to enable the toolbar manually,\n // since production deployments rely on the extension to do that, but the extension can't match the top-level domain\n try {\n const existingCookie = patchedHeaders.get('cookie');\n\n // If the request doesn't contain the toolbar cookie, we add it to support the middleware injection\n if (!existingCookie?.includes('__vercel_toolbar')) {\n patchedHeaders.set(\n 'cookie',\n [`__vercel_toolbar=1`, existingCookie].join('; '),\n );\n\n // We also return a `set-cookie` header to set the cookie locally, to support the Next.js injection which checks the document\n responseCallbacks.push((response) => {\n response.cookies.set('__vercel_toolbar', '1', {\n httpOnly: false,\n sameSite: 'lax',\n secure: true,\n maxAge: 29030400,\n });\n });\n }\n } catch (error) {\n // Do Nothing\n }\n } else if (req.cookies.get(zoneFallbackCookieName)?.value === '1') {\n // If the preview exists and we have the fallback cookie, we make sure to clear the cookie to route subsequent assets to the preview\n responseCallbacks.push((response) => {\n response.cookies.set(zoneFallbackCookieName, '', {\n httpOnly: true,\n sameSite: 'lax',\n secure: true,\n maxAge: 0,\n });\n });\n }\n } catch {\n // Do Nothing\n }\n }\n }\n\n const isFlagEnabled = async (): Promise<boolean> =>\n flagFn ? flagFn() : true;\n\n // If the pattern doesn't match, we don't need to execute the flag\n if (pattern.test(pathname) && (await isFlagEnabled())) {\n if (proxyRouting) {\n const headers = new Headers(req.headers);\n /**\n * This header informs the proxy which zone the route the request to.\n * It will override any provided redirect / rewrite host.\n *\n * If a rewrite / redirect includes this header, the proxy will perform the\n * action, but will also replace the host with corresponding host for the zone.\n */\n headers.set('x-vercel-mfe-zone', application.name);\n return onRewrite(\n NextResponse.next({\n request: {\n headers,\n },\n headers: {\n // temporary, can delete when proxyRouting flag is removed\n 'x-vercel-mfe-middleware-sent-proxy': application.name,\n },\n }),\n );\n }\n return onRewrite(\n NextResponse.rewrite(`${rewriteDomain}${pathname}${search}`, {\n request: {\n headers: patchedHeaders,\n },\n }),\n );\n }\n };\n // If the path does not match the pattern, we don't do anything and let the request continue\n}\n\n/**\n * Returns an array of middleware functions that will handle routing to the\n * right microfrontends for the provided configuration.\n *\n * @param config - The microfrontends configuration object.\n * @param flagValues - An object that maps flag names to functions that return the flag value.\n */\nexport function getMicrofrontendsMiddleware({\n request,\n flagValues,\n}: {\n request: NextRequest;\n flagValues?: Record<string, () => Promise<boolean>>;\n}): MicrofrontendsMiddleware[] {\n const config = MicrofrontendConfigEdge.fromEnv({\n cookies: request.cookies.getAll(),\n });\n const middlewares: MicrofrontendsMiddleware[] = [];\n\n middlewares.push({\n src: '/.well-known/vercel/microfrontend-routing',\n fn: microfrontendInternalRoutingHandler({ config }),\n });\n\n for (const application of config.getAllApplications()) {\n if (application.name === process.env.NEXT_PUBLIC_MFE_CURRENT_APPLICATION) {\n continue;\n }\n if (application.routing) {\n if (\n process.env.VERCEL_ENV === 'preview' &&\n application.routing.assetPrefix\n ) {\n const pattern = pathToRegexp(\n `/${application.routing.assetPrefix}/:path+`,\n );\n middlewares.push({\n src: pattern,\n fn: getHandler({\n application,\n pattern,\n }),\n });\n }\n for (const pathGroup of application.routing.matches) {\n if (process.env.VERCEL_ENV === 'preview' || pathGroup.options?.flag) {\n const flagName = pathGroup.options?.flag;\n // biome-ignore lint/suspicious/noImplicitAnyLet: Ignored using `--suppress`\n let flagFn;\n if (flagName) {\n flagFn = flagValues?.[flagName];\n if (!flagFn) {\n throw new Error(\n `Flag \"${flagName}\" was specified to control routing for path group \"${pathGroup.group}\" in application ${application.name} but not found in provided flag values.`,\n );\n }\n }\n for (const path of pathGroup.paths) {\n const pattern = pathToRegexp(path);\n middlewares.push({\n src: pattern,\n fn: getHandler({\n application,\n flagFn,\n pattern,\n }),\n });\n }\n }\n }\n }\n }\n return middlewares;\n}\n\n/**\n * Executes the middlewares returned by `getMicrofrontendsMiddleware` and\n * returns a `Response` if any of the microfrontends middlewares match or\n * `undefined` if none match. If a `Response` object is returned, the calling\n * code should return that Response from the Next.js middleware in order to\n * stop execution of the middleware and perform the rewrite.\n */\nexport async function runMicrofrontendsMiddleware(\n request: NextRequest,\n flagValues?: Record<string, () => Promise<boolean>>,\n): Promise<Response | undefined> {\n const pathname = request.nextUrl.pathname;\n const middlewares = getMicrofrontendsMiddleware({\n request,\n flagValues,\n });\n\n for (const mware of middlewares) {\n if (\n typeof mware.src === 'string'\n ? pathname === mware.src\n : mware.src.test(pathname)\n ) {\n // eslint-disable-next-line no-await-in-loop\n const response = await mware.fn(request);\n if (response) {\n return response;\n }\n }\n }\n}\n","/// <reference types=\"@edge-runtime/types\" />\n\nimport { parse } from 'jsonc-parser';\nimport { MicrofrontendConfigCommon } from '../common/microfrontend-config';\nimport type { Config } from '../schema';\nimport { Overrides } from '../overrides';\n\n/**\n * Edge Runtime does not support ajv validation, or fs access.\n * This version of the MicrofrontendConfig does not validate the config shape,\n * and requires the config to be set on the environment.\n *\n * It should be used for Next.js middleware which runs in the Edge Runtime.\n */\nexport class MicrofrontendConfigEdge extends MicrofrontendConfigCommon {\n static fromEnv({\n cookies,\n }: {\n cookies: { name: string; value: string }[];\n }): MicrofrontendConfigEdge {\n return new MicrofrontendConfigCommon({\n config: parse(MicrofrontendConfigCommon.getConfigFromEnv()) as Config,\n overrides: Overrides.parseOverrides(cookies),\n });\n }\n}\n","export type MicrofrontendErrorType =\n | 'config'\n | 'packageJson'\n | 'vercelJson'\n | 'zone'\n | 'unknown';\n\nexport type MicrofrontendErrorSubtype =\n | 'not_found'\n | 'not_found_in_env'\n | 'invalid_asset_prefix'\n | 'invalid_main_path'\n | 'does_not_match_schema'\n | 'unable_to_read_file'\n | 'unsupported_validation_env'\n | 'unsupported_version'\n | 'invalid_path'\n | 'invalid_permissions'\n | 'invalid_syntax'\n | 'missing_microfrontend_config_path'\n | 'unsupported_operation';\n\n// A mapping of error types to their subtypes.\ninterface TypeToSubtype {\n zone:\n | 'invalid_asset_prefix'\n | 'invalid_path'\n | 'multiple_package_managers'\n | 'not_found';\n config:\n | 'conflicting_paths'\n | 'does_not_match_schema'\n | 'invalid_main_path'\n | 'invalid_preview_deployment_suffix'\n | 'multiple_default_applications'\n | 'no_default_application'\n | 'not_found_in_env'\n | 'not_found'\n | 'unable_to_read_file'\n | 'invalid_syntax'\n | 'invalid_permissions'\n | 'unsupported_operation'\n | 'unsupported_validation_env'\n | 'unsupported_version';\n packageJson:\n | 'missing_field_name'\n | 'unable_to_read_file'\n | 'invalid_permissions'\n | 'invalid_syntax';\n vercelJson:\n | 'missing_field_microFrontend_config_path'\n | 'unable_to_read_file'\n | 'invalid_permissions'\n | 'invalid_syntax';\n unknown: never;\n}\n\nexport type MicrofrontendErrorSource =\n | '@vercel/microfrontends'\n | '@vercel/microfrontends/next'\n | 'fs'\n | 'ajv';\n\nexport interface MicrofrontendErrorOptions<T extends MicrofrontendErrorType> {\n source?: MicrofrontendErrorSource;\n type?: T;\n subtype?: TypeToSubtype[T];\n}\n\ninterface HandleOptions {\n fileName?: string;\n}\n\nexport class MicrofrontendError<\n T extends MicrofrontendErrorType = 'unknown',\n> extends Error {\n public source: MicrofrontendErrorSource;\n public type: T;\n public subtype?: TypeToSubtype[T];\n\n constructor(message: string, opts?: MicrofrontendErrorOptions<T>) {\n super(message);\n this.name = 'MicrofrontendsError';\n this.source = opts?.source ?? '@vercel/microfrontends';\n this.type = opts?.type ?? ('unknown' as T);\n this.subtype = opts?.subtype;\n Error.captureStackTrace(this, MicrofrontendError);\n }\n\n isKnown(): boolean {\n return this.type !== 'unknown';\n }\n\n isUnknown(): boolean {\n return !this.isKnown();\n }\n\n /**\n * Converts an error to a MicrofrontendsError.\n * @param original - The original error to convert.\n * @returns The converted MicrofrontendsError.\n */\n static convert(\n original: Error,\n opts?: HandleOptions,\n ): MicrofrontendError<MicrofrontendErrorType> {\n if (opts?.fileName) {\n const err = MicrofrontendError.convertFSError(original, opts.fileName);\n if (err) {\n return err;\n }\n }\n\n if (\n original.message.includes(\n 'Code generation from strings disallowed for this context',\n )\n ) {\n return new MicrofrontendError(original.message, {\n type: 'config',\n subtype: 'unsupported_validation_env',\n source: 'ajv',\n });\n }\n\n // unknown catch-all\n return new MicrofrontendError(original.message);\n }\n\n static convertFSError(\n original: Error,\n fileName: string,\n ): MicrofrontendError<MicrofrontendErrorType> | null {\n if (original instanceof Error && 'code' in original) {\n if (original.code === 'ENOENT') {\n return new MicrofrontendError(`Could not find \"${fileName}\"`, {\n type: 'config',\n subtype: 'unable_to_read_file',\n source: 'fs',\n });\n }\n if (original.code === 'EACCES') {\n return new MicrofrontendError(\n `Permission denied while accessing \"${fileName}\"`,\n {\n type: 'config',\n subtype: 'invalid_permissions',\n source: 'fs',\n },\n );\n }\n }\n\n if (original instanceof SyntaxError) {\n return new MicrofrontendError(\n `Failed to parse \"${fileName}\": Invalid JSON format.`,\n {\n type: 'config',\n subtype: 'invalid_syntax',\n source: 'fs',\n },\n );\n }\n\n return null;\n }\n\n /**\n * Handles an unknown error and returns a MicrofrontendsError instance.\n * @param err - The error to handle.\n * @returns A MicrofrontendsError instance.\n */\n static handle(\n err: unknown,\n opts?: HandleOptions,\n ): MicrofrontendError<MicrofrontendErrorType> {\n if (err instanceof MicrofrontendError) {\n return err as MicrofrontendError<MicrofrontendErrorType>;\n }\n\n // handle Error instances\n if (err instanceof Error) {\n return MicrofrontendError.convert(err, opts);\n }\n\n // handle object errors\n if (typeof err === 'object' && err !== null) {\n if ('message' in err && typeof err.message === 'string') {\n return MicrofrontendError.convert(new Error(err.message), opts);\n }\n }\n\n return new MicrofrontendError('An unknown error occurred');\n }\n}\n","// NOTE: This is copied from https://github.com/vercel/api/blob/main/packages/util-func/src/url-safe-string.ts.\n// See https://linear.app/vercel/issue/FDRTN-199/spike-move-preview-domain-generation-logic-into-build-and-deploy\n// for cleaning this up before release.\n\ninterface Options {\n joinString?: string;\n lowercaseOnly?: boolean;\n maxLen?: number;\n regexRemovePattern?: RegExp;\n trimWhitespace?: boolean;\n}\n\n/**\n * This function allows to convert single string to URL-safe tags to use for routing,\n * SEO purposes, etc. It is taken from https://www.npmjs.com/package/url-safe-string\n * and implemented here to be typed and skip the dependency.\n */\nfunction buildUrlSafeString(givenOpts: Options = {}): {\n generate: (...args: string[]) => string;\n} {\n const options = {\n joinString: '-',\n lowercaseOnly: true,\n maxLen: 100,\n regexRemovePattern: /(?:(?!(?:[a-z0-9])).)/gi,\n trimWhitespace: true,\n ...givenOpts,\n };\n\n return {\n generate: (...args: string[]) => {\n const reJoinString = new RegExp(`${options.joinString}+`, 'g');\n\n // biome-ignore lint/suspicious/noImplicitAnyLet: Ignored using `--suppress`\n let tag;\n\n if (args.length === 0) {\n throw new Error('generate method must be passed at least one argument');\n }\n\n // Validate, trim all arguments:\n for (let i = 0; i < args.length; i++) {\n const arg = args[i];\n if (typeof arg !== 'string')\n throw new Error('all supplied arguments must be Strings');\n\n if (options.trimWhitespace) {\n args[i] = arg.trim();\n }\n }\n\n // Join strings and convert whitespace between words to join string\n tag = args.join(options.joinString);\n tag = tag.replace(/\\s/g, options.joinString);\n if (options.lowercaseOnly) tag = tag.toLowerCase();\n // Regex away anything \"unsafe\", but ignore the join string!\n tag = tag.replace(options.regexRemovePattern, (match) => {\n if (match === options.joinString) return match;\n\n return '';\n });\n\n // Truncate in excess of maxLen\n if (tag.length > options.maxLen) tag = tag.substring(0, options.maxLen);\n\n // Remove any duplicates of the join string using this pattern: /<join string>+/g\n tag = tag.replace(reJoinString, options.joinString);\n\n return tag;\n },\n };\n}\n\n/**\n * Export a preconfigured version for convenience.\n */\nexport const urlSafeString = buildUrlSafeString().generate;\n\nexport function makeUrlSafe(name: string): string {\n return urlSafeString(name.replace(/\\//g, '-'))\n .replace(/^-*/g, '')\n .replace(/-*$/g, '');\n}\n","import { makeUrlSafe } from '../../routing/url';\nimport type { MicrofrontendConfig } from '../microfrontend-config';\nimport type { OverridesConfig } from './types';\n\nexport const OVERRIDES_COOKIE_PREFIX = 'vercel-micro-frontends-override';\n\nexport class Overrides {\n config: OverridesConfig;\n\n constructor(config: OverridesConfig) {\n this.config = config;\n }\n\n static overrideEnvCookiePrefix = `${OVERRIDES_COOKIE_PREFIX}:env:`;\n\n static getAppEnvOverrideCookieName(zone: string): string {\n return `${Overrides.overrideEnvCookiePrefix}${zone}`;\n }\n\n static isOverrideCookie(cookie: { name?: string }): boolean {\n return Boolean(cookie.name?.startsWith(OVERRIDES_COOKIE_PREFIX));\n }\n\n static getOverrideFromCookie(cookie: {\n name: string;\n value?: string | null;\n }): { zone: string; host: string } | undefined {\n if (!Overrides.isOverrideCookie(cookie) || !cookie.value) return;\n return {\n zone: cookie.name.replace(Overrides.overrideEnvCookiePrefix, ''),\n host: cookie.value,\n };\n }\n\n static parseOverrides(\n cookies: { name: string; value?: string | null }[],\n ): OverridesConfig {\n const overridesConfig: OverridesConfig = { applications: {} };\n\n cookies.forEach((cookie) => {\n const override = Overrides.getOverrideFromCookie(cookie);\n if (!override) return;\n overridesConfig.applications[override.zone] = {\n environment: { host: override.host },\n };\n });\n\n return overridesConfig;\n }\n\n static validOverrideDomainsForZone(\n microfrontendConfig: MicrofrontendConfig,\n zone: string,\n ): string[] {\n const projectName = microfrontendConfig.getZone(zone).vercel?.projectName;\n if (!projectName) {\n return [microfrontendConfig.getZone(zone).production.host];\n }\n const parsedProjectName = makeUrlSafe(projectName);\n const previewDeploymentSuffix =\n microfrontendConfig.options?.vercel?.previewDeploymentSuffix;\n const teamSlug = microfrontendConfig.options?.vercel?.teamSlug;\n if (!teamSlug && !previewDeploymentSuffix) {\n return [microfrontendConfig.getZone(zone).production.host];\n }\n\n const suffix = previewDeploymentSuffix\n ? `.${previewDeploymentSuffix}`\n : `-${teamSlug}.vercel.app`;\n\n // <project-name>-git-<branch-name>-<scope-slug>.vercel.app\n // <project-name>-git-<branch-name>.<custom-suffix>\n return [\n `${parsedProjectName}-git-([a-zA-Z0-9-]+)${suffix}`,\n microfrontendConfig.getZone(zone).production.host,\n ];\n }\n\n static validateOverrideDomain(\n microfrontendConfig: MicrofrontendConfig,\n zone: string,\n domain: string,\n ): boolean {\n return new RegExp(\n `^${Overrides.validOverrideDomainsForZone(microfrontendConfig, zone).join(\n '|',\n )}$`,\n ).test(domain);\n }\n\n serialize(): OverridesConfig {\n return this.config;\n }\n}\n","import type { HostConfig } from '../schema';\n\ninterface HostDisplayOptions {\n includeDefaultPort?: boolean;\n}\n\nexport class Host {\n protocol: 'http' | 'https';\n host: HostConfig['host'];\n port: number;\n serialized: HostConfig;\n\n constructor({ protocol, host, port }: HostConfig) {\n this.protocol = protocol || 'https';\n this.host = host;\n this.port = Host.getPort({ port, protocol: this.protocol });\n this.serialized = {\n protocol,\n host,\n ...(port ? { port } : undefined),\n };\n }\n\n isLocal(): boolean {\n return this.host === 'localhost' || this.host === '127.0.0.1';\n }\n\n static getPort({\n protocol,\n port,\n }: { protocol: HostConfig['protocol']; port?: HostConfig['port'] }): number {\n if (!port) {\n if (protocol === 'http') {\n return 80;\n }\n return 443;\n }\n\n return port;\n }\n\n isDefaultPort(): boolean {\n return this.port === Host.getPort({ protocol: this.protocol });\n }\n\n toString(opts: HostDisplayOptions = {}): string {\n const url = this.toUrl(opts);\n // strip the trailing slash\n return url.toString().replace(/\\/$/, '');\n }\n\n toUrl(opts: HostDisplayOptions = {}): URL {\n const { includeDefaultPort } = opts;\n const url = `${this.protocol}://${this.host}${this.isDefaultPort() && !includeDefaultPort ? '' : `:${this.port}`}`;\n\n return new URL(url);\n }\n\n serialize(): HostConfig {\n return this.serialized;\n }\n}\n","import type { ApplicationConfig, Routing, Vercel } from '../schema';\nimport type { ApplicationOverrideConfig } from '../overrides';\nimport { MicrofrontendError } from '../errors';\nimport { Host } from './host';\n\nexport class Application {\n default: boolean;\n routing?: Routing;\n name: string;\n development: {\n local: Host;\n fallback?: Host;\n };\n production: Host;\n vercel?: Vercel;\n overrides?: {\n environment?: Host;\n };\n\n constructor(\n name: string,\n {\n app,\n overrides,\n }: { app: ApplicationConfig; overrides?: ApplicationOverrideConfig },\n ) {\n // validate\n Application.validate(name, app);\n\n this.name = name;\n this.default = app.default;\n this.routing = app.routing;\n this.development = {\n local: new Host(app.development.local),\n fallback: app.development.fallback\n ? new Host(app.development.fallback)\n : undefined,\n };\n this.production = new Host(app.production);\n this.vercel = app.vercel;\n this.overrides = overrides?.environment\n ? {\n environment: new Host(overrides.environment),\n }\n : undefined;\n }\n\n isDefault(): boolean {\n return this.default;\n }\n\n static validate(name: string, app: ApplicationConfig): void {\n // validate assetPrefix\n if (\n app.routing?.assetPrefix?.startsWith('/') ||\n app.routing?.assetPrefix?.endsWith('/')\n ) {\n throw new MicrofrontendError(\n `Invalid assetPrefix for application \"${name}\". Must not start or end with a slash.`,\n { type: 'zone', subtype: 'invalid_asset_prefix' },\n );\n }\n\n // validate routes\n for (const group of app.routing?.matches ?? []) {\n for (const p of group.paths) {\n if (p === '/') {\n continue;\n }\n if (p.endsWith('/')) {\n throw new MicrofrontendError(\n `Invalid path for application \"${name}\". ${p} must not end with a slash.`,\n { type: 'zone', subtype: 'invalid_path' },\n );\n }\n\n if (!p.startsWith('/')) {\n throw new MicrofrontendError(\n `Invalid path for application \"${name}\". ${p} must start with a slash.`,\n { type: 'zone', subtype: 'invalid_path' },\n );\n }\n }\n }\n }\n\n serialize(): ApplicationConfig {\n if (this.routing === undefined || this.default) {\n return {\n default: true,\n development: {\n local: this.development.local.serialize(),\n fallback: this.development.fallback?.serialize(),\n },\n production: this.production.serialize(),\n vercel: this.vercel,\n };\n }\n\n return {\n default: false,\n routing: this.routing,\n development: {\n local: this.development.local.serialize(),\n fallback: this.development.fallback?.serialize(),\n },\n production: this.production.serialize(),\n vercel: this.vercel,\n };\n }\n}\n","import type { ApplicationConfig, Config, Options } from '../schema';\nimport { MicrofrontendError } from '../errors';\nimport type { OverridesConfig } from '../overrides';\nimport { Overrides } from '../overrides/config';\nimport { Application } from './application';\n\nconst SUPPORTED_VERSIONS = ['1'];\nconst DEFAULT_LOCAL_PROXY_PORT = 3024;\n\n/**\n * A class to manage the microfrontends configuration.\n *\n * This class should not be used directly. Instead, use the `MicrofrontendConfig` or `MicrofrontendConfigEdgeRuntime` classes.\n */\nexport class MicrofrontendConfigCommon {\n config: Config;\n name?: string;\n zones: Record<string, Application> = {};\n version: string;\n overrides?: Overrides;\n options?: Options;\n $schema: string | undefined;\n\n constructor({\n config,\n overrides,\n }: { config: Config; overrides?: OverridesConfig }) {\n if (!SUPPORTED_VERSIONS.includes(config.version)) {\n throw new MicrofrontendError(\n `Unsupported version: ${config.version}. Supported versions are: ${SUPPORTED_VERSIONS.join(\n ', ',\n )}`,\n { type: 'config', subtype: 'unsupported_version' },\n );\n }\n const disableOverrides = config.options?.vercel?.disableOverrides ?? false;\n\n this.overrides =\n overrides && !disableOverrides ? new Overrides(overrides) : undefined;\n\n // create zones\n for (const [zoneName, zoneConfig] of Object.entries(config.applications)) {\n this.zones[zoneName] = new Application(zoneName, {\n app: zoneConfig,\n overrides: !disableOverrides\n ? this.overrides?.config.applications[zoneName]\n : undefined,\n });\n }\n\n this.config = config;\n this.name = config.name;\n this.version = config.version;\n this.options = config.options;\n this.$schema = config.$schema;\n }\n\n isOverridesDisabled(): boolean {\n return this.options?.vercel?.disableOverrides ?? false;\n }\n\n protected static getConfigFromEnv(): string {\n const config = process.env.MFE_CONFIG;\n if (!config) {\n throw new MicrofrontendError(`Missing \"MFE_CONFIG\" in environment.`, {\n type: 'config',\n subtype: 'not_found_in_env',\n });\n }\n return config;\n }\n\n static fromEnv(_: {\n cookies: { name: string; value: string }[];\n }): MicrofrontendConfigCommon | Promise<MicrofrontendConfigCommon> {\n throw new Error('Not implemented');\n }\n\n getConfig(): Config {\n return this.config;\n }\n\n getAllApplications(): Application[] {\n return Object.values(this.zones);\n }\n\n getZone(name: string): Application {\n const zone = this.zones[name];\n if (!zone) {\n throw new MicrofrontendError(\n `Could not find microfrontends configuration for application \"${name}\"`,\n {\n type: 'zone',\n subtype: 'not_found',\n },\n );\n }\n\n return zone;\n }\n\n getApplicationByProjectId(projectId: string): Application | undefined {\n return Object.values(this.zones).find(\n (zone) => zone.vercel?.projectId === projectId,\n );\n }\n\n getDefaultZone(): Application {\n const zone = Object.values(this.zones).find((z) => z.default);\n if (!zone) {\n throw new MicrofrontendError(\n `Could not find default zone in microfrontends configuration`,\n {\n type: 'zone',\n subtype: 'not_found',\n },\n );\n }\n\n return zone;\n }\n\n /**\n * Returns the configured port for the local proxy\n */\n getLocalProxyPort(): number {\n return this.config.options?.localProxy?.port ?? DEFAULT_LOCAL_PROXY_PORT;\n }\n\n /**\n * Serializes the class back to the Schema type.\n *\n * NOTE: This is used when writing the config to disk and must always match the input Schema\n */\n toSchemaJson(): Config {\n const applications: Record<string, ApplicationConfig> = {};\n for (const [name, zone] of Object.entries(this.zones)) {\n applications[name] = zone.serialize();\n }\n\n return {\n $schema: this.$schema,\n name: this.name,\n version: this.version,\n options: this.options,\n applications,\n };\n }\n\n serialize(): { config: Config; overrides?: OverridesConfig } {\n const applications: Record<string, ApplicationConfig> = {};\n for (const [name, zone] of Object.entries(this.zones)) {\n applications[name] = zone.serialize();\n }\n\n return {\n config: {\n name: this.name,\n version: this.version,\n applications,\n options: this.options,\n $schema: this.$schema,\n },\n overrides: this.overrides?.serialize(),\n };\n }\n\n write(_: string): void {\n throw new MicrofrontendError(\n `Writing to file to disk requires using an instance of \"MicrofrontendConfig\".`,\n { type: 'config', subtype: 'unsupported_operation' },\n );\n }\n}\n","/// <reference types=\"@edge-runtime/types\" />\n\nimport type { Application } from '../config/common/application';\n\nfunction debugDomains(zone: string, env: string, domain: string): void {\n if (process.env.MFE_DEBUG === 'true') {\n const indent = ' '.repeat(4);\n const header = 'domains (zone (env) -> domain)';\n const separator = '⎯'.repeat(header.length);\n const line = `${indent} 1. ${zone} (${env}) -> ${domain}`;\n\n // eslint-disable-next-line no-console\n console.log(`${indent}${header}\\n${indent}${separator}\\n${line}\\n`);\n }\n}\n\n/**\n * Returns the Vercel domain for the given application based on the current\n * environment (local, preview, production).\n */\nexport function getDomainForCurrentEnvironment(\n zone: Application,\n opts: { ignoreOverride?: boolean } = {},\n): string {\n if (!opts.ignoreOverride && zone.overrides?.environment) {\n return zone.overrides.environment.toString();\n }\n const zoneName = zone.name;\n if (!process.env.VERCEL_ENV || process.env.VERCEL_ENV === 'development') {\n // TODO(mknichel): Convert this back to the local development domain once\n // there is local development proxy support.\n const domain =\n process.env.NODE_ENV === 'test'\n ? zone.development.local.toString()\n : zone.production.toString();\n debugDomains(zoneName, 'development', domain);\n return domain;\n } else if (process.env.VERCEL_ENV === 'production') {\n const domain = zone.production.toString();\n debugDomains(zoneName, 'production', domain);\n return domain;\n } else if (process.env.VERCEL_ENV === 'preview') {\n const MFE_PREVIEW_DOMAINS = JSON.parse(\n process.env.MFE_PREVIEW_DOMAINS ?? '{}',\n ) as Record<string, string>;\n if (MFE_PREVIEW_DOMAINS[zoneName]) {\n debugDomains(zoneName, 'preview', MFE_PREVIEW_DOMAINS[zoneName]);\n return MFE_PREVIEW_DOMAINS[zoneName];\n }\n\n throw new Error(\n `Could not find preview domain for application \"${zoneName}\"`,\n );\n }\n // TODO(mknichel): Add support in this function for custom environments.\n // Custom Vercel environments may have an arbitrary string for `VERCEL_ENV`.\n debugDomains(zoneName, process.env.VERCEL_ENV, zone.production.toString());\n return zone.production.toString();\n}\n"],"mappings":"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","names":[]}
@@ -493,9 +493,9 @@ ${line}
493
493
  `);
494
494
  }
495
495
  }
496
- function getDomainForCurrentEnvironment(zone) {
496
+ function getDomainForCurrentEnvironment(zone, opts = {}) {
497
497
  var _a;
498
- if ((_a = zone.overrides) == null ? void 0 : _a.environment) {
498
+ if (!opts.ignoreOverride && ((_a = zone.overrides) == null ? void 0 : _a.environment)) {
499
499
  return zone.overrides.environment.toString();
500
500
  }
501
501
  const zoneName = zone.name;
@@ -550,7 +550,9 @@ function microfrontendInternalRoutingHandler({
550
550
  const payload = Object.fromEntries(
551
551
  await Promise.all(
552
552
  config.getAllApplications().map(async (application) => {
553
- let rewriteDomain = getDomainForCurrentEnvironment(application);
553
+ let rewriteDomain = getDomainForCurrentEnvironment(application, {
554
+ ignoreOverride: true
555
+ });
554
556
  const isPreviewDomainAvailable = await verifyPreviewDomain(
555
557
  req,
556
558
  rewriteDomain
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/next/middleware/middleware.ts","../../src/config/edge/microfrontend-config.ts","../../src/config/errors.ts","../../src/routing/url.ts","../../src/config/overrides/config.ts","../../src/config/common/host.ts","../../src/config/common/application.ts","../../src/config/common/microfrontend-config.ts","../../src/routing/get-domain-for-current-environment.ts"],"sourcesContent":["/// <reference types=\"@edge-runtime/types\" />\n\nimport type { NextRequest } from 'next/server';\nimport { NextResponse } from 'next/server';\nimport { pathToRegexp } from 'path-to-regexp';\nimport { MicrofrontendConfigEdge } from '../../config/edge/microfrontend-config';\nimport { getDomainForCurrentEnvironment } from '../../routing/get-domain-for-current-environment';\nimport type { Application } from '../../config/common/application';\nimport type { HostConfig } from '../../config/schema';\nimport type {\n MicrofrontendsMiddleware,\n MicrofrontendsMiddlewareHandler,\n} from './types';\n\ninterface GetHandlerParams {\n application: Application;\n flagFn?: () => Promise<boolean>;\n pattern: RegExp;\n}\n\ninterface InternalRouting {\n routing: HostConfig;\n}\n\nasync function verifyPreviewDomain(\n req: NextRequest,\n rewriteDomain: string,\n): Promise<boolean> {\n const jwtCookie = req.cookies.get('_vercel_jwt')?.value;\n const deploymentProtectionBypassHeader = req.headers.get(\n 'x-vercel-protection-bypass',\n );\n\n // We make a `HEAD` request with `x-vercel-micro-frontends-check: 1` which will get handled in the proxy without reaching the deployment\n const previewResponse = await fetch(rewriteDomain, {\n method: 'HEAD',\n headers: {\n 'x-vercel-micro-frontends-check': '1',\n ...(jwtCookie ? { cookie: `_vercel_jwt=${jwtCookie}` } : {}),\n ...(deploymentProtectionBypassHeader\n ? {\n 'x-vercel-protection-bypass': deploymentProtectionBypassHeader,\n }\n : {}),\n },\n });\n\n const vercelError = previewResponse.headers.get('x-vercel-error');\n return !(\n previewResponse.status === 404 &&\n (vercelError === 'DEPLOYMENT_NOT_FOUND' || vercelError === 'NOT_FOUND')\n );\n}\n\nfunction microfrontendInternalRoutingHandler({\n config,\n}: { config: MicrofrontendConfigEdge }): MicrofrontendsMiddlewareHandler {\n return async (req: NextRequest): Promise<NextResponse> => {\n const payload: Record<string, InternalRouting> = Object.fromEntries(\n await Promise.all(\n config.getAllApplications().map(async (application) => {\n let rewriteDomain = getDomainForCurrentEnvironment(application);\n const isPreviewDomainAvailable = await verifyPreviewDomain(\n req,\n rewriteDomain,\n );\n\n if (!isPreviewDomainAvailable) {\n rewriteDomain = application.production.toString();\n }\n\n const url = new URL(rewriteDomain);\n return [application.name, { routing: { host: url.host } }] as const;\n }),\n ),\n );\n\n return NextResponse.json(payload);\n };\n}\n\nfunction getHandler({\n application,\n flagFn,\n pattern,\n}: GetHandlerParams): MicrofrontendsMiddlewareHandler {\n return async (req: NextRequest): Promise<NextResponse | undefined> => {\n const pathname = req.nextUrl.pathname;\n const search = req.nextUrl.search;\n\n // If this header is present, it means the proxy handled the routing.\n // Eventually the middleware should use proxy logic for all deployed envs (all except local)\n const proxyRouting = req.headers.get('X-Vercel-Mfe-Proxy') === '1';\n\n let rewriteDomain = proxyRouting\n ? null\n : getDomainForCurrentEnvironment(application);\n const patchedHeaders = new Headers(req.headers);\n\n const responseCallbacks: ((response: NextResponse) => void)[] = [];\n const onRewrite: (response: NextResponse) => NextResponse = (response) => {\n for (const callback of responseCallbacks) {\n callback(response);\n }\n\n return response;\n };\n\n // If this is a preview environment, we check the domain to make sure the project was deployed\n if (process.env.VERCEL_ENV === 'preview' && rewriteDomain) {\n const zoneFallbackCookieName = `__zone_${application.name}_production_fallback`;\n const assetPrefix = application.routing?.assetPrefix;\n\n if (\n assetPrefix &&\n pathname.startsWith(`/${assetPrefix}`) &&\n req.cookies.get(zoneFallbackCookieName)?.value === '1'\n ) {\n // If this is an asset request and we have the cookie, we can safely route to production without fetching\n rewriteDomain = application.production.toString();\n } else {\n try {\n let deploymentFound: boolean;\n if (req.headers.get('x-vercel-skip-deployment-existence-check')) {\n deploymentFound = true;\n } else {\n deploymentFound = await verifyPreviewDomain(req, rewriteDomain);\n }\n\n if (!deploymentFound) {\n // If the deployment is not found, we rewrite to the production domain\n rewriteDomain = application.production.toString();\n\n // We set a 1 minute cookie for the application to avoid checking again for every request\n responseCallbacks.push((response) => {\n response.cookies.set(zoneFallbackCookieName, '1', {\n httpOnly: true,\n sameSite: 'lax',\n secure: true,\n maxAge: 60, // 1 minute\n });\n });\n\n // When routing to a production url, we need to enable the toolbar manually,\n // since production deployments rely on the extension to do that, but the extension can't match the top-level domain\n try {\n const existingCookie = patchedHeaders.get('cookie');\n\n // If the request doesn't contain the toolbar cookie, we add it to support the middleware injection\n if (!existingCookie?.includes('__vercel_toolbar')) {\n patchedHeaders.set(\n 'cookie',\n [`__vercel_toolbar=1`, existingCookie].join('; '),\n );\n\n // We also return a `set-cookie` header to set the cookie locally, to support the Next.js injection which checks the document\n responseCallbacks.push((response) => {\n response.cookies.set('__vercel_toolbar', '1', {\n httpOnly: false,\n sameSite: 'lax',\n secure: true,\n maxAge: 29030400,\n });\n });\n }\n } catch (error) {\n // Do Nothing\n }\n } else if (req.cookies.get(zoneFallbackCookieName)?.value === '1') {\n // If the preview exists and we have the fallback cookie, we make sure to clear the cookie to route subsequent assets to the preview\n responseCallbacks.push((response) => {\n response.cookies.set(zoneFallbackCookieName, '', {\n httpOnly: true,\n sameSite: 'lax',\n secure: true,\n maxAge: 0,\n });\n });\n }\n } catch {\n // Do Nothing\n }\n }\n }\n\n const isFlagEnabled = async (): Promise<boolean> =>\n flagFn ? flagFn() : true;\n\n // If the pattern doesn't match, we don't need to execute the flag\n if (pattern.test(pathname) && (await isFlagEnabled())) {\n if (proxyRouting) {\n const headers = new Headers(req.headers);\n /**\n * This header informs the proxy which zone the route the request to.\n * It will override any provided redirect / rewrite host.\n *\n * If a rewrite / redirect includes this header, the proxy will perform the\n * action, but will also replace the host with corresponding host for the zone.\n */\n headers.set('x-vercel-mfe-zone', application.name);\n return onRewrite(\n NextResponse.next({\n request: {\n headers,\n },\n headers: {\n // temporary, can delete when proxyRouting flag is removed\n 'x-vercel-mfe-middleware-sent-proxy': application.name,\n },\n }),\n );\n }\n return onRewrite(\n NextResponse.rewrite(`${rewriteDomain}${pathname}${search}`, {\n request: {\n headers: patchedHeaders,\n },\n }),\n );\n }\n };\n // If the path does not match the pattern, we don't do anything and let the request continue\n}\n\n/**\n * Returns an array of middleware functions that will handle routing to the\n * right microfrontends for the provided configuration.\n *\n * @param config - The microfrontends configuration object.\n * @param flagValues - An object that maps flag names to functions that return the flag value.\n */\nexport function getMicrofrontendsMiddleware({\n request,\n flagValues,\n}: {\n request: NextRequest;\n flagValues?: Record<string, () => Promise<boolean>>;\n}): MicrofrontendsMiddleware[] {\n const config = MicrofrontendConfigEdge.fromEnv({\n cookies: request.cookies.getAll(),\n });\n const middlewares: MicrofrontendsMiddleware[] = [];\n\n middlewares.push({\n src: '/.well-known/vercel/microfrontend-routing',\n fn: microfrontendInternalRoutingHandler({ config }),\n });\n\n for (const application of config.getAllApplications()) {\n if (application.name === process.env.NEXT_PUBLIC_MFE_CURRENT_APPLICATION) {\n continue;\n }\n if (application.routing) {\n if (\n process.env.VERCEL_ENV === 'preview' &&\n application.routing.assetPrefix\n ) {\n const pattern = pathToRegexp(\n `/${application.routing.assetPrefix}/:path+`,\n );\n middlewares.push({\n src: pattern,\n fn: getHandler({\n application,\n pattern,\n }),\n });\n }\n for (const pathGroup of application.routing.matches) {\n if (process.env.VERCEL_ENV === 'preview' || pathGroup.options?.flag) {\n const flagName = pathGroup.options?.flag;\n // biome-ignore lint/suspicious/noImplicitAnyLet: Ignored using `--suppress`\n let flagFn;\n if (flagName) {\n flagFn = flagValues?.[flagName];\n if (!flagFn) {\n throw new Error(\n `Flag \"${flagName}\" was specified to control routing for path group \"${pathGroup.group}\" in application ${application.name} but not found in provided flag values.`,\n );\n }\n }\n for (const path of pathGroup.paths) {\n const pattern = pathToRegexp(path);\n middlewares.push({\n src: pattern,\n fn: getHandler({\n application,\n flagFn,\n pattern,\n }),\n });\n }\n }\n }\n }\n }\n return middlewares;\n}\n\n/**\n * Executes the middlewares returned by `getMicrofrontendsMiddleware` and\n * returns a `Response` if any of the microfrontends middlewares match or\n * `undefined` if none match. If a `Response` object is returned, the calling\n * code should return that Response from the Next.js middleware in order to\n * stop execution of the middleware and perform the rewrite.\n */\nexport async function runMicrofrontendsMiddleware(\n request: NextRequest,\n flagValues?: Record<string, () => Promise<boolean>>,\n): Promise<Response | undefined> {\n const pathname = request.nextUrl.pathname;\n const middlewares = getMicrofrontendsMiddleware({\n request,\n flagValues,\n });\n\n for (const mware of middlewares) {\n if (\n typeof mware.src === 'string'\n ? pathname === mware.src\n : mware.src.test(pathname)\n ) {\n // eslint-disable-next-line no-await-in-loop\n const response = await mware.fn(request);\n if (response) {\n return response;\n }\n }\n }\n}\n","/// <reference types=\"@edge-runtime/types\" />\n\nimport { parse } from 'jsonc-parser';\nimport { MicrofrontendConfigCommon } from '../common/microfrontend-config';\nimport type { Config } from '../schema';\nimport { Overrides } from '../overrides';\n\n/**\n * Edge Runtime does not support ajv validation, or fs access.\n * This version of the MicrofrontendConfig does not validate the config shape,\n * and requires the config to be set on the environment.\n *\n * It should be used for Next.js middleware which runs in the Edge Runtime.\n */\nexport class MicrofrontendConfigEdge extends MicrofrontendConfigCommon {\n static fromEnv({\n cookies,\n }: {\n cookies: { name: string; value: string }[];\n }): MicrofrontendConfigEdge {\n return new MicrofrontendConfigCommon({\n config: parse(MicrofrontendConfigCommon.getConfigFromEnv()) as Config,\n overrides: Overrides.parseOverrides(cookies),\n });\n }\n}\n","export type MicrofrontendErrorType =\n | 'config'\n | 'packageJson'\n | 'vercelJson'\n | 'zone'\n | 'unknown';\n\nexport type MicrofrontendErrorSubtype =\n | 'not_found'\n | 'not_found_in_env'\n | 'invalid_asset_prefix'\n | 'invalid_main_path'\n | 'does_not_match_schema'\n | 'unable_to_read_file'\n | 'unsupported_validation_env'\n | 'unsupported_version'\n | 'invalid_path'\n | 'invalid_permissions'\n | 'invalid_syntax'\n | 'missing_microfrontend_config_path'\n | 'unsupported_operation';\n\n// A mapping of error types to their subtypes.\ninterface TypeToSubtype {\n zone:\n | 'invalid_asset_prefix'\n | 'invalid_path'\n | 'multiple_package_managers'\n | 'not_found';\n config:\n | 'conflicting_paths'\n | 'does_not_match_schema'\n | 'invalid_main_path'\n | 'invalid_preview_deployment_suffix'\n | 'multiple_default_applications'\n | 'no_default_application'\n | 'not_found_in_env'\n | 'not_found'\n | 'unable_to_read_file'\n | 'invalid_syntax'\n | 'invalid_permissions'\n | 'unsupported_operation'\n | 'unsupported_validation_env'\n | 'unsupported_version';\n packageJson:\n | 'missing_field_name'\n | 'unable_to_read_file'\n | 'invalid_permissions'\n | 'invalid_syntax';\n vercelJson:\n | 'missing_field_microFrontend_config_path'\n | 'unable_to_read_file'\n | 'invalid_permissions'\n | 'invalid_syntax';\n unknown: never;\n}\n\nexport type MicrofrontendErrorSource =\n | '@vercel/microfrontends'\n | '@vercel/microfrontends/next'\n | 'fs'\n | 'ajv';\n\nexport interface MicrofrontendErrorOptions<T extends MicrofrontendErrorType> {\n source?: MicrofrontendErrorSource;\n type?: T;\n subtype?: TypeToSubtype[T];\n}\n\ninterface HandleOptions {\n fileName?: string;\n}\n\nexport class MicrofrontendError<\n T extends MicrofrontendErrorType = 'unknown',\n> extends Error {\n public source: MicrofrontendErrorSource;\n public type: T;\n public subtype?: TypeToSubtype[T];\n\n constructor(message: string, opts?: MicrofrontendErrorOptions<T>) {\n super(message);\n this.name = 'MicrofrontendsError';\n this.source = opts?.source ?? '@vercel/microfrontends';\n this.type = opts?.type ?? ('unknown' as T);\n this.subtype = opts?.subtype;\n Error.captureStackTrace(this, MicrofrontendError);\n }\n\n isKnown(): boolean {\n return this.type !== 'unknown';\n }\n\n isUnknown(): boolean {\n return !this.isKnown();\n }\n\n /**\n * Converts an error to a MicrofrontendsError.\n * @param original - The original error to convert.\n * @returns The converted MicrofrontendsError.\n */\n static convert(\n original: Error,\n opts?: HandleOptions,\n ): MicrofrontendError<MicrofrontendErrorType> {\n if (opts?.fileName) {\n const err = MicrofrontendError.convertFSError(original, opts.fileName);\n if (err) {\n return err;\n }\n }\n\n if (\n original.message.includes(\n 'Code generation from strings disallowed for this context',\n )\n ) {\n return new MicrofrontendError(original.message, {\n type: 'config',\n subtype: 'unsupported_validation_env',\n source: 'ajv',\n });\n }\n\n // unknown catch-all\n return new MicrofrontendError(original.message);\n }\n\n static convertFSError(\n original: Error,\n fileName: string,\n ): MicrofrontendError<MicrofrontendErrorType> | null {\n if (original instanceof Error && 'code' in original) {\n if (original.code === 'ENOENT') {\n return new MicrofrontendError(`Could not find \"${fileName}\"`, {\n type: 'config',\n subtype: 'unable_to_read_file',\n source: 'fs',\n });\n }\n if (original.code === 'EACCES') {\n return new MicrofrontendError(\n `Permission denied while accessing \"${fileName}\"`,\n {\n type: 'config',\n subtype: 'invalid_permissions',\n source: 'fs',\n },\n );\n }\n }\n\n if (original instanceof SyntaxError) {\n return new MicrofrontendError(\n `Failed to parse \"${fileName}\": Invalid JSON format.`,\n {\n type: 'config',\n subtype: 'invalid_syntax',\n source: 'fs',\n },\n );\n }\n\n return null;\n }\n\n /**\n * Handles an unknown error and returns a MicrofrontendsError instance.\n * @param err - The error to handle.\n * @returns A MicrofrontendsError instance.\n */\n static handle(\n err: unknown,\n opts?: HandleOptions,\n ): MicrofrontendError<MicrofrontendErrorType> {\n if (err instanceof MicrofrontendError) {\n return err as MicrofrontendError<MicrofrontendErrorType>;\n }\n\n // handle Error instances\n if (err instanceof Error) {\n return MicrofrontendError.convert(err, opts);\n }\n\n // handle object errors\n if (typeof err === 'object' && err !== null) {\n if ('message' in err && typeof err.message === 'string') {\n return MicrofrontendError.convert(new Error(err.message), opts);\n }\n }\n\n return new MicrofrontendError('An unknown error occurred');\n }\n}\n","// NOTE: This is copied from https://github.com/vercel/api/blob/main/packages/util-func/src/url-safe-string.ts.\n// See https://linear.app/vercel/issue/FDRTN-199/spike-move-preview-domain-generation-logic-into-build-and-deploy\n// for cleaning this up before release.\n\ninterface Options {\n joinString?: string;\n lowercaseOnly?: boolean;\n maxLen?: number;\n regexRemovePattern?: RegExp;\n trimWhitespace?: boolean;\n}\n\n/**\n * This function allows to convert single string to URL-safe tags to use for routing,\n * SEO purposes, etc. It is taken from https://www.npmjs.com/package/url-safe-string\n * and implemented here to be typed and skip the dependency.\n */\nfunction buildUrlSafeString(givenOpts: Options = {}): {\n generate: (...args: string[]) => string;\n} {\n const options = {\n joinString: '-',\n lowercaseOnly: true,\n maxLen: 100,\n regexRemovePattern: /(?:(?!(?:[a-z0-9])).)/gi,\n trimWhitespace: true,\n ...givenOpts,\n };\n\n return {\n generate: (...args: string[]) => {\n const reJoinString = new RegExp(`${options.joinString}+`, 'g');\n\n // biome-ignore lint/suspicious/noImplicitAnyLet: Ignored using `--suppress`\n let tag;\n\n if (args.length === 0) {\n throw new Error('generate method must be passed at least one argument');\n }\n\n // Validate, trim all arguments:\n for (let i = 0; i < args.length; i++) {\n const arg = args[i];\n if (typeof arg !== 'string')\n throw new Error('all supplied arguments must be Strings');\n\n if (options.trimWhitespace) {\n args[i] = arg.trim();\n }\n }\n\n // Join strings and convert whitespace between words to join string\n tag = args.join(options.joinString);\n tag = tag.replace(/\\s/g, options.joinString);\n if (options.lowercaseOnly) tag = tag.toLowerCase();\n // Regex away anything \"unsafe\", but ignore the join string!\n tag = tag.replace(options.regexRemovePattern, (match) => {\n if (match === options.joinString) return match;\n\n return '';\n });\n\n // Truncate in excess of maxLen\n if (tag.length > options.maxLen) tag = tag.substring(0, options.maxLen);\n\n // Remove any duplicates of the join string using this pattern: /<join string>+/g\n tag = tag.replace(reJoinString, options.joinString);\n\n return tag;\n },\n };\n}\n\n/**\n * Export a preconfigured version for convenience.\n */\nexport const urlSafeString = buildUrlSafeString().generate;\n\nexport function makeUrlSafe(name: string): string {\n return urlSafeString(name.replace(/\\//g, '-'))\n .replace(/^-*/g, '')\n .replace(/-*$/g, '');\n}\n","import { makeUrlSafe } from '../../routing/url';\nimport type { MicrofrontendConfig } from '../microfrontend-config';\nimport type { OverridesConfig } from './types';\n\nexport const OVERRIDES_COOKIE_PREFIX = 'vercel-micro-frontends-override';\n\nexport class Overrides {\n config: OverridesConfig;\n\n constructor(config: OverridesConfig) {\n this.config = config;\n }\n\n static overrideEnvCookiePrefix = `${OVERRIDES_COOKIE_PREFIX}:env:`;\n\n static getAppEnvOverrideCookieName(zone: string): string {\n return `${Overrides.overrideEnvCookiePrefix}${zone}`;\n }\n\n static isOverrideCookie(cookie: { name?: string }): boolean {\n return Boolean(cookie.name?.startsWith(OVERRIDES_COOKIE_PREFIX));\n }\n\n static getOverrideFromCookie(cookie: {\n name: string;\n value?: string | null;\n }): { zone: string; host: string } | undefined {\n if (!Overrides.isOverrideCookie(cookie) || !cookie.value) return;\n return {\n zone: cookie.name.replace(Overrides.overrideEnvCookiePrefix, ''),\n host: cookie.value,\n };\n }\n\n static parseOverrides(\n cookies: { name: string; value?: string | null }[],\n ): OverridesConfig {\n const overridesConfig: OverridesConfig = { applications: {} };\n\n cookies.forEach((cookie) => {\n const override = Overrides.getOverrideFromCookie(cookie);\n if (!override) return;\n overridesConfig.applications[override.zone] = {\n environment: { host: override.host },\n };\n });\n\n return overridesConfig;\n }\n\n static validOverrideDomainsForZone(\n microfrontendConfig: MicrofrontendConfig,\n zone: string,\n ): string[] {\n const projectName = microfrontendConfig.getZone(zone).vercel?.projectName;\n if (!projectName) {\n return [microfrontendConfig.getZone(zone).production.host];\n }\n const parsedProjectName = makeUrlSafe(projectName);\n const previewDeploymentSuffix =\n microfrontendConfig.options?.vercel?.previewDeploymentSuffix;\n const teamSlug = microfrontendConfig.options?.vercel?.teamSlug;\n if (!teamSlug && !previewDeploymentSuffix) {\n return [microfrontendConfig.getZone(zone).production.host];\n }\n\n const suffix = previewDeploymentSuffix\n ? `.${previewDeploymentSuffix}`\n : `-${teamSlug}.vercel.app`;\n\n // <project-name>-git-<branch-name>-<scope-slug>.vercel.app\n // <project-name>-git-<branch-name>.<custom-suffix>\n return [\n `${parsedProjectName}-git-([a-zA-Z0-9-]+)${suffix}`,\n microfrontendConfig.getZone(zone).production.host,\n ];\n }\n\n static validateOverrideDomain(\n microfrontendConfig: MicrofrontendConfig,\n zone: string,\n domain: string,\n ): boolean {\n return new RegExp(\n `^${Overrides.validOverrideDomainsForZone(microfrontendConfig, zone).join(\n '|',\n )}$`,\n ).test(domain);\n }\n\n serialize(): OverridesConfig {\n return this.config;\n }\n}\n","import type { HostConfig } from '../schema';\n\ninterface HostDisplayOptions {\n includeDefaultPort?: boolean;\n}\n\nexport class Host {\n protocol: 'http' | 'https';\n host: HostConfig['host'];\n port: number;\n serialized: HostConfig;\n\n constructor({ protocol, host, port }: HostConfig) {\n this.protocol = protocol || 'https';\n this.host = host;\n this.port = Host.getPort({ port, protocol: this.protocol });\n this.serialized = {\n protocol,\n host,\n ...(port ? { port } : undefined),\n };\n }\n\n isLocal(): boolean {\n return this.host === 'localhost' || this.host === '127.0.0.1';\n }\n\n static getPort({\n protocol,\n port,\n }: { protocol: HostConfig['protocol']; port?: HostConfig['port'] }): number {\n if (!port) {\n if (protocol === 'http') {\n return 80;\n }\n return 443;\n }\n\n return port;\n }\n\n isDefaultPort(): boolean {\n return this.port === Host.getPort({ protocol: this.protocol });\n }\n\n toString(opts: HostDisplayOptions = {}): string {\n const url = this.toUrl(opts);\n // strip the trailing slash\n return url.toString().replace(/\\/$/, '');\n }\n\n toUrl(opts: HostDisplayOptions = {}): URL {\n const { includeDefaultPort } = opts;\n const url = `${this.protocol}://${this.host}${this.isDefaultPort() && !includeDefaultPort ? '' : `:${this.port}`}`;\n\n return new URL(url);\n }\n\n serialize(): HostConfig {\n return this.serialized;\n }\n}\n","import type { ApplicationConfig, Routing, Vercel } from '../schema';\nimport type { ApplicationOverrideConfig } from '../overrides';\nimport { MicrofrontendError } from '../errors';\nimport { Host } from './host';\n\nexport class Application {\n default: boolean;\n routing?: Routing;\n name: string;\n development: {\n local: Host;\n fallback?: Host;\n };\n production: Host;\n vercel?: Vercel;\n overrides?: {\n environment?: Host;\n };\n\n constructor(\n name: string,\n {\n app,\n overrides,\n }: { app: ApplicationConfig; overrides?: ApplicationOverrideConfig },\n ) {\n // validate\n Application.validate(name, app);\n\n this.name = name;\n this.default = app.default;\n this.routing = app.routing;\n this.development = {\n local: new Host(app.development.local),\n fallback: app.development.fallback\n ? new Host(app.development.fallback)\n : undefined,\n };\n this.production = new Host(app.production);\n this.vercel = app.vercel;\n this.overrides = overrides?.environment\n ? {\n environment: new Host(overrides.environment),\n }\n : undefined;\n }\n\n isDefault(): boolean {\n return this.default;\n }\n\n static validate(name: string, app: ApplicationConfig): void {\n // validate assetPrefix\n if (\n app.routing?.assetPrefix?.startsWith('/') ||\n app.routing?.assetPrefix?.endsWith('/')\n ) {\n throw new MicrofrontendError(\n `Invalid assetPrefix for application \"${name}\". Must not start or end with a slash.`,\n { type: 'zone', subtype: 'invalid_asset_prefix' },\n );\n }\n\n // validate routes\n for (const group of app.routing?.matches ?? []) {\n for (const p of group.paths) {\n if (p === '/') {\n continue;\n }\n if (p.endsWith('/')) {\n throw new MicrofrontendError(\n `Invalid path for application \"${name}\". ${p} must not end with a slash.`,\n { type: 'zone', subtype: 'invalid_path' },\n );\n }\n\n if (!p.startsWith('/')) {\n throw new MicrofrontendError(\n `Invalid path for application \"${name}\". ${p} must start with a slash.`,\n { type: 'zone', subtype: 'invalid_path' },\n );\n }\n }\n }\n }\n\n serialize(): ApplicationConfig {\n if (this.routing === undefined || this.default) {\n return {\n default: true,\n development: {\n local: this.development.local.serialize(),\n fallback: this.development.fallback?.serialize(),\n },\n production: this.production.serialize(),\n vercel: this.vercel,\n };\n }\n\n return {\n default: false,\n routing: this.routing,\n development: {\n local: this.development.local.serialize(),\n fallback: this.development.fallback?.serialize(),\n },\n production: this.production.serialize(),\n vercel: this.vercel,\n };\n }\n}\n","import type { ApplicationConfig, Config, Options } from '../schema';\nimport { MicrofrontendError } from '../errors';\nimport type { OverridesConfig } from '../overrides';\nimport { Overrides } from '../overrides/config';\nimport { Application } from './application';\n\nconst SUPPORTED_VERSIONS = ['1'];\nconst DEFAULT_LOCAL_PROXY_PORT = 3024;\n\n/**\n * A class to manage the microfrontends configuration.\n *\n * This class should not be used directly. Instead, use the `MicrofrontendConfig` or `MicrofrontendConfigEdgeRuntime` classes.\n */\nexport class MicrofrontendConfigCommon {\n config: Config;\n name?: string;\n zones: Record<string, Application> = {};\n version: string;\n overrides?: Overrides;\n options?: Options;\n $schema: string | undefined;\n\n constructor({\n config,\n overrides,\n }: { config: Config; overrides?: OverridesConfig }) {\n if (!SUPPORTED_VERSIONS.includes(config.version)) {\n throw new MicrofrontendError(\n `Unsupported version: ${config.version}. Supported versions are: ${SUPPORTED_VERSIONS.join(\n ', ',\n )}`,\n { type: 'config', subtype: 'unsupported_version' },\n );\n }\n const disableOverrides = config.options?.vercel?.disableOverrides ?? false;\n\n this.overrides =\n overrides && !disableOverrides ? new Overrides(overrides) : undefined;\n\n // create zones\n for (const [zoneName, zoneConfig] of Object.entries(config.applications)) {\n this.zones[zoneName] = new Application(zoneName, {\n app: zoneConfig,\n overrides: !disableOverrides\n ? this.overrides?.config.applications[zoneName]\n : undefined,\n });\n }\n\n this.config = config;\n this.name = config.name;\n this.version = config.version;\n this.options = config.options;\n this.$schema = config.$schema;\n }\n\n isOverridesDisabled(): boolean {\n return this.options?.vercel?.disableOverrides ?? false;\n }\n\n protected static getConfigFromEnv(): string {\n const config = process.env.MFE_CONFIG;\n if (!config) {\n throw new MicrofrontendError(`Missing \"MFE_CONFIG\" in environment.`, {\n type: 'config',\n subtype: 'not_found_in_env',\n });\n }\n return config;\n }\n\n static fromEnv(_: {\n cookies: { name: string; value: string }[];\n }): MicrofrontendConfigCommon | Promise<MicrofrontendConfigCommon> {\n throw new Error('Not implemented');\n }\n\n getConfig(): Config {\n return this.config;\n }\n\n getAllApplications(): Application[] {\n return Object.values(this.zones);\n }\n\n getZone(name: string): Application {\n const zone = this.zones[name];\n if (!zone) {\n throw new MicrofrontendError(\n `Could not find microfrontends configuration for application \"${name}\"`,\n {\n type: 'zone',\n subtype: 'not_found',\n },\n );\n }\n\n return zone;\n }\n\n getApplicationByProjectId(projectId: string): Application | undefined {\n return Object.values(this.zones).find(\n (zone) => zone.vercel?.projectId === projectId,\n );\n }\n\n getDefaultZone(): Application {\n const zone = Object.values(this.zones).find((z) => z.default);\n if (!zone) {\n throw new MicrofrontendError(\n `Could not find default zone in microfrontends configuration`,\n {\n type: 'zone',\n subtype: 'not_found',\n },\n );\n }\n\n return zone;\n }\n\n /**\n * Returns the configured port for the local proxy\n */\n getLocalProxyPort(): number {\n return this.config.options?.localProxy?.port ?? DEFAULT_LOCAL_PROXY_PORT;\n }\n\n /**\n * Serializes the class back to the Schema type.\n *\n * NOTE: This is used when writing the config to disk and must always match the input Schema\n */\n toSchemaJson(): Config {\n const applications: Record<string, ApplicationConfig> = {};\n for (const [name, zone] of Object.entries(this.zones)) {\n applications[name] = zone.serialize();\n }\n\n return {\n $schema: this.$schema,\n name: this.name,\n version: this.version,\n options: this.options,\n applications,\n };\n }\n\n serialize(): { config: Config; overrides?: OverridesConfig } {\n const applications: Record<string, ApplicationConfig> = {};\n for (const [name, zone] of Object.entries(this.zones)) {\n applications[name] = zone.serialize();\n }\n\n return {\n config: {\n name: this.name,\n version: this.version,\n applications,\n options: this.options,\n $schema: this.$schema,\n },\n overrides: this.overrides?.serialize(),\n };\n }\n\n write(_: string): void {\n throw new MicrofrontendError(\n `Writing to file to disk requires using an instance of \"MicrofrontendConfig\".`,\n { type: 'config', subtype: 'unsupported_operation' },\n );\n }\n}\n","/// <reference types=\"@edge-runtime/types\" />\n\nimport type { Application } from '../config/common/application';\n\nfunction debugDomains(zone: string, env: string, domain: string): void {\n if (process.env.MFE_DEBUG === 'true') {\n const indent = ' '.repeat(4);\n const header = 'domains (zone (env) -> domain)';\n const separator = '⎯'.repeat(header.length);\n const line = `${indent} 1. ${zone} (${env}) -> ${domain}`;\n\n // eslint-disable-next-line no-console\n console.log(`${indent}${header}\\n${indent}${separator}\\n${line}\\n`);\n }\n}\n\n/**\n * Returns the Vercel domain for the given application based on the current\n * environment (local, preview, production).\n */\nexport function getDomainForCurrentEnvironment(zone: Application): string {\n if (zone.overrides?.environment) {\n return zone.overrides.environment.toString();\n }\n const zoneName = zone.name;\n if (!process.env.VERCEL_ENV || process.env.VERCEL_ENV === 'development') {\n // TODO(mknichel): Convert this back to the local development domain once\n // there is local development proxy support.\n const domain =\n process.env.NODE_ENV === 'test'\n ? zone.development.local.toString()\n : zone.production.toString();\n debugDomains(zoneName, 'development', domain);\n return domain;\n } else if (process.env.VERCEL_ENV === 'production') {\n const domain = zone.production.toString();\n debugDomains(zoneName, 'production', domain);\n return domain;\n } else if (process.env.VERCEL_ENV === 'preview') {\n const MFE_PREVIEW_DOMAINS = JSON.parse(\n process.env.MFE_PREVIEW_DOMAINS ?? '{}',\n ) as Record<string, string>;\n if (MFE_PREVIEW_DOMAINS[zoneName]) {\n debugDomains(zoneName, 'preview', MFE_PREVIEW_DOMAINS[zoneName]);\n return MFE_PREVIEW_DOMAINS[zoneName];\n }\n\n throw new Error(\n `Could not find preview domain for application \"${zoneName}\"`,\n );\n }\n // TODO(mknichel): Add support in this function for custom environments.\n // Custom Vercel environments may have an arbitrary string for `VERCEL_ENV`.\n debugDomains(zoneName, process.env.VERCEL_ENV, zone.production.toString());\n return zone.production.toString();\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/next/middleware/middleware.ts","../../src/config/edge/microfrontend-config.ts","../../src/config/errors.ts","../../src/routing/url.ts","../../src/config/overrides/config.ts","../../src/config/common/host.ts","../../src/config/common/application.ts","../../src/config/common/microfrontend-config.ts","../../src/routing/get-domain-for-current-environment.ts"],"sourcesContent":["/// <reference types=\"@edge-runtime/types\" />\n\nimport type { NextRequest } from 'next/server';\nimport { NextResponse } from 'next/server';\nimport { pathToRegexp } from 'path-to-regexp';\nimport { MicrofrontendConfigEdge } from '../../config/edge/microfrontend-config';\nimport { getDomainForCurrentEnvironment } from '../../routing/get-domain-for-current-environment';\nimport type { Application } from '../../config/common/application';\nimport type { HostConfig } from '../../config/schema';\nimport type {\n MicrofrontendsMiddleware,\n MicrofrontendsMiddlewareHandler,\n} from './types';\n\ninterface GetHandlerParams {\n application: Application;\n flagFn?: () => Promise<boolean>;\n pattern: RegExp;\n}\n\ninterface InternalRouting {\n routing: HostConfig;\n}\n\nasync function verifyPreviewDomain(\n req: NextRequest,\n rewriteDomain: string,\n): Promise<boolean> {\n const jwtCookie = req.cookies.get('_vercel_jwt')?.value;\n const deploymentProtectionBypassHeader = req.headers.get(\n 'x-vercel-protection-bypass',\n );\n\n // We make a `HEAD` request with `x-vercel-micro-frontends-check: 1` which will get handled in the proxy without reaching the deployment\n const previewResponse = await fetch(rewriteDomain, {\n method: 'HEAD',\n headers: {\n 'x-vercel-micro-frontends-check': '1',\n ...(jwtCookie ? { cookie: `_vercel_jwt=${jwtCookie}` } : {}),\n ...(deploymentProtectionBypassHeader\n ? {\n 'x-vercel-protection-bypass': deploymentProtectionBypassHeader,\n }\n : {}),\n },\n });\n\n const vercelError = previewResponse.headers.get('x-vercel-error');\n return !(\n previewResponse.status === 404 &&\n (vercelError === 'DEPLOYMENT_NOT_FOUND' || vercelError === 'NOT_FOUND')\n );\n}\n\nfunction microfrontendInternalRoutingHandler({\n config,\n}: { config: MicrofrontendConfigEdge }): MicrofrontendsMiddlewareHandler {\n return async (req: NextRequest): Promise<NextResponse> => {\n const payload: Record<string, InternalRouting> = Object.fromEntries(\n await Promise.all(\n config.getAllApplications().map(async (application) => {\n let rewriteDomain = getDomainForCurrentEnvironment(application, {\n ignoreOverride: true,\n });\n const isPreviewDomainAvailable = await verifyPreviewDomain(\n req,\n rewriteDomain,\n );\n\n if (!isPreviewDomainAvailable) {\n rewriteDomain = application.production.toString();\n }\n\n const url = new URL(rewriteDomain);\n return [application.name, { routing: { host: url.host } }] as const;\n }),\n ),\n );\n\n return NextResponse.json(payload);\n };\n}\n\nfunction getHandler({\n application,\n flagFn,\n pattern,\n}: GetHandlerParams): MicrofrontendsMiddlewareHandler {\n return async (req: NextRequest): Promise<NextResponse | undefined> => {\n const pathname = req.nextUrl.pathname;\n const search = req.nextUrl.search;\n\n // If this header is present, it means the proxy handled the routing.\n // Eventually the middleware should use proxy logic for all deployed envs (all except local)\n const proxyRouting = req.headers.get('X-Vercel-Mfe-Proxy') === '1';\n\n let rewriteDomain = proxyRouting\n ? null\n : getDomainForCurrentEnvironment(application);\n const patchedHeaders = new Headers(req.headers);\n\n const responseCallbacks: ((response: NextResponse) => void)[] = [];\n const onRewrite: (response: NextResponse) => NextResponse = (response) => {\n for (const callback of responseCallbacks) {\n callback(response);\n }\n\n return response;\n };\n\n // If this is a preview environment, we check the domain to make sure the project was deployed\n if (process.env.VERCEL_ENV === 'preview' && rewriteDomain) {\n const zoneFallbackCookieName = `__zone_${application.name}_production_fallback`;\n const assetPrefix = application.routing?.assetPrefix;\n\n if (\n assetPrefix &&\n pathname.startsWith(`/${assetPrefix}`) &&\n req.cookies.get(zoneFallbackCookieName)?.value === '1'\n ) {\n // If this is an asset request and we have the cookie, we can safely route to production without fetching\n rewriteDomain = application.production.toString();\n } else {\n try {\n let deploymentFound: boolean;\n if (req.headers.get('x-vercel-skip-deployment-existence-check')) {\n deploymentFound = true;\n } else {\n deploymentFound = await verifyPreviewDomain(req, rewriteDomain);\n }\n\n if (!deploymentFound) {\n // If the deployment is not found, we rewrite to the production domain\n rewriteDomain = application.production.toString();\n\n // We set a 1 minute cookie for the application to avoid checking again for every request\n responseCallbacks.push((response) => {\n response.cookies.set(zoneFallbackCookieName, '1', {\n httpOnly: true,\n sameSite: 'lax',\n secure: true,\n maxAge: 60, // 1 minute\n });\n });\n\n // When routing to a production url, we need to enable the toolbar manually,\n // since production deployments rely on the extension to do that, but the extension can't match the top-level domain\n try {\n const existingCookie = patchedHeaders.get('cookie');\n\n // If the request doesn't contain the toolbar cookie, we add it to support the middleware injection\n if (!existingCookie?.includes('__vercel_toolbar')) {\n patchedHeaders.set(\n 'cookie',\n [`__vercel_toolbar=1`, existingCookie].join('; '),\n );\n\n // We also return a `set-cookie` header to set the cookie locally, to support the Next.js injection which checks the document\n responseCallbacks.push((response) => {\n response.cookies.set('__vercel_toolbar', '1', {\n httpOnly: false,\n sameSite: 'lax',\n secure: true,\n maxAge: 29030400,\n });\n });\n }\n } catch (error) {\n // Do Nothing\n }\n } else if (req.cookies.get(zoneFallbackCookieName)?.value === '1') {\n // If the preview exists and we have the fallback cookie, we make sure to clear the cookie to route subsequent assets to the preview\n responseCallbacks.push((response) => {\n response.cookies.set(zoneFallbackCookieName, '', {\n httpOnly: true,\n sameSite: 'lax',\n secure: true,\n maxAge: 0,\n });\n });\n }\n } catch {\n // Do Nothing\n }\n }\n }\n\n const isFlagEnabled = async (): Promise<boolean> =>\n flagFn ? flagFn() : true;\n\n // If the pattern doesn't match, we don't need to execute the flag\n if (pattern.test(pathname) && (await isFlagEnabled())) {\n if (proxyRouting) {\n const headers = new Headers(req.headers);\n /**\n * This header informs the proxy which zone the route the request to.\n * It will override any provided redirect / rewrite host.\n *\n * If a rewrite / redirect includes this header, the proxy will perform the\n * action, but will also replace the host with corresponding host for the zone.\n */\n headers.set('x-vercel-mfe-zone', application.name);\n return onRewrite(\n NextResponse.next({\n request: {\n headers,\n },\n headers: {\n // temporary, can delete when proxyRouting flag is removed\n 'x-vercel-mfe-middleware-sent-proxy': application.name,\n },\n }),\n );\n }\n return onRewrite(\n NextResponse.rewrite(`${rewriteDomain}${pathname}${search}`, {\n request: {\n headers: patchedHeaders,\n },\n }),\n );\n }\n };\n // If the path does not match the pattern, we don't do anything and let the request continue\n}\n\n/**\n * Returns an array of middleware functions that will handle routing to the\n * right microfrontends for the provided configuration.\n *\n * @param config - The microfrontends configuration object.\n * @param flagValues - An object that maps flag names to functions that return the flag value.\n */\nexport function getMicrofrontendsMiddleware({\n request,\n flagValues,\n}: {\n request: NextRequest;\n flagValues?: Record<string, () => Promise<boolean>>;\n}): MicrofrontendsMiddleware[] {\n const config = MicrofrontendConfigEdge.fromEnv({\n cookies: request.cookies.getAll(),\n });\n const middlewares: MicrofrontendsMiddleware[] = [];\n\n middlewares.push({\n src: '/.well-known/vercel/microfrontend-routing',\n fn: microfrontendInternalRoutingHandler({ config }),\n });\n\n for (const application of config.getAllApplications()) {\n if (application.name === process.env.NEXT_PUBLIC_MFE_CURRENT_APPLICATION) {\n continue;\n }\n if (application.routing) {\n if (\n process.env.VERCEL_ENV === 'preview' &&\n application.routing.assetPrefix\n ) {\n const pattern = pathToRegexp(\n `/${application.routing.assetPrefix}/:path+`,\n );\n middlewares.push({\n src: pattern,\n fn: getHandler({\n application,\n pattern,\n }),\n });\n }\n for (const pathGroup of application.routing.matches) {\n if (process.env.VERCEL_ENV === 'preview' || pathGroup.options?.flag) {\n const flagName = pathGroup.options?.flag;\n // biome-ignore lint/suspicious/noImplicitAnyLet: Ignored using `--suppress`\n let flagFn;\n if (flagName) {\n flagFn = flagValues?.[flagName];\n if (!flagFn) {\n throw new Error(\n `Flag \"${flagName}\" was specified to control routing for path group \"${pathGroup.group}\" in application ${application.name} but not found in provided flag values.`,\n );\n }\n }\n for (const path of pathGroup.paths) {\n const pattern = pathToRegexp(path);\n middlewares.push({\n src: pattern,\n fn: getHandler({\n application,\n flagFn,\n pattern,\n }),\n });\n }\n }\n }\n }\n }\n return middlewares;\n}\n\n/**\n * Executes the middlewares returned by `getMicrofrontendsMiddleware` and\n * returns a `Response` if any of the microfrontends middlewares match or\n * `undefined` if none match. If a `Response` object is returned, the calling\n * code should return that Response from the Next.js middleware in order to\n * stop execution of the middleware and perform the rewrite.\n */\nexport async function runMicrofrontendsMiddleware(\n request: NextRequest,\n flagValues?: Record<string, () => Promise<boolean>>,\n): Promise<Response | undefined> {\n const pathname = request.nextUrl.pathname;\n const middlewares = getMicrofrontendsMiddleware({\n request,\n flagValues,\n });\n\n for (const mware of middlewares) {\n if (\n typeof mware.src === 'string'\n ? pathname === mware.src\n : mware.src.test(pathname)\n ) {\n // eslint-disable-next-line no-await-in-loop\n const response = await mware.fn(request);\n if (response) {\n return response;\n }\n }\n }\n}\n","/// <reference types=\"@edge-runtime/types\" />\n\nimport { parse } from 'jsonc-parser';\nimport { MicrofrontendConfigCommon } from '../common/microfrontend-config';\nimport type { Config } from '../schema';\nimport { Overrides } from '../overrides';\n\n/**\n * Edge Runtime does not support ajv validation, or fs access.\n * This version of the MicrofrontendConfig does not validate the config shape,\n * and requires the config to be set on the environment.\n *\n * It should be used for Next.js middleware which runs in the Edge Runtime.\n */\nexport class MicrofrontendConfigEdge extends MicrofrontendConfigCommon {\n static fromEnv({\n cookies,\n }: {\n cookies: { name: string; value: string }[];\n }): MicrofrontendConfigEdge {\n return new MicrofrontendConfigCommon({\n config: parse(MicrofrontendConfigCommon.getConfigFromEnv()) as Config,\n overrides: Overrides.parseOverrides(cookies),\n });\n }\n}\n","export type MicrofrontendErrorType =\n | 'config'\n | 'packageJson'\n | 'vercelJson'\n | 'zone'\n | 'unknown';\n\nexport type MicrofrontendErrorSubtype =\n | 'not_found'\n | 'not_found_in_env'\n | 'invalid_asset_prefix'\n | 'invalid_main_path'\n | 'does_not_match_schema'\n | 'unable_to_read_file'\n | 'unsupported_validation_env'\n | 'unsupported_version'\n | 'invalid_path'\n | 'invalid_permissions'\n | 'invalid_syntax'\n | 'missing_microfrontend_config_path'\n | 'unsupported_operation';\n\n// A mapping of error types to their subtypes.\ninterface TypeToSubtype {\n zone:\n | 'invalid_asset_prefix'\n | 'invalid_path'\n | 'multiple_package_managers'\n | 'not_found';\n config:\n | 'conflicting_paths'\n | 'does_not_match_schema'\n | 'invalid_main_path'\n | 'invalid_preview_deployment_suffix'\n | 'multiple_default_applications'\n | 'no_default_application'\n | 'not_found_in_env'\n | 'not_found'\n | 'unable_to_read_file'\n | 'invalid_syntax'\n | 'invalid_permissions'\n | 'unsupported_operation'\n | 'unsupported_validation_env'\n | 'unsupported_version';\n packageJson:\n | 'missing_field_name'\n | 'unable_to_read_file'\n | 'invalid_permissions'\n | 'invalid_syntax';\n vercelJson:\n | 'missing_field_microFrontend_config_path'\n | 'unable_to_read_file'\n | 'invalid_permissions'\n | 'invalid_syntax';\n unknown: never;\n}\n\nexport type MicrofrontendErrorSource =\n | '@vercel/microfrontends'\n | '@vercel/microfrontends/next'\n | 'fs'\n | 'ajv';\n\nexport interface MicrofrontendErrorOptions<T extends MicrofrontendErrorType> {\n source?: MicrofrontendErrorSource;\n type?: T;\n subtype?: TypeToSubtype[T];\n}\n\ninterface HandleOptions {\n fileName?: string;\n}\n\nexport class MicrofrontendError<\n T extends MicrofrontendErrorType = 'unknown',\n> extends Error {\n public source: MicrofrontendErrorSource;\n public type: T;\n public subtype?: TypeToSubtype[T];\n\n constructor(message: string, opts?: MicrofrontendErrorOptions<T>) {\n super(message);\n this.name = 'MicrofrontendsError';\n this.source = opts?.source ?? '@vercel/microfrontends';\n this.type = opts?.type ?? ('unknown' as T);\n this.subtype = opts?.subtype;\n Error.captureStackTrace(this, MicrofrontendError);\n }\n\n isKnown(): boolean {\n return this.type !== 'unknown';\n }\n\n isUnknown(): boolean {\n return !this.isKnown();\n }\n\n /**\n * Converts an error to a MicrofrontendsError.\n * @param original - The original error to convert.\n * @returns The converted MicrofrontendsError.\n */\n static convert(\n original: Error,\n opts?: HandleOptions,\n ): MicrofrontendError<MicrofrontendErrorType> {\n if (opts?.fileName) {\n const err = MicrofrontendError.convertFSError(original, opts.fileName);\n if (err) {\n return err;\n }\n }\n\n if (\n original.message.includes(\n 'Code generation from strings disallowed for this context',\n )\n ) {\n return new MicrofrontendError(original.message, {\n type: 'config',\n subtype: 'unsupported_validation_env',\n source: 'ajv',\n });\n }\n\n // unknown catch-all\n return new MicrofrontendError(original.message);\n }\n\n static convertFSError(\n original: Error,\n fileName: string,\n ): MicrofrontendError<MicrofrontendErrorType> | null {\n if (original instanceof Error && 'code' in original) {\n if (original.code === 'ENOENT') {\n return new MicrofrontendError(`Could not find \"${fileName}\"`, {\n type: 'config',\n subtype: 'unable_to_read_file',\n source: 'fs',\n });\n }\n if (original.code === 'EACCES') {\n return new MicrofrontendError(\n `Permission denied while accessing \"${fileName}\"`,\n {\n type: 'config',\n subtype: 'invalid_permissions',\n source: 'fs',\n },\n );\n }\n }\n\n if (original instanceof SyntaxError) {\n return new MicrofrontendError(\n `Failed to parse \"${fileName}\": Invalid JSON format.`,\n {\n type: 'config',\n subtype: 'invalid_syntax',\n source: 'fs',\n },\n );\n }\n\n return null;\n }\n\n /**\n * Handles an unknown error and returns a MicrofrontendsError instance.\n * @param err - The error to handle.\n * @returns A MicrofrontendsError instance.\n */\n static handle(\n err: unknown,\n opts?: HandleOptions,\n ): MicrofrontendError<MicrofrontendErrorType> {\n if (err instanceof MicrofrontendError) {\n return err as MicrofrontendError<MicrofrontendErrorType>;\n }\n\n // handle Error instances\n if (err instanceof Error) {\n return MicrofrontendError.convert(err, opts);\n }\n\n // handle object errors\n if (typeof err === 'object' && err !== null) {\n if ('message' in err && typeof err.message === 'string') {\n return MicrofrontendError.convert(new Error(err.message), opts);\n }\n }\n\n return new MicrofrontendError('An unknown error occurred');\n }\n}\n","// NOTE: This is copied from https://github.com/vercel/api/blob/main/packages/util-func/src/url-safe-string.ts.\n// See https://linear.app/vercel/issue/FDRTN-199/spike-move-preview-domain-generation-logic-into-build-and-deploy\n// for cleaning this up before release.\n\ninterface Options {\n joinString?: string;\n lowercaseOnly?: boolean;\n maxLen?: number;\n regexRemovePattern?: RegExp;\n trimWhitespace?: boolean;\n}\n\n/**\n * This function allows to convert single string to URL-safe tags to use for routing,\n * SEO purposes, etc. It is taken from https://www.npmjs.com/package/url-safe-string\n * and implemented here to be typed and skip the dependency.\n */\nfunction buildUrlSafeString(givenOpts: Options = {}): {\n generate: (...args: string[]) => string;\n} {\n const options = {\n joinString: '-',\n lowercaseOnly: true,\n maxLen: 100,\n regexRemovePattern: /(?:(?!(?:[a-z0-9])).)/gi,\n trimWhitespace: true,\n ...givenOpts,\n };\n\n return {\n generate: (...args: string[]) => {\n const reJoinString = new RegExp(`${options.joinString}+`, 'g');\n\n // biome-ignore lint/suspicious/noImplicitAnyLet: Ignored using `--suppress`\n let tag;\n\n if (args.length === 0) {\n throw new Error('generate method must be passed at least one argument');\n }\n\n // Validate, trim all arguments:\n for (let i = 0; i < args.length; i++) {\n const arg = args[i];\n if (typeof arg !== 'string')\n throw new Error('all supplied arguments must be Strings');\n\n if (options.trimWhitespace) {\n args[i] = arg.trim();\n }\n }\n\n // Join strings and convert whitespace between words to join string\n tag = args.join(options.joinString);\n tag = tag.replace(/\\s/g, options.joinString);\n if (options.lowercaseOnly) tag = tag.toLowerCase();\n // Regex away anything \"unsafe\", but ignore the join string!\n tag = tag.replace(options.regexRemovePattern, (match) => {\n if (match === options.joinString) return match;\n\n return '';\n });\n\n // Truncate in excess of maxLen\n if (tag.length > options.maxLen) tag = tag.substring(0, options.maxLen);\n\n // Remove any duplicates of the join string using this pattern: /<join string>+/g\n tag = tag.replace(reJoinString, options.joinString);\n\n return tag;\n },\n };\n}\n\n/**\n * Export a preconfigured version for convenience.\n */\nexport const urlSafeString = buildUrlSafeString().generate;\n\nexport function makeUrlSafe(name: string): string {\n return urlSafeString(name.replace(/\\//g, '-'))\n .replace(/^-*/g, '')\n .replace(/-*$/g, '');\n}\n","import { makeUrlSafe } from '../../routing/url';\nimport type { MicrofrontendConfig } from '../microfrontend-config';\nimport type { OverridesConfig } from './types';\n\nexport const OVERRIDES_COOKIE_PREFIX = 'vercel-micro-frontends-override';\n\nexport class Overrides {\n config: OverridesConfig;\n\n constructor(config: OverridesConfig) {\n this.config = config;\n }\n\n static overrideEnvCookiePrefix = `${OVERRIDES_COOKIE_PREFIX}:env:`;\n\n static getAppEnvOverrideCookieName(zone: string): string {\n return `${Overrides.overrideEnvCookiePrefix}${zone}`;\n }\n\n static isOverrideCookie(cookie: { name?: string }): boolean {\n return Boolean(cookie.name?.startsWith(OVERRIDES_COOKIE_PREFIX));\n }\n\n static getOverrideFromCookie(cookie: {\n name: string;\n value?: string | null;\n }): { zone: string; host: string } | undefined {\n if (!Overrides.isOverrideCookie(cookie) || !cookie.value) return;\n return {\n zone: cookie.name.replace(Overrides.overrideEnvCookiePrefix, ''),\n host: cookie.value,\n };\n }\n\n static parseOverrides(\n cookies: { name: string; value?: string | null }[],\n ): OverridesConfig {\n const overridesConfig: OverridesConfig = { applications: {} };\n\n cookies.forEach((cookie) => {\n const override = Overrides.getOverrideFromCookie(cookie);\n if (!override) return;\n overridesConfig.applications[override.zone] = {\n environment: { host: override.host },\n };\n });\n\n return overridesConfig;\n }\n\n static validOverrideDomainsForZone(\n microfrontendConfig: MicrofrontendConfig,\n zone: string,\n ): string[] {\n const projectName = microfrontendConfig.getZone(zone).vercel?.projectName;\n if (!projectName) {\n return [microfrontendConfig.getZone(zone).production.host];\n }\n const parsedProjectName = makeUrlSafe(projectName);\n const previewDeploymentSuffix =\n microfrontendConfig.options?.vercel?.previewDeploymentSuffix;\n const teamSlug = microfrontendConfig.options?.vercel?.teamSlug;\n if (!teamSlug && !previewDeploymentSuffix) {\n return [microfrontendConfig.getZone(zone).production.host];\n }\n\n const suffix = previewDeploymentSuffix\n ? `.${previewDeploymentSuffix}`\n : `-${teamSlug}.vercel.app`;\n\n // <project-name>-git-<branch-name>-<scope-slug>.vercel.app\n // <project-name>-git-<branch-name>.<custom-suffix>\n return [\n `${parsedProjectName}-git-([a-zA-Z0-9-]+)${suffix}`,\n microfrontendConfig.getZone(zone).production.host,\n ];\n }\n\n static validateOverrideDomain(\n microfrontendConfig: MicrofrontendConfig,\n zone: string,\n domain: string,\n ): boolean {\n return new RegExp(\n `^${Overrides.validOverrideDomainsForZone(microfrontendConfig, zone).join(\n '|',\n )}$`,\n ).test(domain);\n }\n\n serialize(): OverridesConfig {\n return this.config;\n }\n}\n","import type { HostConfig } from '../schema';\n\ninterface HostDisplayOptions {\n includeDefaultPort?: boolean;\n}\n\nexport class Host {\n protocol: 'http' | 'https';\n host: HostConfig['host'];\n port: number;\n serialized: HostConfig;\n\n constructor({ protocol, host, port }: HostConfig) {\n this.protocol = protocol || 'https';\n this.host = host;\n this.port = Host.getPort({ port, protocol: this.protocol });\n this.serialized = {\n protocol,\n host,\n ...(port ? { port } : undefined),\n };\n }\n\n isLocal(): boolean {\n return this.host === 'localhost' || this.host === '127.0.0.1';\n }\n\n static getPort({\n protocol,\n port,\n }: { protocol: HostConfig['protocol']; port?: HostConfig['port'] }): number {\n if (!port) {\n if (protocol === 'http') {\n return 80;\n }\n return 443;\n }\n\n return port;\n }\n\n isDefaultPort(): boolean {\n return this.port === Host.getPort({ protocol: this.protocol });\n }\n\n toString(opts: HostDisplayOptions = {}): string {\n const url = this.toUrl(opts);\n // strip the trailing slash\n return url.toString().replace(/\\/$/, '');\n }\n\n toUrl(opts: HostDisplayOptions = {}): URL {\n const { includeDefaultPort } = opts;\n const url = `${this.protocol}://${this.host}${this.isDefaultPort() && !includeDefaultPort ? '' : `:${this.port}`}`;\n\n return new URL(url);\n }\n\n serialize(): HostConfig {\n return this.serialized;\n }\n}\n","import type { ApplicationConfig, Routing, Vercel } from '../schema';\nimport type { ApplicationOverrideConfig } from '../overrides';\nimport { MicrofrontendError } from '../errors';\nimport { Host } from './host';\n\nexport class Application {\n default: boolean;\n routing?: Routing;\n name: string;\n development: {\n local: Host;\n fallback?: Host;\n };\n production: Host;\n vercel?: Vercel;\n overrides?: {\n environment?: Host;\n };\n\n constructor(\n name: string,\n {\n app,\n overrides,\n }: { app: ApplicationConfig; overrides?: ApplicationOverrideConfig },\n ) {\n // validate\n Application.validate(name, app);\n\n this.name = name;\n this.default = app.default;\n this.routing = app.routing;\n this.development = {\n local: new Host(app.development.local),\n fallback: app.development.fallback\n ? new Host(app.development.fallback)\n : undefined,\n };\n this.production = new Host(app.production);\n this.vercel = app.vercel;\n this.overrides = overrides?.environment\n ? {\n environment: new Host(overrides.environment),\n }\n : undefined;\n }\n\n isDefault(): boolean {\n return this.default;\n }\n\n static validate(name: string, app: ApplicationConfig): void {\n // validate assetPrefix\n if (\n app.routing?.assetPrefix?.startsWith('/') ||\n app.routing?.assetPrefix?.endsWith('/')\n ) {\n throw new MicrofrontendError(\n `Invalid assetPrefix for application \"${name}\". Must not start or end with a slash.`,\n { type: 'zone', subtype: 'invalid_asset_prefix' },\n );\n }\n\n // validate routes\n for (const group of app.routing?.matches ?? []) {\n for (const p of group.paths) {\n if (p === '/') {\n continue;\n }\n if (p.endsWith('/')) {\n throw new MicrofrontendError(\n `Invalid path for application \"${name}\". ${p} must not end with a slash.`,\n { type: 'zone', subtype: 'invalid_path' },\n );\n }\n\n if (!p.startsWith('/')) {\n throw new MicrofrontendError(\n `Invalid path for application \"${name}\". ${p} must start with a slash.`,\n { type: 'zone', subtype: 'invalid_path' },\n );\n }\n }\n }\n }\n\n serialize(): ApplicationConfig {\n if (this.routing === undefined || this.default) {\n return {\n default: true,\n development: {\n local: this.development.local.serialize(),\n fallback: this.development.fallback?.serialize(),\n },\n production: this.production.serialize(),\n vercel: this.vercel,\n };\n }\n\n return {\n default: false,\n routing: this.routing,\n development: {\n local: this.development.local.serialize(),\n fallback: this.development.fallback?.serialize(),\n },\n production: this.production.serialize(),\n vercel: this.vercel,\n };\n }\n}\n","import type { ApplicationConfig, Config, Options } from '../schema';\nimport { MicrofrontendError } from '../errors';\nimport type { OverridesConfig } from '../overrides';\nimport { Overrides } from '../overrides/config';\nimport { Application } from './application';\n\nconst SUPPORTED_VERSIONS = ['1'];\nconst DEFAULT_LOCAL_PROXY_PORT = 3024;\n\n/**\n * A class to manage the microfrontends configuration.\n *\n * This class should not be used directly. Instead, use the `MicrofrontendConfig` or `MicrofrontendConfigEdgeRuntime` classes.\n */\nexport class MicrofrontendConfigCommon {\n config: Config;\n name?: string;\n zones: Record<string, Application> = {};\n version: string;\n overrides?: Overrides;\n options?: Options;\n $schema: string | undefined;\n\n constructor({\n config,\n overrides,\n }: { config: Config; overrides?: OverridesConfig }) {\n if (!SUPPORTED_VERSIONS.includes(config.version)) {\n throw new MicrofrontendError(\n `Unsupported version: ${config.version}. Supported versions are: ${SUPPORTED_VERSIONS.join(\n ', ',\n )}`,\n { type: 'config', subtype: 'unsupported_version' },\n );\n }\n const disableOverrides = config.options?.vercel?.disableOverrides ?? false;\n\n this.overrides =\n overrides && !disableOverrides ? new Overrides(overrides) : undefined;\n\n // create zones\n for (const [zoneName, zoneConfig] of Object.entries(config.applications)) {\n this.zones[zoneName] = new Application(zoneName, {\n app: zoneConfig,\n overrides: !disableOverrides\n ? this.overrides?.config.applications[zoneName]\n : undefined,\n });\n }\n\n this.config = config;\n this.name = config.name;\n this.version = config.version;\n this.options = config.options;\n this.$schema = config.$schema;\n }\n\n isOverridesDisabled(): boolean {\n return this.options?.vercel?.disableOverrides ?? false;\n }\n\n protected static getConfigFromEnv(): string {\n const config = process.env.MFE_CONFIG;\n if (!config) {\n throw new MicrofrontendError(`Missing \"MFE_CONFIG\" in environment.`, {\n type: 'config',\n subtype: 'not_found_in_env',\n });\n }\n return config;\n }\n\n static fromEnv(_: {\n cookies: { name: string; value: string }[];\n }): MicrofrontendConfigCommon | Promise<MicrofrontendConfigCommon> {\n throw new Error('Not implemented');\n }\n\n getConfig(): Config {\n return this.config;\n }\n\n getAllApplications(): Application[] {\n return Object.values(this.zones);\n }\n\n getZone(name: string): Application {\n const zone = this.zones[name];\n if (!zone) {\n throw new MicrofrontendError(\n `Could not find microfrontends configuration for application \"${name}\"`,\n {\n type: 'zone',\n subtype: 'not_found',\n },\n );\n }\n\n return zone;\n }\n\n getApplicationByProjectId(projectId: string): Application | undefined {\n return Object.values(this.zones).find(\n (zone) => zone.vercel?.projectId === projectId,\n );\n }\n\n getDefaultZone(): Application {\n const zone = Object.values(this.zones).find((z) => z.default);\n if (!zone) {\n throw new MicrofrontendError(\n `Could not find default zone in microfrontends configuration`,\n {\n type: 'zone',\n subtype: 'not_found',\n },\n );\n }\n\n return zone;\n }\n\n /**\n * Returns the configured port for the local proxy\n */\n getLocalProxyPort(): number {\n return this.config.options?.localProxy?.port ?? DEFAULT_LOCAL_PROXY_PORT;\n }\n\n /**\n * Serializes the class back to the Schema type.\n *\n * NOTE: This is used when writing the config to disk and must always match the input Schema\n */\n toSchemaJson(): Config {\n const applications: Record<string, ApplicationConfig> = {};\n for (const [name, zone] of Object.entries(this.zones)) {\n applications[name] = zone.serialize();\n }\n\n return {\n $schema: this.$schema,\n name: this.name,\n version: this.version,\n options: this.options,\n applications,\n };\n }\n\n serialize(): { config: Config; overrides?: OverridesConfig } {\n const applications: Record<string, ApplicationConfig> = {};\n for (const [name, zone] of Object.entries(this.zones)) {\n applications[name] = zone.serialize();\n }\n\n return {\n config: {\n name: this.name,\n version: this.version,\n applications,\n options: this.options,\n $schema: this.$schema,\n },\n overrides: this.overrides?.serialize(),\n };\n }\n\n write(_: string): void {\n throw new MicrofrontendError(\n `Writing to file to disk requires using an instance of \"MicrofrontendConfig\".`,\n { type: 'config', subtype: 'unsupported_operation' },\n );\n }\n}\n","/// <reference types=\"@edge-runtime/types\" />\n\nimport type { Application } from '../config/common/application';\n\nfunction debugDomains(zone: string, env: string, domain: string): void {\n if (process.env.MFE_DEBUG === 'true') {\n const indent = ' '.repeat(4);\n const header = 'domains (zone (env) -> domain)';\n const separator = '⎯'.repeat(header.length);\n const line = `${indent} 1. ${zone} (${env}) -> ${domain}`;\n\n // eslint-disable-next-line no-console\n console.log(`${indent}${header}\\n${indent}${separator}\\n${line}\\n`);\n }\n}\n\n/**\n * Returns the Vercel domain for the given application based on the current\n * environment (local, preview, production).\n */\nexport function getDomainForCurrentEnvironment(\n zone: Application,\n opts: { ignoreOverride?: boolean } = {},\n): string {\n if (!opts.ignoreOverride && zone.overrides?.environment) {\n return zone.overrides.environment.toString();\n }\n const zoneName = zone.name;\n if (!process.env.VERCEL_ENV || process.env.VERCEL_ENV === 'development') {\n // TODO(mknichel): Convert this back to the local development domain once\n // there is local development proxy support.\n const domain =\n process.env.NODE_ENV === 'test'\n ? zone.development.local.toString()\n : zone.production.toString();\n debugDomains(zoneName, 'development', domain);\n return domain;\n } else if (process.env.VERCEL_ENV === 'production') {\n const domain = zone.production.toString();\n debugDomains(zoneName, 'production', domain);\n return domain;\n } else if (process.env.VERCEL_ENV === 'preview') {\n const MFE_PREVIEW_DOMAINS = JSON.parse(\n process.env.MFE_PREVIEW_DOMAINS ?? '{}',\n ) as Record<string, string>;\n if (MFE_PREVIEW_DOMAINS[zoneName]) {\n debugDomains(zoneName, 'preview', MFE_PREVIEW_DOMAINS[zoneName]);\n return MFE_PREVIEW_DOMAINS[zoneName];\n }\n\n throw new Error(\n `Could not find preview domain for application \"${zoneName}\"`,\n );\n }\n // TODO(mknichel): Add support in this function for custom environments.\n // Custom Vercel environments may have an arbitrary string for `VERCEL_ENV`.\n debugDomains(zoneName, process.env.VERCEL_ENV, zone.production.toString());\n return zone.production.toString();\n}\n"],"mappings":";AAGA,SAAS,oBAAoB;AAC7B,SAAS,oBAAoB;;;ACF7B,SAAS,aAAa;;;ACuEf,IAAM,qBAAN,cAEG,MAAM;AAAA,EAKd,YAAY,SAAiB,MAAqC;AAChE,UAAM,OAAO;AACb,SAAK,OAAO;AACZ,SAAK,UAAS,6BAAM,WAAU;AAC9B,SAAK,QAAO,6BAAM,SAAS;AAC3B,SAAK,UAAU,6BAAM;AACrB,UAAM,kBAAkB,MAAM,kBAAkB;AAAA,EAClD;AAAA,EAEA,UAAmB;AACjB,WAAO,KAAK,SAAS;AAAA,EACvB;AAAA,EAEA,YAAqB;AACnB,WAAO,CAAC,KAAK,QAAQ;AAAA,EACvB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,OAAO,QACL,UACA,MAC4C;AAC5C,QAAI,6BAAM,UAAU;AAClB,YAAM,MAAM,mBAAmB,eAAe,UAAU,KAAK,QAAQ;AACrE,UAAI,KAAK;AACP,eAAO;AAAA,MACT;AAAA,IACF;AAEA,QACE,SAAS,QAAQ;AAAA,MACf;AAAA,IACF,GACA;AACA,aAAO,IAAI,mBAAmB,SAAS,SAAS;AAAA,QAC9C,MAAM;AAAA,QACN,SAAS;AAAA,QACT,QAAQ;AAAA,MACV,CAAC;AAAA,IACH;AAGA,WAAO,IAAI,mBAAmB,SAAS,OAAO;AAAA,EAChD;AAAA,EAEA,OAAO,eACL,UACA,UACmD;AACnD,QAAI,oBAAoB,SAAS,UAAU,UAAU;AACnD,UAAI,SAAS,SAAS,UAAU;AAC9B,eAAO,IAAI,mBAAmB,mBAAmB,aAAa;AAAA,UAC5D,MAAM;AAAA,UACN,SAAS;AAAA,UACT,QAAQ;AAAA,QACV,CAAC;AAAA,MACH;AACA,UAAI,SAAS,SAAS,UAAU;AAC9B,eAAO,IAAI;AAAA,UACT,sCAAsC;AAAA,UACtC;AAAA,YACE,MAAM;AAAA,YACN,SAAS;AAAA,YACT,QAAQ;AAAA,UACV;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,QAAI,oBAAoB,aAAa;AACnC,aAAO,IAAI;AAAA,QACT,oBAAoB;AAAA,QACpB;AAAA,UACE,MAAM;AAAA,UACN,SAAS;AAAA,UACT,QAAQ;AAAA,QACV;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,OAAO,OACL,KACA,MAC4C;AAC5C,QAAI,eAAe,oBAAoB;AACrC,aAAO;AAAA,IACT;AAGA,QAAI,eAAe,OAAO;AACxB,aAAO,mBAAmB,QAAQ,KAAK,IAAI;AAAA,IAC7C;AAGA,QAAI,OAAO,QAAQ,YAAY,QAAQ,MAAM;AAC3C,UAAI,aAAa,OAAO,OAAO,IAAI,YAAY,UAAU;AACvD,eAAO,mBAAmB,QAAQ,IAAI,MAAM,IAAI,OAAO,GAAG,IAAI;AAAA,MAChE;AAAA,IACF;AAEA,WAAO,IAAI,mBAAmB,2BAA2B;AAAA,EAC3D;AACF;;;ACjLA,SAAS,mBAAmB,YAAqB,CAAC,GAEhD;AACA,QAAM,UAAU;AAAA,IACd,YAAY;AAAA,IACZ,eAAe;AAAA,IACf,QAAQ;AAAA,IACR,oBAAoB;AAAA,IACpB,gBAAgB;AAAA,IAChB,GAAG;AAAA,EACL;AAEA,SAAO;AAAA,IACL,UAAU,IAAI,SAAmB;AAC/B,YAAM,eAAe,IAAI,OAAO,GAAG,QAAQ,eAAe,GAAG;AAG7D,UAAI;AAEJ,UAAI,KAAK,WAAW,GAAG;AACrB,cAAM,IAAI,MAAM,sDAAsD;AAAA,MACxE;AAGA,eAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AACpC,cAAM,MAAM,KAAK,CAAC;AAClB,YAAI,OAAO,QAAQ;AACjB,gBAAM,IAAI,MAAM,wCAAwC;AAE1D,YAAI,QAAQ,gBAAgB;AAC1B,eAAK,CAAC,IAAI,IAAI,KAAK;AAAA,QACrB;AAAA,MACF;AAGA,YAAM,KAAK,KAAK,QAAQ,UAAU;AAClC,YAAM,IAAI,QAAQ,OAAO,QAAQ,UAAU;AAC3C,UAAI,QAAQ;AAAe,cAAM,IAAI,YAAY;AAEjD,YAAM,IAAI,QAAQ,QAAQ,oBAAoB,CAAC,UAAU;AACvD,YAAI,UAAU,QAAQ;AAAY,iBAAO;AAEzC,eAAO;AAAA,MACT,CAAC;AAGD,UAAI,IAAI,SAAS,QAAQ;AAAQ,cAAM,IAAI,UAAU,GAAG,QAAQ,MAAM;AAGtE,YAAM,IAAI,QAAQ,cAAc,QAAQ,UAAU;AAElD,aAAO;AAAA,IACT;AAAA,EACF;AACF;AAKO,IAAM,gBAAgB,mBAAmB,EAAE;AAE3C,SAAS,YAAY,MAAsB;AAChD,SAAO,cAAc,KAAK,QAAQ,OAAO,GAAG,CAAC,EAC1C,QAAQ,QAAQ,EAAE,EAClB,QAAQ,QAAQ,EAAE;AACvB;;;AC9EO,IAAM,0BAA0B;AAEhC,IAAM,aAAN,MAAgB;AAAA,EAGrB,YAAY,QAAyB;AACnC,SAAK,SAAS;AAAA,EAChB;AAAA,EAIA,OAAO,4BAA4B,MAAsB;AACvD,WAAO,GAAG,WAAU,0BAA0B;AAAA,EAChD;AAAA,EAEA,OAAO,iBAAiB,QAAoC;AAnB9D;AAoBI,WAAO,SAAQ,YAAO,SAAP,mBAAa,WAAW,wBAAwB;AAAA,EACjE;AAAA,EAEA,OAAO,sBAAsB,QAGkB;AAC7C,QAAI,CAAC,WAAU,iBAAiB,MAAM,KAAK,CAAC,OAAO;AAAO;AAC1D,WAAO;AAAA,MACL,MAAM,OAAO,KAAK,QAAQ,WAAU,yBAAyB,EAAE;AAAA,MAC/D,MAAM,OAAO;AAAA,IACf;AAAA,EACF;AAAA,EAEA,OAAO,eACL,SACiB;AACjB,UAAM,kBAAmC,EAAE,cAAc,CAAC,EAAE;AAE5D,YAAQ,QAAQ,CAAC,WAAW;AAC1B,YAAM,WAAW,WAAU,sBAAsB,MAAM;AACvD,UAAI,CAAC;AAAU;AACf,sBAAgB,aAAa,SAAS,IAAI,IAAI;AAAA,QAC5C,aAAa,EAAE,MAAM,SAAS,KAAK;AAAA,MACrC;AAAA,IACF,CAAC;AAED,WAAO;AAAA,EACT;AAAA,EAEA,OAAO,4BACL,qBACA,MACU;AArDd;AAsDI,UAAM,eAAc,yBAAoB,QAAQ,IAAI,EAAE,WAAlC,mBAA0C;AAC9D,QAAI,CAAC,aAAa;AAChB,aAAO,CAAC,oBAAoB,QAAQ,IAAI,EAAE,WAAW,IAAI;AAAA,IAC3D;AACA,UAAM,oBAAoB,YAAY,WAAW;AACjD,UAAM,2BACJ,+BAAoB,YAApB,mBAA6B,WAA7B,mBAAqC;AACvC,UAAM,YAAW,+BAAoB,YAApB,mBAA6B,WAA7B,mBAAqC;AACtD,QAAI,CAAC,YAAY,CAAC,yBAAyB;AACzC,aAAO,CAAC,oBAAoB,QAAQ,IAAI,EAAE,WAAW,IAAI;AAAA,IAC3D;AAEA,UAAM,SAAS,0BACX,IAAI,4BACJ,IAAI;AAIR,WAAO;AAAA,MACL,GAAG,wCAAwC;AAAA,MAC3C,oBAAoB,QAAQ,IAAI,EAAE,WAAW;AAAA,IAC/C;AAAA,EACF;AAAA,EAEA,OAAO,uBACL,qBACA,MACA,QACS;AACT,WAAO,IAAI;AAAA,MACT,IAAI,WAAU,4BAA4B,qBAAqB,IAAI,EAAE;AAAA,QACnE;AAAA,MACF;AAAA,IACF,EAAE,KAAK,MAAM;AAAA,EACf;AAAA,EAEA,YAA6B;AAC3B,WAAO,KAAK;AAAA,EACd;AACF;AAvFO,IAAM,YAAN;AAAM,UAOJ,0BAA0B,GAAG;;;ACP/B,IAAM,OAAN,MAAW;AAAA,EAMhB,YAAY,EAAE,UAAU,MAAM,KAAK,GAAe;AAChD,SAAK,WAAW,YAAY;AAC5B,SAAK,OAAO;AACZ,SAAK,OAAO,KAAK,QAAQ,EAAE,MAAM,UAAU,KAAK,SAAS,CAAC;AAC1D,SAAK,aAAa;AAAA,MAChB;AAAA,MACA;AAAA,MACA,GAAI,OAAO,EAAE,KAAK,IAAI;AAAA,IACxB;AAAA,EACF;AAAA,EAEA,UAAmB;AACjB,WAAO,KAAK,SAAS,eAAe,KAAK,SAAS;AAAA,EACpD;AAAA,EAEA,OAAO,QAAQ;AAAA,IACb;AAAA,IACA;AAAA,EACF,GAA4E;AAC1E,QAAI,CAAC,MAAM;AACT,UAAI,aAAa,QAAQ;AACvB,eAAO;AAAA,MACT;AACA,aAAO;AAAA,IACT;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,gBAAyB;AACvB,WAAO,KAAK,SAAS,KAAK,QAAQ,EAAE,UAAU,KAAK,SAAS,CAAC;AAAA,EAC/D;AAAA,EAEA,SAAS,OAA2B,CAAC,GAAW;AAC9C,UAAM,MAAM,KAAK,MAAM,IAAI;AAE3B,WAAO,IAAI,SAAS,EAAE,QAAQ,OAAO,EAAE;AAAA,EACzC;AAAA,EAEA,MAAM,OAA2B,CAAC,GAAQ;AACxC,UAAM,EAAE,mBAAmB,IAAI;AAC/B,UAAM,MAAM,GAAG,KAAK,cAAc,KAAK,OAAO,KAAK,cAAc,KAAK,CAAC,qBAAqB,KAAK,IAAI,KAAK;AAE1G,WAAO,IAAI,IAAI,GAAG;AAAA,EACpB;AAAA,EAEA,YAAwB;AACtB,WAAO,KAAK;AAAA,EACd;AACF;;;ACxDO,IAAM,cAAN,MAAkB;AAAA,EAcvB,YACE,MACA;AAAA,IACE;AAAA,IACA;AAAA,EACF,GACA;AAEA,gBAAY,SAAS,MAAM,GAAG;AAE9B,SAAK,OAAO;AACZ,SAAK,UAAU,IAAI;AACnB,SAAK,UAAU,IAAI;AACnB,SAAK,cAAc;AAAA,MACjB,OAAO,IAAI,KAAK,IAAI,YAAY,KAAK;AAAA,MACrC,UAAU,IAAI,YAAY,WACtB,IAAI,KAAK,IAAI,YAAY,QAAQ,IACjC;AAAA,IACN;AACA,SAAK,aAAa,IAAI,KAAK,IAAI,UAAU;AACzC,SAAK,SAAS,IAAI;AAClB,SAAK,aAAY,uCAAW,eACxB;AAAA,MACE,aAAa,IAAI,KAAK,UAAU,WAAW;AAAA,IAC7C,IACA;AAAA,EACN;AAAA,EAEA,YAAqB;AACnB,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,OAAO,SAAS,MAAc,KAA8B;AAnD9D;AAqDI,UACE,eAAI,YAAJ,mBAAa,gBAAb,mBAA0B,WAAW,WACrC,eAAI,YAAJ,mBAAa,gBAAb,mBAA0B,SAAS,OACnC;AACA,YAAM,IAAI;AAAA,QACR,wCAAwC;AAAA,QACxC,EAAE,MAAM,QAAQ,SAAS,uBAAuB;AAAA,MAClD;AAAA,IACF;AAGA,eAAW,WAAS,SAAI,YAAJ,mBAAa,YAAW,CAAC,GAAG;AAC9C,iBAAW,KAAK,MAAM,OAAO;AAC3B,YAAI,MAAM,KAAK;AACb;AAAA,QACF;AACA,YAAI,EAAE,SAAS,GAAG,GAAG;AACnB,gBAAM,IAAI;AAAA,YACR,iCAAiC,UAAU;AAAA,YAC3C,EAAE,MAAM,QAAQ,SAAS,eAAe;AAAA,UAC1C;AAAA,QACF;AAEA,YAAI,CAAC,EAAE,WAAW,GAAG,GAAG;AACtB,gBAAM,IAAI;AAAA,YACR,iCAAiC,UAAU;AAAA,YAC3C,EAAE,MAAM,QAAQ,SAAS,eAAe;AAAA,UAC1C;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EAEA,YAA+B;AAtFjC;AAuFI,QAAI,KAAK,YAAY,UAAa,KAAK,SAAS;AAC9C,aAAO;AAAA,QACL,SAAS;AAAA,QACT,aAAa;AAAA,UACX,OAAO,KAAK,YAAY,MAAM,UAAU;AAAA,UACxC,WAAU,UAAK,YAAY,aAAjB,mBAA2B;AAAA,QACvC;AAAA,QACA,YAAY,KAAK,WAAW,UAAU;AAAA,QACtC,QAAQ,KAAK;AAAA,MACf;AAAA,IACF;AAEA,WAAO;AAAA,MACL,SAAS;AAAA,MACT,SAAS,KAAK;AAAA,MACd,aAAa;AAAA,QACX,OAAO,KAAK,YAAY,MAAM,UAAU;AAAA,QACxC,WAAU,UAAK,YAAY,aAAjB,mBAA2B;AAAA,MACvC;AAAA,MACA,YAAY,KAAK,WAAW,UAAU;AAAA,MACtC,QAAQ,KAAK;AAAA,IACf;AAAA,EACF;AACF;;;ACxGA,IAAM,qBAAqB,CAAC,GAAG;AAC/B,IAAM,2BAA2B;AAO1B,IAAM,4BAAN,MAAgC;AAAA,EASrC,YAAY;AAAA,IACV;AAAA,IACA;AAAA,EACF,GAAoD;AATpD,iBAAqC,CAAC;AAjBxC;AA2BI,QAAI,CAAC,mBAAmB,SAAS,OAAO,OAAO,GAAG;AAChD,YAAM,IAAI;AAAA,QACR,wBAAwB,OAAO,oCAAoC,mBAAmB;AAAA,UACpF;AAAA,QACF;AAAA,QACA,EAAE,MAAM,UAAU,SAAS,sBAAsB;AAAA,MACnD;AAAA,IACF;AACA,UAAM,qBAAmB,kBAAO,YAAP,mBAAgB,WAAhB,mBAAwB,qBAAoB;AAErE,SAAK,YACH,aAAa,CAAC,mBAAmB,IAAI,UAAU,SAAS,IAAI;AAG9D,eAAW,CAAC,UAAU,UAAU,KAAK,OAAO,QAAQ,OAAO,YAAY,GAAG;AACxE,WAAK,MAAM,QAAQ,IAAI,IAAI,YAAY,UAAU;AAAA,QAC/C,KAAK;AAAA,QACL,WAAW,CAAC,oBACR,UAAK,cAAL,mBAAgB,OAAO,aAAa,YACpC;AAAA,MACN,CAAC;AAAA,IACH;AAEA,SAAK,SAAS;AACd,SAAK,OAAO,OAAO;AACnB,SAAK,UAAU,OAAO;AACtB,SAAK,UAAU,OAAO;AACtB,SAAK,UAAU,OAAO;AAAA,EACxB;AAAA,EAEA,sBAA+B;AAzDjC;AA0DI,aAAO,gBAAK,YAAL,mBAAc,WAAd,mBAAsB,qBAAoB;AAAA,EACnD;AAAA,EAEA,OAAiB,mBAA2B;AAC1C,UAAM,SAAS,QAAQ,IAAI;AAC3B,QAAI,CAAC,QAAQ;AACX,YAAM,IAAI,mBAAmB,wCAAwC;AAAA,QACnE,MAAM;AAAA,QACN,SAAS;AAAA,MACX,CAAC;AAAA,IACH;AACA,WAAO;AAAA,EACT;AAAA,EAEA,OAAO,QAAQ,GAEoD;AACjE,UAAM,IAAI,MAAM,iBAAiB;AAAA,EACnC;AAAA,EAEA,YAAoB;AAClB,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,qBAAoC;AAClC,WAAO,OAAO,OAAO,KAAK,KAAK;AAAA,EACjC;AAAA,EAEA,QAAQ,MAA2B;AACjC,UAAM,OAAO,KAAK,MAAM,IAAI;AAC5B,QAAI,CAAC,MAAM;AACT,YAAM,IAAI;AAAA,QACR,gEAAgE;AAAA,QAChE;AAAA,UACE,MAAM;AAAA,UACN,SAAS;AAAA,QACX;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,0BAA0B,WAA4C;AACpE,WAAO,OAAO,OAAO,KAAK,KAAK,EAAE;AAAA,MAC/B,CAAC,SAAM;AAvGb;AAuGgB,2BAAK,WAAL,mBAAa,eAAc;AAAA;AAAA,IACvC;AAAA,EACF;AAAA,EAEA,iBAA8B;AAC5B,UAAM,OAAO,OAAO,OAAO,KAAK,KAAK,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO;AAC5D,QAAI,CAAC,MAAM;AACT,YAAM,IAAI;AAAA,QACR;AAAA,QACA;AAAA,UACE,MAAM;AAAA,UACN,SAAS;AAAA,QACX;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,oBAA4B;AA7H9B;AA8HI,aAAO,gBAAK,OAAO,YAAZ,mBAAqB,eAArB,mBAAiC,SAAQ;AAAA,EAClD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,eAAuB;AACrB,UAAM,eAAkD,CAAC;AACzD,eAAW,CAAC,MAAM,IAAI,KAAK,OAAO,QAAQ,KAAK,KAAK,GAAG;AACrD,mBAAa,IAAI,IAAI,KAAK,UAAU;AAAA,IACtC;AAEA,WAAO;AAAA,MACL,SAAS,KAAK;AAAA,MACd,MAAM,KAAK;AAAA,MACX,SAAS,KAAK;AAAA,MACd,SAAS,KAAK;AAAA,MACd;AAAA,IACF;AAAA,EACF;AAAA,EAEA,YAA6D;AArJ/D;AAsJI,UAAM,eAAkD,CAAC;AACzD,eAAW,CAAC,MAAM,IAAI,KAAK,OAAO,QAAQ,KAAK,KAAK,GAAG;AACrD,mBAAa,IAAI,IAAI,KAAK,UAAU;AAAA,IACtC;AAEA,WAAO;AAAA,MACL,QAAQ;AAAA,QACN,MAAM,KAAK;AAAA,QACX,SAAS,KAAK;AAAA,QACd;AAAA,QACA,SAAS,KAAK;AAAA,QACd,SAAS,KAAK;AAAA,MAChB;AAAA,MACA,YAAW,UAAK,cAAL,mBAAgB;AAAA,IAC7B;AAAA,EACF;AAAA,EAEA,MAAM,GAAiB;AACrB,UAAM,IAAI;AAAA,MACR;AAAA,MACA,EAAE,MAAM,UAAU,SAAS,wBAAwB;AAAA,IACrD;AAAA,EACF;AACF;;;AN/JO,IAAM,0BAAN,cAAsC,0BAA0B;AAAA,EACrE,OAAO,QAAQ;AAAA,IACb;AAAA,EACF,GAE4B;AAC1B,WAAO,IAAI,0BAA0B;AAAA,MACnC,QAAQ,MAAM,0BAA0B,iBAAiB,CAAC;AAAA,MAC1D,WAAW,UAAU,eAAe,OAAO;AAAA,IAC7C,CAAC;AAAA,EACH;AACF;;;AOrBA,SAAS,aAAa,MAAc,KAAa,QAAsB;AACrE,MAAI,QAAQ,IAAI,cAAc,QAAQ;AACpC,UAAM,SAAS,IAAI,OAAO,CAAC;AAC3B,UAAM,SAAS;AACf,UAAM,YAAY,SAAI,OAAO,OAAO,MAAM;AAC1C,UAAM,OAAO,GAAG,aAAa,SAAS,WAAW;AAGjD,YAAQ,IAAI,GAAG,SAAS;AAAA,EAAW,SAAS;AAAA,EAAc;AAAA,CAAQ;AAAA,EACpE;AACF;AAMO,SAAS,+BACd,MACA,OAAqC,CAAC,GAC9B;AAvBV;AAwBE,MAAI,CAAC,KAAK,oBAAkB,UAAK,cAAL,mBAAgB,cAAa;AACvD,WAAO,KAAK,UAAU,YAAY,SAAS;AAAA,EAC7C;AACA,QAAM,WAAW,KAAK;AACtB,MAAI,CAAC,QAAQ,IAAI,cAAc,QAAQ,IAAI,eAAe,eAAe;AAGvE,UAAM,SACJ,QAAQ,IAAI,aAAa,SACrB,KAAK,YAAY,MAAM,SAAS,IAChC,KAAK,WAAW,SAAS;AAC/B,iBAAa,UAAU,eAAe,MAAM;AAC5C,WAAO;AAAA,EACT,WAAW,QAAQ,IAAI,eAAe,cAAc;AAClD,UAAM,SAAS,KAAK,WAAW,SAAS;AACxC,iBAAa,UAAU,cAAc,MAAM;AAC3C,WAAO;AAAA,EACT,WAAW,QAAQ,IAAI,eAAe,WAAW;AAC/C,UAAM,sBAAsB,KAAK;AAAA,MAC/B,QAAQ,IAAI,uBAAuB;AAAA,IACrC;AACA,QAAI,oBAAoB,QAAQ,GAAG;AACjC,mBAAa,UAAU,WAAW,oBAAoB,QAAQ,CAAC;AAC/D,aAAO,oBAAoB,QAAQ;AAAA,IACrC;AAEA,UAAM,IAAI;AAAA,MACR,kDAAkD;AAAA,IACpD;AAAA,EACF;AAGA,eAAa,UAAU,QAAQ,IAAI,YAAY,KAAK,WAAW,SAAS,CAAC;AACzE,SAAO,KAAK,WAAW,SAAS;AAClC;;;ARlCA,eAAe,oBACb,KACA,eACkB;AA3BpB;AA4BE,QAAM,aAAY,SAAI,QAAQ,IAAI,aAAa,MAA7B,mBAAgC;AAClD,QAAM,mCAAmC,IAAI,QAAQ;AAAA,IACnD;AAAA,EACF;AAGA,QAAM,kBAAkB,MAAM,MAAM,eAAe;AAAA,IACjD,QAAQ;AAAA,IACR,SAAS;AAAA,MACP,kCAAkC;AAAA,MAClC,GAAI,YAAY,EAAE,QAAQ,eAAe,YAAY,IAAI,CAAC;AAAA,MAC1D,GAAI,mCACA;AAAA,QACE,8BAA8B;AAAA,MAChC,IACA,CAAC;AAAA,IACP;AAAA,EACF,CAAC;AAED,QAAM,cAAc,gBAAgB,QAAQ,IAAI,gBAAgB;AAChE,SAAO,EACL,gBAAgB,WAAW,QAC1B,gBAAgB,0BAA0B,gBAAgB;AAE/D;AAEA,SAAS,oCAAoC;AAAA,EAC3C;AACF,GAAyE;AACvE,SAAO,OAAO,QAA4C;AACxD,UAAM,UAA2C,OAAO;AAAA,MACtD,MAAM,QAAQ;AAAA,QACZ,OAAO,mBAAmB,EAAE,IAAI,OAAO,gBAAgB;AACrD,cAAI,gBAAgB,+BAA+B,aAAa;AAAA,YAC9D,gBAAgB;AAAA,UAClB,CAAC;AACD,gBAAM,2BAA2B,MAAM;AAAA,YACrC;AAAA,YACA;AAAA,UACF;AAEA,cAAI,CAAC,0BAA0B;AAC7B,4BAAgB,YAAY,WAAW,SAAS;AAAA,UAClD;AAEA,gBAAM,MAAM,IAAI,IAAI,aAAa;AACjC,iBAAO,CAAC,YAAY,MAAM,EAAE,SAAS,EAAE,MAAM,IAAI,KAAK,EAAE,CAAC;AAAA,QAC3D,CAAC;AAAA,MACH;AAAA,IACF;AAEA,WAAO,aAAa,KAAK,OAAO;AAAA,EAClC;AACF;AAEA,SAAS,WAAW;AAAA,EAClB;AAAA,EACA;AAAA,EACA;AACF,GAAsD;AACpD,SAAO,OAAO,QAAwD;AAxFxE;AAyFI,UAAM,WAAW,IAAI,QAAQ;AAC7B,UAAM,SAAS,IAAI,QAAQ;AAI3B,UAAM,eAAe,IAAI,QAAQ,IAAI,oBAAoB,MAAM;AAE/D,QAAI,gBAAgB,eAChB,OACA,+BAA+B,WAAW;AAC9C,UAAM,iBAAiB,IAAI,QAAQ,IAAI,OAAO;AAE9C,UAAM,oBAA0D,CAAC;AACjE,UAAM,YAAsD,CAAC,aAAa;AACxE,iBAAW,YAAY,mBAAmB;AACxC,iBAAS,QAAQ;AAAA,MACnB;AAEA,aAAO;AAAA,IACT;AAGA,QAAI,QAAQ,IAAI,eAAe,aAAa,eAAe;AACzD,YAAM,yBAAyB,UAAU,YAAY;AACrD,YAAM,eAAc,iBAAY,YAAZ,mBAAqB;AAEzC,UACE,eACA,SAAS,WAAW,IAAI,aAAa,OACrC,SAAI,QAAQ,IAAI,sBAAsB,MAAtC,mBAAyC,WAAU,KACnD;AAEA,wBAAgB,YAAY,WAAW,SAAS;AAAA,MAClD,OAAO;AACL,YAAI;AACF,cAAI;AACJ,cAAI,IAAI,QAAQ,IAAI,0CAA0C,GAAG;AAC/D,8BAAkB;AAAA,UACpB,OAAO;AACL,8BAAkB,MAAM,oBAAoB,KAAK,aAAa;AAAA,UAChE;AAEA,cAAI,CAAC,iBAAiB;AAEpB,4BAAgB,YAAY,WAAW,SAAS;AAGhD,8BAAkB,KAAK,CAAC,aAAa;AACnC,uBAAS,QAAQ,IAAI,wBAAwB,KAAK;AAAA,gBAChD,UAAU;AAAA,gBACV,UAAU;AAAA,gBACV,QAAQ;AAAA,gBACR,QAAQ;AAAA;AAAA,cACV,CAAC;AAAA,YACH,CAAC;AAID,gBAAI;AACF,oBAAM,iBAAiB,eAAe,IAAI,QAAQ;AAGlD,kBAAI,EAAC,iDAAgB,SAAS,sBAAqB;AACjD,+BAAe;AAAA,kBACb;AAAA,kBACA,CAAC,sBAAsB,cAAc,EAAE,KAAK,IAAI;AAAA,gBAClD;AAGA,kCAAkB,KAAK,CAAC,aAAa;AACnC,2BAAS,QAAQ,IAAI,oBAAoB,KAAK;AAAA,oBAC5C,UAAU;AAAA,oBACV,UAAU;AAAA,oBACV,QAAQ;AAAA,oBACR,QAAQ;AAAA,kBACV,CAAC;AAAA,gBACH,CAAC;AAAA,cACH;AAAA,YACF,SAAS,OAAP;AAAA,YAEF;AAAA,UACF,aAAW,SAAI,QAAQ,IAAI,sBAAsB,MAAtC,mBAAyC,WAAU,KAAK;AAEjE,8BAAkB,KAAK,CAAC,aAAa;AACnC,uBAAS,QAAQ,IAAI,wBAAwB,IAAI;AAAA,gBAC/C,UAAU;AAAA,gBACV,UAAU;AAAA,gBACV,QAAQ;AAAA,gBACR,QAAQ;AAAA,cACV,CAAC;AAAA,YACH,CAAC;AAAA,UACH;AAAA,QACF,QAAE;AAAA,QAEF;AAAA,MACF;AAAA,IACF;AAEA,UAAM,gBAAgB,YACpB,SAAS,OAAO,IAAI;AAGtB,QAAI,QAAQ,KAAK,QAAQ,KAAM,MAAM,cAAc,GAAI;AACrD,UAAI,cAAc;AAChB,cAAM,UAAU,IAAI,QAAQ,IAAI,OAAO;AAQvC,gBAAQ,IAAI,qBAAqB,YAAY,IAAI;AACjD,eAAO;AAAA,UACL,aAAa,KAAK;AAAA,YAChB,SAAS;AAAA,cACP;AAAA,YACF;AAAA,YACA,SAAS;AAAA;AAAA,cAEP,sCAAsC,YAAY;AAAA,YACpD;AAAA,UACF,CAAC;AAAA,QACH;AAAA,MACF;AACA,aAAO;AAAA,QACL,aAAa,QAAQ,GAAG,gBAAgB,WAAW,UAAU;AAAA,UAC3D,SAAS;AAAA,YACP,SAAS;AAAA,UACX;AAAA,QACF,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AAEF;AASO,SAAS,4BAA4B;AAAA,EAC1C;AAAA,EACA;AACF,GAG+B;AA/O/B;AAgPE,QAAM,SAAS,wBAAwB,QAAQ;AAAA,IAC7C,SAAS,QAAQ,QAAQ,OAAO;AAAA,EAClC,CAAC;AACD,QAAM,cAA0C,CAAC;AAEjD,cAAY,KAAK;AAAA,IACf,KAAK;AAAA,IACL,IAAI,oCAAoC,EAAE,OAAO,CAAC;AAAA,EACpD,CAAC;AAED,aAAW,eAAe,OAAO,mBAAmB,GAAG;AACrD,QAAI,YAAY,SAAS,QAAQ,IAAI,qCAAqC;AACxE;AAAA,IACF;AACA,QAAI,YAAY,SAAS;AACvB,UACE,QAAQ,IAAI,eAAe,aAC3B,YAAY,QAAQ,aACpB;AACA,cAAM,UAAU;AAAA,UACd,IAAI,YAAY,QAAQ;AAAA,QAC1B;AACA,oBAAY,KAAK;AAAA,UACf,KAAK;AAAA,UACL,IAAI,WAAW;AAAA,YACb;AAAA,YACA;AAAA,UACF,CAAC;AAAA,QACH,CAAC;AAAA,MACH;AACA,iBAAW,aAAa,YAAY,QAAQ,SAAS;AACnD,YAAI,QAAQ,IAAI,eAAe,eAAa,eAAU,YAAV,mBAAmB,OAAM;AACnE,gBAAM,YAAW,eAAU,YAAV,mBAAmB;AAEpC,cAAI;AACJ,cAAI,UAAU;AACZ,qBAAS,yCAAa;AACtB,gBAAI,CAAC,QAAQ;AACX,oBAAM,IAAI;AAAA,gBACR,SAAS,8DAA8D,UAAU,yBAAyB,YAAY;AAAA,cACxH;AAAA,YACF;AAAA,UACF;AACA,qBAAW,QAAQ,UAAU,OAAO;AAClC,kBAAM,UAAU,aAAa,IAAI;AACjC,wBAAY,KAAK;AAAA,cACf,KAAK;AAAA,cACL,IAAI,WAAW;AAAA,gBACb;AAAA,gBACA;AAAA,gBACA;AAAA,cACF,CAAC;AAAA,YACH,CAAC;AAAA,UACH;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AASA,eAAsB,4BACpB,SACA,YAC+B;AAC/B,QAAM,WAAW,QAAQ,QAAQ;AACjC,QAAM,cAAc,4BAA4B;AAAA,IAC9C;AAAA,IACA;AAAA,EACF,CAAC;AAED,aAAW,SAAS,aAAa;AAC/B,QACE,OAAO,MAAM,QAAQ,WACjB,aAAa,MAAM,MACnB,MAAM,IAAI,KAAK,QAAQ,GAC3B;AAEA,YAAM,WAAW,MAAM,MAAM,GAAG,OAAO;AACvC,UAAI,UAAU;AACZ,eAAO;AAAA,MACT;AAAA,IACF;AAAA,EACF;AACF;","names":[]}
@@ -508,6 +508,9 @@ var DefaultApplication = class extends Application {
508
508
  this.default = true;
509
509
  this.production = new Host(app.production);
510
510
  }
511
+ getAssetPrefix() {
512
+ return "";
513
+ }
511
514
  };
512
515
  var ChildApplication = class extends Application {
513
516
  constructor(name, {