summaryrefslogtreecommitdiff
path: root/node_modules/@jet-app/app-store/tmp/src/common/web-navigation/platform-landing-page-utils.js
blob: c4084257cfc21bb8128480b4b63b4c1f476b7da6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
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