import { isNothing, unwrapOptional as unwrap } from "@jet/environment/types/optional"; import { FlowAction } from "../../api/models"; import { generateRoutes } from "../util/generate-routes"; import { updateWebNavigation } from "./inject-web-navigation"; /** * Determine if the two {@linkcode LandingPageIntent} arguments are equivalent */ export function landingPageIntentsAreEquivalent(activeIntent, navLinkIntent) { if (isNothing(activeIntent) || isNothing(navLinkIntent)) { return false; } for (const key of ["$kind", "storefront", "language"]) { if (activeIntent[key] !== navLinkIntent[key]) { return false; } } return true; } /** * Dynamically create an {@linkcode IntentController} for a platform "landing page" * * A "landing page" is a vanity URL within a specific platform that loads some other * page under-the-hood; the "canonical URL" for the "landing page" should reflect this * vanity URL, rather than the real canonical URL for the underlying Media API entity. * * @param url the vanity URL for the landing page * @param intentFactory a function that produces the underlying `Intent` for the data backing the landing page * @param prepareAction a function that can be used to provide additional configuration of the `FlowAction` for a landing page */ export function defineLandingPageController(url, intentFactory, prepareAction) { const intentKind = `LandingPage_${url.substring(1)}_Intent`; const { routes, makeCanonicalUrl } = generateRoutes((locale) => ({ ...locale, $kind: intentKind, }), url, [], { exclusions: [ { query: ["term"], }, ], }); return { $intentKind: intentKind, routes, async perform(landingPageIntent, objectGraph) { var _a; const pageIntent = intentFactory({ storefront: landingPageIntent.storefront, language: landingPageIntent.language, }); const viewModel = await objectGraph.dispatcher.dispatch(pageIntent, objectGraph); if (viewModel) { // Override the default canonical URL to use the vanity URL instead; this ensures // that the navigation mechanics of the "web" client respect the vanity URL, which the // Media API would not know about when providing it's own value for this property // @ts-expect-error TypeScript can't know that `landingPageIntent` satisfies the requirements of // `makeCanonicalUrl`, but this will be safe at runtime because all we actually require // from the intent is the locale information viewModel.canonicalURL = makeCanonicalUrl(objectGraph, landingPageIntent); (_a = objectGraph.seo) === null || _a === void 0 ? void 0 : _a.updateCanonicalURL(viewModel, viewModel.canonicalURL); // If the web navigation has already been injected, the active state of the "tabs" will be incorrect // since non-"landing pages" never have display active landing page links. We need to update the // navigation shelf, if it exists, based on the `landingPageIntent` updateWebNavigation(objectGraph, viewModel, unwrap(pageIntent.platform), landingPageIntent); } return viewModel; }, buildIntent(locale) { return { ...locale, $kind: intentKind, }; }, buildAction(locale, objectGraph) { const intent = this.buildIntent(locale); return this.actionFor(intent, objectGraph, {}); }, actionFor(landingPageIntent, objectGraph) { const action = new FlowAction("page"); action.destination = landingPageIntent; // @ts-expect-error TypeScript can't know that `landingPageIntent` satisfies the requirements of // `makeCanonicalUrl`, but this will be safe at runtime because all we actually require // from the intent is the locale information action.pageUrl = makeCanonicalUrl(objectGraph, landingPageIntent); prepareAction === null || prepareAction === void 0 ? void 0 : prepareAction(objectGraph, action); return action; }, }; } /** * Dynamically create an {@linkcode IntentController} that redirects from the platform root * to the default landing page * * @param url the URL for the platform to redirect for * @param intentFactory a function that produces the `Intent` for the `LandingPageController` that should be delegated to */ export function definePlatformRootRedirectController(url, intentFactory) { const intentKind = `PlatformRootRedirect_${url.substring(1)}_Intent`; const { routes } = generateRoutes((locale) => ({ ...locale, $kind: intentKind, }), url); return { $intentKind: intentKind, routes, async perform(landingPageIntent, objectGraph) { const pageIntent = intentFactory({ storefront: landingPageIntent.storefront, language: landingPageIntent.language, }); return await objectGraph.dispatcher.dispatch(pageIntent, objectGraph); }, }; } /** * Dynamically create an {@linkcode IntentController} that redirects from the root * to the default landing page * * @param intentFactory a function that produces the `Intent` for the `LandingPageController` that should be delegated to */ export function defineRootRedirectController(intentFactory) { const intentKind = `RootRedirect_Intent`; const { routes } = generateRoutes((locale) => ({ ...locale, $kind: intentKind, }), "/"); return { $intentKind: intentKind, routes, async perform(landingPageIntent, objectGraph) { const pageIntent = intentFactory({ storefront: landingPageIntent.storefront, language: landingPageIntent.language, }); return await objectGraph.dispatcher.dispatch(pageIntent, objectGraph); }, }; } //# sourceMappingURL=platform-landing-page-utils.js.map