diff options
Diffstat (limited to 'node_modules/@jet-app/app-store/tmp/src/controllers')
19 files changed, 947 insertions, 0 deletions
diff --git a/node_modules/@jet-app/app-store/tmp/src/controllers/app-events/app-event-page-intent-controller.js b/node_modules/@jet-app/app-store/tmp/src/controllers/app-events/app-event-page-intent-controller.js new file mode 100644 index 0000000..1cda6ab --- /dev/null +++ b/node_modules/@jet-app/app-store/tmp/src/controllers/app-events/app-event-page-intent-controller.js @@ -0,0 +1,42 @@ +import { isNothing } from "@jet/environment/types/optional"; +import { appEventPageRoutes } from "../../common/product-page/intent-controller-routing"; +import { injectSEOData } from "../../api/models/web-renderable-page"; +import { makeAppEventPageRequest, makeShelfBasedAppEventDetailPage } from "../../common/app-events/app-events-common"; +import { withActiveIntent } from "../../foundation/dependencies/active-intent"; +import { fetchData, NetworkError } from "../../foundation/media/network"; +import { URL } from "../../foundation/network/urls"; +import { injectWebNavigation } from "../../common/web-navigation/inject-web-navigation"; +import { validateAdamId } from "../../foundation/media/util"; +export const AppEventPageIntentController = { + $intentKind: "AppEventPageIntent", + routes: appEventPageRoutes, + async perform(intent, objectGraphWithoutActiveIntent) { + return await withActiveIntent(objectGraphWithoutActiveIntent, intent, async (objectGraph) => { + var _a; + // See: https://github.pie.apple.com/its/Jingle/blob/ce14e21b6ac3dd4be884aa12b26d4e79c6d8aa7a/MZStorePlatform/src/main/java/com/apple/jingle/store/mediaapi/resource/SFMediaAPICommonResourceType.java#L50 + validateAdamId(objectGraph, intent.id); + const mediaApiRequest = makeAppEventPageRequest(objectGraph, intent); + const response = await fetchData(objectGraph, mediaApiRequest); + const page = makeShelfBasedAppEventDetailPage(objectGraph, response); + if (isNothing(page)) { + const notFoundError = new NetworkError("Media API response lacked required data"); + notFoundError.statusCode = 404; + throw notFoundError; + } + // The page URL (`.canonicalURL` property on the view-model) from Media API does not account for the `platform` + // query param; we need to add that in ourselves. We can't rely on `makeCanonicalUrl` as that does not handle the + // `appName` segment; we need to take the Media API URL and append the `platform` ourselves + if (intent.platform && page.canonicalURL) { + const pageURL = new URL(page.canonicalURL); + pageURL.param("platform", intent.platform); + page.canonicalURL = pageURL.toString(); + } + if (objectGraph.client.isWeb) { + injectWebNavigation(objectGraph, page, intent.platform); + injectSEOData(page, (_a = objectGraph.seo) === null || _a === void 0 ? void 0 : _a.getSEODataForAppEventPage(objectGraph, page, response)); + } + return page; + }); + }, +}; +//# sourceMappingURL=app-event-page-intent-controller.js.map
\ No newline at end of file diff --git a/node_modules/@jet-app/app-store/tmp/src/controllers/arcade/arcade-grouping-page-intent-controller.js b/node_modules/@jet-app/app-store/tmp/src/controllers/arcade/arcade-grouping-page-intent-controller.js new file mode 100644 index 0000000..ba1e42a --- /dev/null +++ b/node_modules/@jet-app/app-store/tmp/src/controllers/arcade/arcade-grouping-page-intent-controller.js @@ -0,0 +1,71 @@ +import { isNothing } from "@jet/environment/types/optional"; +import { fetchData } from "../../foundation/media/network"; +import { makeBaseGroupingPageRequest, prepareGroupingPageRequest } from "../../common/grouping/grouping-request"; +import { flattenedGroupingFromDataContainer, groupingPageFromFlattenedGrouping, groupingParseContextFromDataContainer, } from "../../common/grouping/render-grouping-page"; +import { arcadeAppsRequestForIcons } from "../../common/arcade/arcade-common"; +import { GroupingArcadeFooterShelfController } from "../../common/grouping/shelf-controllers/grouping-arcade-footer-shelf-controller"; +import { injectWebNavigation } from "../../common/web-navigation/inject-web-navigation"; +import { injectSEOData } from "../../api/models/web-renderable-page"; +import { withActiveIntent } from "../../foundation/dependencies/active-intent"; +import { setPreviewPlatform } from "../../common/preview-platform"; +function makeMediaApiArcadeGroupingPageRequest(objectGraph, intent) { + const mediaApiRequest = makeBaseGroupingPageRequest(objectGraph) + .addingQuery("name", "arcade") + .addingQuery("tabs", "subscriber"); + prepareGroupingPageRequest(objectGraph, mediaApiRequest); + setPreviewPlatform(objectGraph, mediaApiRequest); + return mediaApiRequest; +} +function makeArcadeSeeAllShelf(objectGraph, groupingParseContext, response) { + const token = { + id: "arcade-see-all-games-footer", + presentationHints: {}, + featuredContentId: -1 /* FeaturedContentID.Native_GroupingShelf */, + featuredContentData: null, + nativeGroupingShelfId: 1 /* NativeGroupingShelfID.Arcade_SeeAllGamesFooter */, + metricsPageInformation: groupingParseContext.metricsPageInformation, + metricsLocationTracker: groupingParseContext.metricsLocationTracker, + pageGenreId: groupingParseContext.pageGenreId, + title: null, + shouldFilter: false, + remainingItems: [], + isFirstRender: true, + isDeferring: false, + showOrdinals: false, + hasExistingContent: false, + showingPlaceholders: false, + ordinalIndex: 1, + isSearchLandingPage: groupingParseContext.isSearchLandingPage, + isArcadePage: groupingParseContext === null || groupingParseContext === void 0 ? void 0 : groupingParseContext.isArcadePage, + }; + const groupingArcadeFooterShelfController = new GroupingArcadeFooterShelfController(); + const arcadeFooterShelf = groupingArcadeFooterShelfController.createShelf(objectGraph, response, groupingParseContext, token, null); + return arcadeFooterShelf; +} +export const ArcadeGroupingPageIntentController = { + $intentKind: "ArcadeGroupingPageIntent", + async perform(intent, objectGraphWithoutActiveIntent) { + return await withActiveIntent(objectGraphWithoutActiveIntent, intent, async (objectGraph) => { + var _a; + const groupingPageRequest = makeMediaApiArcadeGroupingPageRequest(objectGraph, intent); + const arcadeFooterRequest = arcadeAppsRequestForIcons(objectGraph, 20); + const [groupingPageResponse, arcadeFooterResponse] = await Promise.all([ + fetchData(objectGraph, groupingPageRequest), + fetchData(objectGraph, arcadeFooterRequest), + ]); + const flattenedGrouping = flattenedGroupingFromDataContainer(objectGraph, groupingPageResponse); + const groupingParseContext = groupingParseContextFromDataContainer(objectGraph, groupingPageResponse); + if (isNothing(flattenedGrouping) || isNothing(groupingParseContext)) { + return null; + } + const page = groupingPageFromFlattenedGrouping(objectGraph, flattenedGrouping, groupingParseContext); + page.shelves.push(makeArcadeSeeAllShelf(objectGraph, groupingParseContext, arcadeFooterResponse)); + if (objectGraph.client.isWeb) { + injectWebNavigation(objectGraph, page, intent.platform); + injectSEOData(page, (_a = objectGraph.seo) === null || _a === void 0 ? void 0 : _a.getSEODataForGroupingPage(objectGraph, page, groupingPageResponse)); + } + return page; + }); + }, +}; +//# sourceMappingURL=arcade-grouping-page-intent-controller.js.map
\ No newline at end of file diff --git a/node_modules/@jet-app/app-store/tmp/src/controllers/arcade/routable-arcade-see-all-page-controller.js b/node_modules/@jet-app/app-store/tmp/src/controllers/arcade/routable-arcade-see-all-page-controller.js new file mode 100644 index 0000000..9751c7b --- /dev/null +++ b/node_modules/@jet-app/app-store/tmp/src/controllers/arcade/routable-arcade-see-all-page-controller.js @@ -0,0 +1,42 @@ +import { ArcadeSeeAllGamesPage } from "../../api/models"; +import { defaultAdditionalPlatformsForClient } from "../../foundation/media/data-fetching"; +import { fetchData } from "../../foundation/media/network"; +import { withActiveIntent } from "../../foundation/dependencies/active-intent"; +import { arcadeAppsRequest } from "../../common/arcade/arcade-common"; +import { defaultRequestAttributes, prepareRequestWithSelectedFacets } from "../../common/arcade/arcade-see-all-request"; +import { createArcadeSeeAllGamesPaginationToken, createShelves, } from "../../common/arcade/render-arcade-see-all-games-page"; +import { shouldFetchCustomAttributes } from "../../common/product-page/product-page-variants"; +import { metricsPageInformationFromMediaApiResponse } from "../../common/metrics/helpers/page"; +import { asArrayOrEmpty } from "../../foundation/json-parsing/server-data"; +import { injectWebNavigation } from "../../common/web-navigation/inject-web-navigation"; +import { createDefaultSelectedFacetOptions } from "../../common/arcade/arcade-see-all-games-facets"; +import { arcadeSeeAllRoutes as routes, makeArcadeSeeAllCanonicalUrl } from "../../common/arcade/arcade-see-all-routing"; +import { injectSEOData } from "../../api/models/web-renderable-page"; +export const RoutableArcadeSeeAllPageController = { + $intentKind: "RoutableArcadeSeeAllPageIntent", + routes, + async perform(intent, objectGraphWithoutActiveIntent) { + return await withActiveIntent(objectGraphWithoutActiveIntent, intent, async (objectGraph) => { + var _a; + const mediaApiRequest = arcadeAppsRequest(objectGraph) + .includingAdditionalPlatforms(defaultAdditionalPlatformsForClient(objectGraph)) + .includingAttributes(defaultRequestAttributes(objectGraph)) + .usingCustomAttributes(shouldFetchCustomAttributes(objectGraph)); + if (objectGraph.client.isWeb) { + mediaApiRequest.withSparseLimit(20); + } + prepareRequestWithSelectedFacets(mediaApiRequest, createDefaultSelectedFacetOptions(objectGraph)); + const mediaApiResponse = await fetchData(objectGraph, mediaApiRequest); + const pageInformation = metricsPageInformationFromMediaApiResponse(objectGraph, "Room", "arcadeSeeAllGames", mediaApiResponse); + const paginationToken = createArcadeSeeAllGamesPaginationToken(objectGraph, { isCompactMode: false }, pageInformation); + const page = new ArcadeSeeAllGamesPage(createShelves(objectGraph, asArrayOrEmpty(mediaApiResponse, "results.groups"), paginationToken)); + if (objectGraph.client.isWeb) { + page.canonicalURL = makeArcadeSeeAllCanonicalUrl(objectGraph, intent); + injectWebNavigation(objectGraph, page, intent.platform); + injectSEOData(page, (_a = objectGraph.seo) === null || _a === void 0 ? void 0 : _a.getSEODataForArcadeSeeAllPage(objectGraph, page, mediaApiResponse)); + } + return page; + }); + }, +}; +//# sourceMappingURL=routable-arcade-see-all-page-controller.js.map
\ No newline at end of file diff --git a/node_modules/@jet-app/app-store/tmp/src/controllers/developer/developer-page-intent-controller.js b/node_modules/@jet-app/app-store/tmp/src/controllers/developer/developer-page-intent-controller.js new file mode 100644 index 0000000..458db1d --- /dev/null +++ b/node_modules/@jet-app/app-store/tmp/src/controllers/developer/developer-page-intent-controller.js @@ -0,0 +1,28 @@ +import { Path } from "../../foundation/network/url-constants"; +import { makeDeveloperPageIntent } from "../../api/intents/developer-page-intent"; +import { generateRoutes } from "../../common/util/generate-routes"; +import { makeDeveloperRequest } from "../../common/developer/developer-request"; +import { fetchData } from "../../foundation/media/network"; +import { developerPageFromResponse } from "../../common/developer/developer-common"; +import { injectWebNavigation } from "../../common/web-navigation/inject-web-navigation"; +import { injectSEOData } from "../../api/models/web-renderable-page"; +import { validateAdamId } from "../../foundation/media/util"; +const { routes } = generateRoutes(makeDeveloperPageIntent, `/${Path.developer}/{name}/{id}`); +export const DeveloperPageIntentController = { + $intentKind: "DeveloperPageIntent", + routes, + async perform(intent, objectGraph) { + var _a; + // See: https://github.pie.apple.com/its/Jingle/blob/ce14e21b6ac3dd4be884aa12b26d4e79c6d8aa7a/MZStorePlatform/src/main/java/com/apple/jingle/store/mediaapi/resource/SFMediaAPICommonResourceType.java#L52 + validateAdamId(objectGraph, intent.id); + const mediaApiRequest = makeDeveloperRequest(objectGraph, intent.id); + const response = await fetchData(objectGraph, mediaApiRequest); + const page = developerPageFromResponse(objectGraph, response); + if (objectGraph.client.isWeb) { + injectWebNavigation(objectGraph, page); + injectSEOData(page, (_a = objectGraph.seo) === null || _a === void 0 ? void 0 : _a.getSEODataForDeveloperPage(objectGraph, page, response)); + } + return page; + }, +}; +//# sourceMappingURL=developer-page-intent-controller.js.map
\ No newline at end of file diff --git a/node_modules/@jet-app/app-store/tmp/src/controllers/editorial-pages/editorial-page-intent-controller.js b/node_modules/@jet-app/app-store/tmp/src/controllers/editorial-pages/editorial-page-intent-controller.js new file mode 100644 index 0000000..8c19eb7 --- /dev/null +++ b/node_modules/@jet-app/app-store/tmp/src/controllers/editorial-pages/editorial-page-intent-controller.js @@ -0,0 +1,55 @@ +import { isNothing } from "@jet/environment"; +import { renderPage as renderEditorialPage } from "../../common/editorial-pages/editorial-page-controller-util"; +import { makeEditorialPageRequest } from "../../common/editorial-pages/editorial-page-media-api-utils"; +import * as mediaNetwork from "../../foundation/media/network"; +import { FlowAction } from "../../api/models"; +import { withActiveIntent } from "../../foundation/dependencies/active-intent"; +import { isEditorialPageIntentByID } from "../../api/intents/editorial/editorial-page-intent"; +import { editorialPageRoutes, makeEditorialPageURL, } from "../../common/editorial-pages/editorial-page-intent-controller-utils"; +import { injectWebNavigation } from "../../common/web-navigation/inject-web-navigation"; +import { injectSEOData } from "../../api/models/web-renderable-page"; +import { validateAdamId, validateNeedsVisionRestriction } from "../../foundation/media/util"; +export const EditorialPageIntentController = { + $intentKind: "EditorialPageIntent", + routes(objectGraph) { + return editorialPageRoutes(objectGraph); + }, + async perform(intent, objectGraphWithoutActiveIntent) { + return await withActiveIntent(objectGraphWithoutActiveIntent, intent, async (objectGraph) => { + var _a; + if ("id" in intent) { + // See: https://github.pie.apple.com/its/Jingle/blob/ce14e21b6ac3dd4be884aa12b26d4e79c6d8aa7a/MZStorePlatform/src/main/java/com/apple/jingle/store/mediaapi/resource/SFMediaAPICommonResourceType.java#L91 + validateAdamId(objectGraph, intent.id); + } + validateNeedsVisionRestriction(objectGraph); + const mediaApiRequest = makeEditorialPageRequest(objectGraph, intent); + const response = await mediaNetwork.fetchData(objectGraph, mediaApiRequest); + const editorialPage = await renderEditorialPage(objectGraph, response, { + isArcadePage: false, + }); + if (isNothing(editorialPage)) { + const notFoundError = new mediaNetwork.NetworkError("Media API response lacked required data"); + notFoundError.statusCode = 404; + throw notFoundError; + } + // The Media API often does not provide a URL; if that is the case, synthesize one + if (isNothing(editorialPage.canonicalURL) && isEditorialPageIntentByID(intent)) { + editorialPage.canonicalURL = makeEditorialPageURL(objectGraph, intent); + } + if (objectGraph.client.isWeb) { + injectWebNavigation(objectGraph, editorialPage, intent.platform); + injectSEOData(editorialPage, (_a = objectGraph.seo) === null || _a === void 0 ? void 0 : _a.getSEODataForEditorialPage(objectGraph, editorialPage, response)); + } + return editorialPage; + }); + }, + actionFor(intent, objectGraph) { + const action = new FlowAction("page"); + action.destination = intent; + if (isEditorialPageIntentByID(intent)) { + action.pageUrl = makeEditorialPageURL(objectGraph, intent); + } + return action; + }, +}; +//# sourceMappingURL=editorial-page-intent-controller.js.map
\ No newline at end of file diff --git a/node_modules/@jet-app/app-store/tmp/src/controllers/editorial-pages/editorial-shelf-collection-page-intent-controller.js b/node_modules/@jet-app/app-store/tmp/src/controllers/editorial-pages/editorial-shelf-collection-page-intent-controller.js new file mode 100644 index 0000000..a8fdf9c --- /dev/null +++ b/node_modules/@jet-app/app-store/tmp/src/controllers/editorial-pages/editorial-shelf-collection-page-intent-controller.js @@ -0,0 +1,35 @@ +import { isNothing } from "@jet/environment/types/optional"; +import * as mediaNetwork from "../../foundation/media/network"; +import { withActiveIntent } from "../../foundation/dependencies/active-intent"; +import { editorialShelfCollectionPageRoutes, makeEditorialShelfCollectionPageURL, makeEditorialShelfCollectionPageRequest, renderEditorialShelfCollectionPage, } from "../../common/editorial-pages/editorial-shelf-collection-page-utils"; +import { injectWebNavigation } from "../../common/web-navigation/inject-web-navigation"; +import { injectSEOData } from "../../api/models/web-renderable-page"; +import { validateEditorialShelfCollectionId } from "../../foundation/media/util"; +export const EditorialShelfCollectionPageIntentController = { + $intentKind: "EditorialShelfCollectionPageIntent", + routes: editorialShelfCollectionPageRoutes, + async perform(intent, objectGraphWithoutActiveIntent) { + return await withActiveIntent(objectGraphWithoutActiveIntent, intent, async (objectGraph) => { + var _a; + // See: https://github.pie.apple.com/its/amp-enums/blob/f75500b44f871f35ba3ce459a5ff4c9f225e71b0/src/main/java/com/apple/jingle/store/IdSpace.java#L43 + validateEditorialShelfCollectionId(objectGraph, intent.id); + const mediaApiReqest = makeEditorialShelfCollectionPageRequest(objectGraph, intent); + const response = await mediaNetwork.fetchData(objectGraph, mediaApiReqest); + const editorialShelfCollectionPage = renderEditorialShelfCollectionPage(objectGraph, response); + if (isNothing(editorialShelfCollectionPage)) { + const notFoundError = new mediaNetwork.NetworkError("Media API response lacked required data"); + notFoundError.statusCode = 404; + throw notFoundError; + } + if (isNothing(editorialShelfCollectionPage.canonicalURL)) { + editorialShelfCollectionPage.canonicalURL = makeEditorialShelfCollectionPageURL(objectGraph, intent); + } + if (objectGraph.client.isWeb) { + injectWebNavigation(objectGraph, editorialShelfCollectionPage, intent.platform); + injectSEOData(editorialShelfCollectionPage, (_a = objectGraph.seo) === null || _a === void 0 ? void 0 : _a.getSEODataForEditorialShelfCollectionPage(objectGraph, editorialShelfCollectionPage, response)); + } + return editorialShelfCollectionPage; + }); + }, +}; +//# sourceMappingURL=editorial-shelf-collection-page-intent-controller.js.map
\ No newline at end of file diff --git a/node_modules/@jet-app/app-store/tmp/src/controllers/grouping/grouping-page-intent-controller.js b/node_modules/@jet-app/app-store/tmp/src/controllers/grouping/grouping-page-intent-controller.js new file mode 100644 index 0000000..a12827a --- /dev/null +++ b/node_modules/@jet-app/app-store/tmp/src/controllers/grouping/grouping-page-intent-controller.js @@ -0,0 +1,58 @@ +import { isNothing } from "@jet/environment/types/optional"; +import { fetchData } from "../../foundation/media/network"; +import { withActiveIntent } from "../../foundation/dependencies/active-intent"; +import { makeBaseGroupingPageRequest, prepareGroupingPageRequest } from "../../common/grouping/grouping-request"; +import { flattenedGroupingFromDataContainer, groupingPageFromFlattenedGrouping, groupingParseContextFromDataContainer, } from "../../common/grouping/render-grouping-page"; +import { injectWebNavigation } from "../../common/web-navigation/inject-web-navigation"; +import { setPreviewPlatform } from "../../common/preview-platform"; +import { groupingPageRoutes as routes, makeGroupingPageCanonicalURL } from "../../common/grouping/grouping-page-url"; +import { injectSEOData } from "../../api/models/web-renderable-page"; +import { validateGroupingId } from "../../foundation/media/util"; +function makeMediaApiGroupingPageRequest(objectGraph, intent) { + const mediaApiRequest = makeBaseGroupingPageRequest(objectGraph); + if ("name" in intent) { + mediaApiRequest.addingQuery("name", intent.name); + } + else { + mediaApiRequest.withIdOfType(intent.id, "groupings"); + } + if ("tabs" in intent) { + mediaApiRequest.addingQuery("tabs", intent.tabs); + } + prepareGroupingPageRequest(objectGraph, mediaApiRequest); + setPreviewPlatform(objectGraph, mediaApiRequest); + return mediaApiRequest; +} +export const GroupingPageIntentController = { + $intentKind: "GroupingPageIntent", + routes, + async perform(intent, objectGraphWithoutActiveIntent) { + return await withActiveIntent(objectGraphWithoutActiveIntent, intent, async (objectGraph) => { + var _a; + if ("id" in intent) { + // See: https://github.pie.apple.com/its/Jingle/blob/aaccec936f1feed227fd171ae66bb160cf38e497/MZStorePlatform/src/main/clojure/jingle/store/platform/api/realm/apps/apps_endpoints.clj#L1554 + // See: https://github.pie.apple.com/its/Jingle/blob/aaccec936f1feed227fd171ae66bb160cf38e497/MZStorePlatform/src/main/clojure/jingle/store/platform/api/controller/editorial_resource.clj#L9 + // See: https://github.pie.apple.com/its/Jingle/blob/aaccec936f1feed227fd171ae66bb160cf38e497/MZStorePlatform/src/main/java/com/apple/jingle/store/mediaapi/util/SFMediaAPIEditorialUtil.java#L585 + // See: https://github.pie.apple.com/its/Jingle/blob/aaccec936f1feed227fd171ae66bb160cf38e497/MZStorePlatform/src/main/java/com/apple/jingle/store/mediaapi/util/SFMediaAPIEditorialUtil.java#L633-L639 + validateGroupingId(objectGraph, intent.id); + } + const mediaApiRequest = makeMediaApiGroupingPageRequest(objectGraph, intent); + const response = await fetchData(objectGraph, mediaApiRequest); + const flattenedGrouping = flattenedGroupingFromDataContainer(objectGraph, response); + const groupingParseContext = groupingParseContextFromDataContainer(objectGraph, response); + if (isNothing(flattenedGrouping) || isNothing(groupingParseContext)) { + return null; + } + const page = groupingPageFromFlattenedGrouping(objectGraph, flattenedGrouping, groupingParseContext); + if ("id" in intent) { + page.canonicalURL = makeGroupingPageCanonicalURL(objectGraph, intent); + } + if (objectGraph.client.isWeb) { + injectWebNavigation(objectGraph, page, intent.platform); + injectSEOData(page, (_a = objectGraph.seo) === null || _a === void 0 ? void 0 : _a.getSEODataForGroupingPage(objectGraph, page, response)); + } + return page; + }); + }, +}; +//# sourceMappingURL=grouping-page-intent-controller.js.map
\ No newline at end of file diff --git a/node_modules/@jet-app/app-store/tmp/src/controllers/product-page/bundle-page-intent-controller.js b/node_modules/@jet-app/app-store/tmp/src/controllers/product-page/bundle-page-intent-controller.js new file mode 100644 index 0000000..382da66 --- /dev/null +++ b/node_modules/@jet-app/app-store/tmp/src/controllers/product-page/bundle-page-intent-controller.js @@ -0,0 +1,61 @@ +import { makeBundlePageIntent as baseMakeBundlePageIntent, } from "../../api/intents/bundle-page-intent"; +import { injectSEOData } from "../../api/models/web-renderable-page"; +import { generateRoutes } from "../../common/util/generate-routes"; +import { makeBundlePageRequest } from "../../common/product-page/bundle-page-common"; +import { createProductPageFromResponse } from "../../common/product-page/shelf-based/shelf-based-product-page"; +import { inferPreviewPlatformFromDeviceFamilies } from "../../common/preview-platform"; +import * as mediaNetwork from "../../foundation/media/network"; +import { injectWebNavigation } from "../../common/web-navigation/inject-web-navigation"; +import { withActiveIntent } from "../../foundation/dependencies/active-intent"; +import { URL } from "../../foundation/network/urls"; +import { validateAdamId } from "../../foundation/media/util"; +function makeBundlePageIntent(opts) { + const { ...clone } = opts; + // The `{bundleName}` dynamic segment is part of the URL for SEO purposes, but is not actually part + // of the `Intent` since it is not necessary for data-fetching. This data must not end up as + // part of the `Intent` as the value cannot be consistently normalized, which can break important + // caching behavior within the `web` client + delete clone["bundleName"]; + return baseMakeBundlePageIntent(clone); +} +// @ts-expect-error `generateRoutes` does not handle a typed `Platform` value correctly +const { routes } = generateRoutes(makeBundlePageIntent, "/app-bundle/{bundleName}/{id}", [], { + optionalQuery: ["platform", "lic"], +}); +export const BundlePageIntentController = { + $intentKind: "BundlePageIntent", + routes, + async perform(intent, objectGraphWithoutActiveIntent) { + return await withActiveIntent(objectGraphWithoutActiveIntent, intent, async (objectGraph) => { + var _a, _b; + // See: https://github.pie.apple.com/its/Jingle/blob/ce14e21b6ac3dd4be884aa12b26d4e79c6d8aa7a/MZStorePlatform/src/main/java/com/apple/jingle/store/mediaapi/resource/SFMediaAPICommonResourceType.java#L47 + validateAdamId(objectGraph, intent.id); + const mediaApiRequest = makeBundlePageRequest(objectGraph, intent); + const response = await mediaNetwork.fetchData(objectGraph, mediaApiRequest); + const previewPlatform = (_a = intent.platform) !== null && _a !== void 0 ? _a : inferPreviewPlatformFromDeviceFamilies(objectGraph, response); + if (!objectGraph.activeIntent.previewPlatform) { + objectGraph.activeIntent.setInferredPreviewPlatform(previewPlatform); + } + const page = await createProductPageFromResponse(objectGraph, response); + // The page URL (`.canonicalURL` property on the view-model) from Media API does not account for the `platform` + // query param; we need to add that in ourselves. We can't rely on `makeCanonicalUrl` as that does not handle the + // `bundleName` segment; we need to take the Media API URL and append the `platform` ourselves + if (page.canonicalURL) { + const pageURL = new URL(page.canonicalURL); + if (intent.platform) { + pageURL.param("platform", intent.platform); + } + if (intent.lic) { + pageURL.param("lic", intent.lic); + } + page.canonicalURL = pageURL.toString(); + } + if (objectGraph.client.isWeb) { + injectWebNavigation(objectGraph, page, previewPlatform); + injectSEOData(page, (_b = objectGraph.seo) === null || _b === void 0 ? void 0 : _b.getSEODataForBundlePage(objectGraph, page, response)); + } + return page; + }); + }, +}; +//# sourceMappingURL=bundle-page-intent-controller.js.map
\ No newline at end of file diff --git a/node_modules/@jet-app/app-store/tmp/src/controllers/product-page/eula-page-intent-controller.js b/node_modules/@jet-app/app-store/tmp/src/controllers/product-page/eula-page-intent-controller.js new file mode 100644 index 0000000..af1d155 --- /dev/null +++ b/node_modules/@jet-app/app-store/tmp/src/controllers/product-page/eula-page-intent-controller.js @@ -0,0 +1,38 @@ +import { withActiveIntent } from "../../foundation/dependencies/active-intent"; +import { isNothing } from "@jet/environment"; +import * as mediaNetwork from "../../foundation/media/network"; +import * as mediaDataFetching from "../../foundation/media/data-fetching"; +import * as models from "../../api/models"; +import * as serverData from "../../foundation/json-parsing/server-data"; +export const EulaPageIntentController = { + $intentKind: "EulaPageIntent", + async perform(intent, objectGraphWithoutActiveIntent) { + return await withActiveIntent(objectGraphWithoutActiveIntent, intent, async (objectGraph) => { + const { resourceId, resourceType } = intent; + if (isNothing(resourceId) || isNothing(resourceType)) { + const notFoundError = new mediaNetwork.NetworkError("content not found"); + notFoundError.statusCode = 404; + throw notFoundError; + } + const mediaApiRequest = new mediaDataFetching.Request(objectGraph).withIdOfType(resourceId, "eula"); + mediaApiRequest.targetResourceType = resourceType; + const response = await mediaNetwork.fetchData(objectGraph, mediaApiRequest); + const fullText = serverData.asString(response, "results.eula.text"); + const textParagraphs = fullText.split(/\n{1,2}/); // Split by one or two newlines. 3+ are respected. + const paragraphs = []; + for (const text of textParagraphs) { + const paragraph = new models.Paragraph(text); + paragraph.wantsCollapsedNewlines = false; + paragraph.suppressVerticalMargins = true; + paragraphs.push(paragraph); + } + const shelf = new models.Shelf("paragraph"); + shelf.isHorizontal = false; + shelf.items = paragraphs; + const page = new models.GenericPage([shelf]); + page.title = objectGraph.loc.string("LICENSE_AGREEMENT"); + return page; + }); + }, +}; +//# sourceMappingURL=eula-page-intent-controller.js.map
\ No newline at end of file diff --git a/node_modules/@jet-app/app-store/tmp/src/controllers/product-page/product-page-intent-controller.js b/node_modules/@jet-app/app-store/tmp/src/controllers/product-page/product-page-intent-controller.js new file mode 100644 index 0000000..c13c360 --- /dev/null +++ b/node_modules/@jet-app/app-store/tmp/src/controllers/product-page/product-page-intent-controller.js @@ -0,0 +1,63 @@ +import { withActiveIntent } from "../../foundation/dependencies/active-intent"; +import { FlowAction } from "../../api/models"; +import { productPageRoutes, makeProductPageURLWithoutAppSlug, } from "../../common/product-page/intent-controller-routing"; +import { injectSEOData } from "../../api/models/web-renderable-page"; +import { lookupURLForProductId as makeProductPageRequest } from "../../common/builders/url-mapping"; +import { createProductPageFromResponse } from "../../common/product-page/product-page-util"; +import { injectWebNavigation } from "../../common/web-navigation/inject-web-navigation"; +import * as mediaNetwork from "../../foundation/media/network"; +import { URL } from "../../foundation/network/urls"; +import { inferPreviewPlatformFromDeviceFamilies } from "../../common/preview-platform"; +import { validateAdamId } from "../../foundation/media/util"; +export const ProductPageIntentController = { + $intentKind: "ProductPageIntent", + routes: productPageRoutes, + async perform(intent, objectGraphWithoutActiveIntent) { + return await withActiveIntent(objectGraphWithoutActiveIntent, intent, async (objectGraph) => { + var _a, _b; + // See: https://github.pie.apple.com/its/Jingle/blob/ce14e21b6ac3dd4be884aa12b26d4e79c6d8aa7a/MZStorePlatform/src/main/java/com/apple/jingle/store/mediaapi/resource/SFMediaAPICommonResourceType.java#L46 + validateAdamId(objectGraph, intent.id); + const mediaApiRequest = makeProductPageRequest(objectGraph, intent.id, false, intent.ppid, false, false); + const response = await mediaNetwork.fetchData(objectGraph, mediaApiRequest); + // If the `Intent` does not specify a platform that the user requested, we need to select one of the options + // available in the Media API response to use instead. This will ensure we use the correct platform attributes + // when rendering the view-model + const inferredPlatform = inferPreviewPlatformFromDeviceFamilies(objectGraph, response); + if (!objectGraph.activeIntent.previewPlatform) { + const platformToSet = (_a = intent.platform) !== null && _a !== void 0 ? _a : inferredPlatform; + objectGraph.activeIntent.setInferredPreviewPlatform(platformToSet); + } + const previewPlatform = objectGraph.activeIntent.previewPlatform; + const productPage = (await createProductPageFromResponse(objectGraph, response)); + // The page URL (`.canonicalURL` property on the view-model) from Media API does not account for + // the `platform` and `ppid` query param; we need to add that in ourselves. + // We can't rely on `makeCanonicalUrl` as that does not handle the `appName` segment; + // We need to take the Media API URL and append the `platform` and `ppid` ourselves + if (productPage.canonicalURL) { + const pageURL = new URL(productPage.canonicalURL); + if (typeof intent.platform === "string" && intent.platform !== inferredPlatform) { + pageURL.param("platform", intent.platform); + } + if (typeof intent.ppid === "string" && intent.ppid) { + pageURL.param("ppid", intent.ppid); + } + if (typeof intent.lic === "string" && intent.lic) { + pageURL.param("lic", intent.lic); + } + productPage.canonicalURL = pageURL.toString(); + } + if (objectGraph.client.isWeb) { + injectWebNavigation(objectGraph, productPage, previewPlatform); + injectSEOData(productPage, (_b = objectGraph.seo) === null || _b === void 0 ? void 0 : _b.getSEODataForProductPage(objectGraph, productPage, response)); + } + return productPage; + }); + }, + actionFor(intent, objectGraph) { + const action = new FlowAction("product"); + action.destination = intent; + action.pageUrl = makeProductPageURLWithoutAppSlug(objectGraph, intent); + return action; + }, +}; +//# sourceMappingURL=product-page-intent-controller.js.map
\ No newline at end of file diff --git a/node_modules/@jet-app/app-store/tmp/src/controllers/product-page/see-all-intent-controller.js b/node_modules/@jet-app/app-store/tmp/src/controllers/product-page/see-all-intent-controller.js new file mode 100644 index 0000000..618bf5d --- /dev/null +++ b/node_modules/@jet-app/app-store/tmp/src/controllers/product-page/see-all-intent-controller.js @@ -0,0 +1,39 @@ +import { injectSEOData } from "../../api/models/web-renderable-page"; +import { withActiveIntent } from "../../foundation/dependencies/active-intent"; +import * as mediaNetwork from "../../foundation/media/network"; +import { validateAdamId } from "../../foundation/media/util"; +import { mediaApiProductSeeAllRequest } from "../../common/builders/url-mapping"; +import { createProductPageFromResponse } from "../../common/product-page/product-page-util"; +import { seeAllPageRoutes } from "../../common/product-page/intent-controller-routing"; +import { injectWebNavigation } from "../../common/web-navigation/inject-web-navigation"; +export const SeeAllPageIntentController = { + $intentKind: "SeeAllPageIntent", + routes: seeAllPageRoutes, + async perform(intent, objectGraphWithoutActiveIntent) { + return await withActiveIntent(objectGraphWithoutActiveIntent, intent, async (objectGraph) => { + var _a, _b; + validateAdamId(objectGraph, intent.id); + const seeAllRequest = mediaApiProductSeeAllRequest(objectGraph, intent.id, intent["see-all"]); + const seeAllResponse = await mediaNetwork.fetchData(objectGraph, seeAllRequest); + const page = (await createProductPageFromResponse(objectGraph, seeAllResponse)); + if (objectGraph.client.isWeb) { + // Synthesize the URL for the page based on the product page URL and the expected query param + if (page.canonicalURL) { + const pageURL = new URL(page.canonicalURL); + const params = pageURL.searchParams; + params.set("see-all", intent["see-all"]); + params.set("platform", intent.platform); + if (intent.platform) { + params.set("platform", intent.platform); + } + page.canonicalURL = pageURL.toString(); + } + page.seeAllType = intent["see-all"]; + injectWebNavigation(objectGraph, page, intent.platform); + injectSEOData(page, (_b = (_a = objectGraph.seo) === null || _a === void 0 ? void 0 : _a.getSEODataForSeeAllPage) === null || _b === void 0 ? void 0 : _b.call(_a, objectGraph, page, seeAllResponse)); + } + return page; + }); + }, +}; +//# sourceMappingURL=see-all-intent-controller.js.map
\ No newline at end of file diff --git a/node_modules/@jet-app/app-store/tmp/src/controllers/room/room-page-intent-controller.js b/node_modules/@jet-app/app-store/tmp/src/controllers/room/room-page-intent-controller.js new file mode 100644 index 0000000..a414856 --- /dev/null +++ b/node_modules/@jet-app/app-store/tmp/src/controllers/room/room-page-intent-controller.js @@ -0,0 +1,29 @@ +import { withActiveIntent } from "../../foundation/dependencies/active-intent"; +import { fetchData } from "../../foundation/media/network"; +import { roomPageRoutes as routes, makeCanonicalRoomPageUrl } from "../../common/room/room-common"; +import { createRoomRequest } from "../../common/room/room-request"; +import { renderRoomPage } from "../../common/room/room-page"; +import { injectWebNavigation } from "../../common/web-navigation/inject-web-navigation"; +import { injectSEOData } from "../../api/models/web-renderable-page"; +import { validateFcId } from "../../foundation/media/util"; +export const RoomPageIntentController = { + $intentKind: "RoomPageIntent", + routes, + async perform(intent, objectGraphWithoutActiveIntent) { + return await withActiveIntent(objectGraphWithoutActiveIntent, intent, async (objectGraph) => { + var _a; + // See: https://github.pie.apple.com/its/Jingle/blob/d2d051c9ef2891f72d5f02f5bbbf2d7748afa7b9/MZStoreComponents/src/main/java/com/apple/jingle/app/store/editorial/SFEditorialHelper.java#L293 + validateFcId(objectGraph, intent.id); + const mediaApiRequest = createRoomRequest(objectGraph, intent.id); + const response = await fetchData(objectGraph, mediaApiRequest); + const page = renderRoomPage(objectGraph, response); + page.canonicalURL = makeCanonicalRoomPageUrl(objectGraph, intent); + if (objectGraph.client.isWeb) { + injectWebNavigation(objectGraph, page, intent.platform); + injectSEOData(page, (_a = objectGraph.seo) === null || _a === void 0 ? void 0 : _a.getSEODataForRoomPage(objectGraph, page, response)); + } + return page; + }); + }, +}; +//# sourceMappingURL=room-page-intent-controller.js.map
\ No newline at end of file diff --git a/node_modules/@jet-app/app-store/tmp/src/controllers/search/search-landing-page-intent-controller.js b/node_modules/@jet-app/app-store/tmp/src/controllers/search/search-landing-page-intent-controller.js new file mode 100644 index 0000000..aafca37 --- /dev/null +++ b/node_modules/@jet-app/app-store/tmp/src/controllers/search/search-landing-page-intent-controller.js @@ -0,0 +1,34 @@ +import { isNothing } from "@jet/environment"; +import { makeSearchLandingPageIntent, } from "../../api/intents/search/search-landing-page-intent"; +import { generateRoutes } from "../../common/util/generate-routes"; +import { fetchPage } from "../../common/search/search-landing-page-utils"; +import { injectWebNavigation } from "../../common/web-navigation/inject-web-navigation"; +import { withActiveIntent } from "../../foundation/dependencies/active-intent"; +import { injectSEOData } from "../../api/models/web-renderable-page"; +import { validateNeedsVisionRestriction } from "../../foundation/media/util"; +const { routes, makeCanonicalUrl } = generateRoutes(makeSearchLandingPageIntent, "/{platform}/search"); +export const SearchLandingPageIntentController = { + $intentKind: "SearchLandingPageIntent", + routes, + async perform(intent, objectGraphWithoutActiveIntent) { + if (objectGraphWithoutActiveIntent.client.isWeb && !intent.platform) { + // Search on the "web" client requires a platform; if we don't have one from the `Intent`, we should + // assume we want `iphone` results + intent.platform = "iphone"; + } + return await withActiveIntent(objectGraphWithoutActiveIntent, intent, async (objectGraph) => { + var _a; + validateNeedsVisionRestriction(objectGraph); + const searchLandingPage = await fetchPage(objectGraph); + if (isNothing(searchLandingPage.canonicalURL)) { + searchLandingPage.canonicalURL = makeCanonicalUrl(objectGraph, intent); + } + if (objectGraph.client.isWeb) { + injectWebNavigation(objectGraph, searchLandingPage, intent.platform); + injectSEOData(searchLandingPage, (_a = objectGraph.seo) === null || _a === void 0 ? void 0 : _a.getSEODataForSearchLandingPage(objectGraph, searchLandingPage, null)); + } + return searchLandingPage; + }); + }, +}; +//# sourceMappingURL=search-landing-page-intent-controller.js.map
\ No newline at end of file diff --git a/node_modules/@jet-app/app-store/tmp/src/controllers/search/search-results-controller.js b/node_modules/@jet-app/app-store/tmp/src/controllers/search/search-results-controller.js new file mode 100644 index 0000000..d263c24 --- /dev/null +++ b/node_modules/@jet-app/app-store/tmp/src/controllers/search/search-results-controller.js @@ -0,0 +1,152 @@ +import { isNothing } from "@jet/environment"; +import * as models from "../../api/models"; +import { FetchTimingMetricsBuilder } from "@jet/environment/metrics/fetch-timing-metrics-builder"; +import { injectSEOData } from "../../api/models/web-renderable-page"; +import { AbstractPageBuilder } from "../../common/builders/abstract-page-builder"; +import * as search from "../../common/search/search"; +import { makeCanonicalSearchResultsPageUrl, searchResultsPageRoutes } from "../../common/search/search-page-url"; +import * as searchResultsFetching from "../../common/search/search-results-fetching"; +import { injectWebNavigation } from "../../common/web-navigation/inject-web-navigation"; +import { replacePlatformSelectorDestinationWithSearchResults } from "../../common/web-navigation/search-results-platform-selection"; +import { withActiveIntent } from "../../foundation/dependencies/active-intent"; +import { validateNeedsVisionRestriction } from "../../foundation/media/util"; +/** Handles `SearchResultsIntent` to fetch the search results. This is for shelves v1. */ +export class SearchResultsIntentController { + constructor() { + this.$intentKind = "SearchResultsIntent"; + } + async perform(intent, objectGraph) { + return await fetchSearchResults(objectGraph, intent.requestDescriptor); + } +} +/** Handles `SearchResultsMoreIntent` to fetch more of the search results. This is for shelves v1. */ +export class SearchResultsMoreIntentController { + constructor() { + this.$intentKind = "SearchResultsMoreIntent"; + } + async perform(intent, objectGraph) { + return await fetchMoreSearchResults(objectGraph, intent.pageToken); + } +} +/** Handles `SegmentedSearchResultsPageIntent` to fetch the segmented search results. */ +export class SegmentedSearchResultsPageIntentController { + constructor() { + this.$intentKind = "SegmentedSearchResultsPageIntent"; + } + async perform(intent, objectGraph) { + return await fetchSegmentedSearchResults(objectGraph, intent.requestDescriptor); + } +} +/** Handles `SearchResultsPageIntent` to fetch the search results. This is for shelves 2.0. */ +export class SearchResultsPageIntentController { + constructor() { + this.$intentKind = "SearchResultsPageIntent"; + this.routes = searchResultsPageRoutes; + } + async perform(intent, objectGraphWithoutActiveIntnet) { + if (objectGraphWithoutActiveIntnet.client.isWeb && !intent.platform) { + // Search on the "web" client requires a platform; if we don't have one from the `Intent`, we should + // assume we want `iphone` results + intent.platform = "iphone"; + } + return await withActiveIntent(objectGraphWithoutActiveIntnet, intent, async (objectGraph) => { + var _a; + validateNeedsVisionRestriction(objectGraph); + const searchResultsPage = await fetchSearchResultsPage(objectGraph, intent); + if (isNothing(searchResultsPage.canonicalURL)) { + searchResultsPage.canonicalURL = makeCanonicalSearchResultsPageUrl(objectGraph, intent); + } + if (objectGraph.client.isWeb) { + const webNavigation = injectWebNavigation(objectGraph, searchResultsPage, intent.platform); + webNavigation.searchAction.destination.term = intent.term; + replacePlatformSelectorDestinationWithSearchResults(objectGraph, webNavigation, intent); + injectSEOData(searchResultsPage, (_a = objectGraph.seo) === null || _a === void 0 ? void 0 : _a.getSEODataForSearchResultsPage(objectGraph, searchResultsPage, null)); + } + return searchResultsPage; + }); + } + actionFor(intent, objectGraph) { + const flowAction = new models.FlowAction("search"); + flowAction.destination = intent; + flowAction.pageUrl = makeCanonicalSearchResultsPageUrl(objectGraph, intent); + return flowAction; + } +} +/** Handles `SearchResultsPageMoreIntent` to fetch more of the search results. This is for shelves 2.0. */ +export class SearchResultsPageMoreIntentController { + constructor() { + this.$intentKind = "SearchResultsPageMoreIntent"; + } + async perform(intent, objectGraph) { + return await fetchMoreSearchResultsPage(objectGraph, intent.pageToken); + } +} +/** Fetches search results for shelves v1. */ +async function fetchSearchResults(objectGraph, requestDescriptor) { + const fetchTimingMetricsBuilder = new FetchTimingMetricsBuilder(); + const modifiedObjectGraph = objectGraph.addingFetchTimingMetricsBuilder(fetchTimingMetricsBuilder); + const combinedSearchData = await searchResultsFetching.fetchSequentialSearchResultsData(modifiedObjectGraph, requestDescriptor); + if (combinedSearchData === null) { + return search.emptyResults(modifiedObjectGraph, requestDescriptor.facets); + } + return await search.searchResultsFromResponse(modifiedObjectGraph, combinedSearchData); +} +/** Fetches search results for segmented search results on visionOS */ +async function fetchSegmentedSearchResults(objectGraph, requestDescriptor) { + const combinedSearchData = await searchResultsFetching.fetchSegmentedSearchResults(objectGraph, requestDescriptor); + if (combinedSearchData === null) { + return search.emptySegmentedResultsPage(objectGraph); + } + return await search.segmentedSearchResultsPageFromResponse(objectGraph, combinedSearchData); +} +/** Fetches more search results for shelves v1. */ +async function fetchMoreSearchResults(objectGraph, token) { + return await search.paginatedSearchResultsWithToken(objectGraph, token); +} +/** Fetches search results for shelves 2.0. */ +async function fetchSearchResultsPage(objectGraph, requestDescriptor) { + const fetchTimingMetricsBuilder = new FetchTimingMetricsBuilder(); + const modifiedObjectGraph = objectGraph.addingFetchTimingMetricsBuilder(fetchTimingMetricsBuilder); + const combinedSearchData = await searchResultsFetching.fetchSequentialSearchResultsData(modifiedObjectGraph, requestDescriptor); + if (combinedSearchData === null) { + return search.emptyResultsPage(objectGraph, requestDescriptor.facets); + } + return await search.searchResultsPageFromResponse(modifiedObjectGraph, combinedSearchData); +} +/** Fetches more search results for shelves 2.0. */ +async function fetchMoreSearchResultsPage(objectGraph, token) { + return await search.paginatedSearchResultsPageWithToken(objectGraph, token); +} +export class SearchResultsBuilder extends AbstractPageBuilder { + constructor(objectGraph, runtime) { + super("SearchResultsBuilder"); + runtime.exportingService("SearchData", { + /** Fetches search results for shelves v1. */ + async fetchResults(options) { + return await fetchSearchResults(objectGraph, options); + }, + /** Fetches more search results for shelves v1. */ + async fetchMoreResults(options) { + return await fetchMoreSearchResults(objectGraph, options.pageToken); + }, + /** Fetches search results for shelves 2.0. */ + async fetchSearchResultsPage(options) { + return await fetchSearchResultsPage(objectGraph, options); + }, + /** Fetches more search results for shelves 2.0. */ + async fetchMoreOfSearchResultsPage(options) { + return await fetchMoreSearchResultsPage(objectGraph, options.pageToken); + }, + }); + } + async handlePage(objectGraph, url, parameters, matchedRuleIdentifier, referrerData, isIncomingURL) { + throw new Error("No page routes specified"); + } + pageRoute(objectGraph) { + return []; + } + pageType() { + return "unknown"; + } +} +//# sourceMappingURL=search-results-controller.js.map
\ No newline at end of file diff --git a/node_modules/@jet-app/app-store/tmp/src/controllers/today/routable-article-page-intent-controller.js b/node_modules/@jet-app/app-store/tmp/src/controllers/today/routable-article-page-intent-controller.js new file mode 100644 index 0000000..9ab32b1 --- /dev/null +++ b/node_modules/@jet-app/app-store/tmp/src/controllers/today/routable-article-page-intent-controller.js @@ -0,0 +1,53 @@ +import { withActiveIntent } from "../../foundation/dependencies/active-intent"; +import { injectSEOData } from "../../api/models/web-renderable-page"; +import { buildArticlePageRequest } from "../../common/today/article-request"; +import { fetchData } from "../../foundation/media/network"; +import { articlePageFromResponse, ArticleParseContext } from "../../common/today/article"; +import { routableArticlePageWithPlatformRoutes, routableArticlePageWithoutPlatformRoutes, makeRoutableArticlePageCanonicalUrl, } from "../../common/today/routable-article-page-url-utils"; +import { injectWebNavigation } from "../../common/web-navigation/inject-web-navigation"; +import { inferPreviewPlatformFromEditorialPlatforms } from "../../common/preview-platform"; +import { validateAdamId } from "../../foundation/media/util"; +export const RoutableArticlePageIntentController = { + $intentKind: "RoutableArticlePageIntent", + routes(objectGraph) { + return [ + // Note: order here is important! Both URL patterns provide an option where there is a + // single dynamic segment in front of the stable `/story` segment; it could be either + // the platform without an explicit storefront, or a storefront without an explicit platform. + // We want to assume the latter, so the URLs without a platform must be defined first + ...routableArticlePageWithoutPlatformRoutes(objectGraph), + ...routableArticlePageWithPlatformRoutes(objectGraph), + ]; + }, + async perform(intent, objectGraphWithoutActiveIntent) { + return await withActiveIntent(objectGraphWithoutActiveIntent, intent, async (objectGraph) => { + var _a, _b, _c; + // See: https://github.pie.apple.com/its/Jingle/blob/ce14e21b6ac3dd4be884aa12b26d4e79c6d8aa7a/MZStorePlatform/src/main/java/com/apple/jingle/store/mediaapi/resource/SFMediaAPICommonResourceType.java#L89 + validateAdamId(objectGraph, intent.id); + const mediaApiRequest = buildArticlePageRequest(objectGraph, intent, false); + const response = await fetchData(objectGraph, mediaApiRequest); + // If the user visits a "story" without an explicit "platform" specified, we need to infer a + // desirable default so that we can look up the correct platform attributes when rendering + // the view-model + const previewPlatform = (_a = intent.platform) !== null && _a !== void 0 ? _a : inferPreviewPlatformFromEditorialPlatforms(objectGraph, response); + if (!objectGraph.activeIntent.previewPlatform) { + objectGraph.activeIntent.setInferredPreviewPlatform(previewPlatform); + } + const articleParseContext = new ArticleParseContext(); + const page = articlePageFromResponse(objectGraph, response, articleParseContext); + // The Media API-provided `.canonicalURL` will not contain the explicit `{platform}` + // segment, if required; we need to override their value to make use of the URL + // factory provided by our routing utils instead + page.canonicalURL = makeRoutableArticlePageCanonicalUrl(objectGraph, intent); + if (objectGraph.client.isWeb) { + const webNavigation = injectWebNavigation(objectGraph, page, previewPlatform); + if ((_b = page.card) === null || _b === void 0 ? void 0 : _b.title) { + webNavigation.title = page.card.title; + } + injectSEOData(page, (_c = objectGraph.seo) === null || _c === void 0 ? void 0 : _c.getSEODataForArticlePage(objectGraph, page, response)); + } + return page; + }); + }, +}; +//# sourceMappingURL=routable-article-page-intent-controller.js.map
\ No newline at end of file diff --git a/node_modules/@jet-app/app-store/tmp/src/controllers/today/routable-today-page-intent-controller.js b/node_modules/@jet-app/app-store/tmp/src/controllers/today/routable-today-page-intent-controller.js new file mode 100644 index 0000000..d12e4ef --- /dev/null +++ b/node_modules/@jet-app/app-store/tmp/src/controllers/today/routable-today-page-intent-controller.js @@ -0,0 +1,21 @@ +import { withActiveIntent } from "../../foundation/dependencies/active-intent"; +import { buildTodayPageFromRequest, generateTodayPageRequest, prepareRequest as prepareTodayPageRequest, } from "../../common/today/today-controller-util"; +import { injectWebNavigation } from "../../common/web-navigation/inject-web-navigation"; +import { injectSEOData } from "../../api/models/web-renderable-page"; +export const RoutableTodayPageIntentController = { + $intentKind: "RoutableTodayPageIntent", + async perform(intent, objectGraphWithoutActiveIntent) { + return await withActiveIntent(objectGraphWithoutActiveIntent, intent, async (objectGraph) => { + var _a; + const mediaApiRequest = generateTodayPageRequest(objectGraph); + prepareTodayPageRequest(objectGraph, mediaApiRequest, true); + const page = await buildTodayPageFromRequest(objectGraph, mediaApiRequest); + if (objectGraph.client.isWeb) { + injectWebNavigation(objectGraph, page, intent.platform); + injectSEOData(page, (_a = objectGraph.seo) === null || _a === void 0 ? void 0 : _a.getSEODataForTodayPage(objectGraph, page, null)); + } + return page; + }); + }, +}; +//# sourceMappingURL=routable-today-page-intent-controller.js.map
\ No newline at end of file diff --git a/node_modules/@jet-app/app-store/tmp/src/controllers/top-charts/charts-hub-page-intent-controller.js b/node_modules/@jet-app/app-store/tmp/src/controllers/top-charts/charts-hub-page-intent-controller.js new file mode 100644 index 0000000..0f1a16e --- /dev/null +++ b/node_modules/@jet-app/app-store/tmp/src/controllers/top-charts/charts-hub-page-intent-controller.js @@ -0,0 +1,39 @@ +import { makeChartsPageIntent } from "../../api/intents/charts-page-intent"; +import { withActiveIntent } from "../../foundation/dependencies/active-intent"; +import { renderChartsHub } from "../../common/charts/charts-hub"; +import { chartsHubPageRoutes, makeChartsHubPageURL } from "../../common/charts/charts-page-url"; +import { injectWebNavigation } from "../../common/web-navigation/inject-web-navigation"; +import { injectSEOData } from "../../api/models/web-renderable-page"; +const APPS_GENRE_ID_STATIC = "36"; +const GAMES_GENRE_ID_STATIC = "6014"; +export const ChartsHubPageIntentController = { + $intentKind: "ChartsHubPageIntent", + routes: chartsHubPageRoutes, + async perform(intent, objectGraphWithoutActiveIntent) { + return await withActiveIntent(objectGraphWithoutActiveIntent, intent, async (objectGraph) => { + var _a; + const [appsPage, gamesPage] = await Promise.all([ + objectGraph.dispatcher.dispatch(makeChartsPageIntent({ + storefront: intent.storefront, + language: intent.language, + platform: intent.platform, + genreId: APPS_GENRE_ID_STATIC, + }), objectGraph), + objectGraph.dispatcher.dispatch(makeChartsPageIntent({ + storefront: intent.storefront, + language: intent.language, + platform: intent.platform, + genreId: GAMES_GENRE_ID_STATIC, + }), objectGraph), + ]); + const hubPage = renderChartsHub(objectGraph, appsPage, gamesPage); + hubPage.canonicalURL = makeChartsHubPageURL(objectGraph, intent); + if (objectGraph.client.isWeb) { + injectWebNavigation(objectGraph, hubPage, intent.platform); + injectSEOData(hubPage, (_a = objectGraph.seo) === null || _a === void 0 ? void 0 : _a.getSEODataForChartsHubPage(objectGraph, hubPage, null)); + } + return hubPage; + }); + }, +}; +//# sourceMappingURL=charts-hub-page-intent-controller.js.map
\ No newline at end of file diff --git a/node_modules/@jet-app/app-store/tmp/src/controllers/top-charts/charts-page-intent-controller.js b/node_modules/@jet-app/app-store/tmp/src/controllers/top-charts/charts-page-intent-controller.js new file mode 100644 index 0000000..79a0667 --- /dev/null +++ b/node_modules/@jet-app/app-store/tmp/src/controllers/top-charts/charts-page-intent-controller.js @@ -0,0 +1,25 @@ +import { injectSEOData } from "../../api/models/web-renderable-page"; +import { withActiveIntent } from "../../foundation/dependencies/active-intent"; +import { chartsPageRoutes, makeChartsPageURL } from "../../common/charts/charts-page-url"; +import { injectWebNavigation } from "../../common/web-navigation/inject-web-navigation"; +import { fetchAndRenderTopChartPage } from "../../common/top-charts/top-charts-page"; +import { validateGenreId } from "../../foundation/media/util"; +export const ChartsPageIntentController = { + $intentKind: "ChartsPageIntent", + routes: chartsPageRoutes, + async perform(intent, objectGraphWithoutActiveIntent) { + return await withActiveIntent(objectGraphWithoutActiveIntent, intent, async (objectGraph) => { + var _a; + // See: https://github.pie.apple.com/its/Jingle/blob/aaccec936f1feed227fd171ae66bb160cf38e497/MZStorePlatform/src/main/clojure/jingle/store/platform/api/controller/categories.clj#L135 + validateGenreId(objectGraph, intent.genreId); + const page = await fetchAndRenderTopChartPage(objectGraph, intent.genreId, null, intent.chart, intent.ageBandId); + if (objectGraph.client.isWeb) { + injectWebNavigation(objectGraph, page, intent.platform); + injectSEOData(page, (_a = objectGraph.seo) === null || _a === void 0 ? void 0 : _a.getSEODataForChartsPage(objectGraph, page, null)); + } + page.canonicalURL = makeChartsPageURL(objectGraph, intent); + return page; + }); + }, +}; +//# sourceMappingURL=charts-page-intent-controller.js.map
\ No newline at end of file diff --git a/node_modules/@jet-app/app-store/tmp/src/controllers/web-navigation/category-tabs-intent-controller.js b/node_modules/@jet-app/app-store/tmp/src/controllers/web-navigation/category-tabs-intent-controller.js new file mode 100644 index 0000000..02487d2 --- /dev/null +++ b/node_modules/@jet-app/app-store/tmp/src/controllers/web-navigation/category-tabs-intent-controller.js @@ -0,0 +1,62 @@ +import { isSome } from "@jet/environment/types/optional"; +import { dataCollectionFromDataContainer } from "../../foundation/media/data-structure"; +import { withActiveIntent } from "../../foundation/dependencies/active-intent"; +import { asDictionary, isDefinedNonNullNonEmpty } from "../../foundation/json-parsing/server-data"; +import { attributeAsDictionary } from "../../foundation/media/attributes"; +import { Request } from "../../foundation/media/data-fetching"; +import { fetchData } from "../../foundation/media/network"; +import { relationshipData } from "../../foundation/media/relationships"; +import { artworkFromApiArtwork } from "../../common/content/content"; +import { actionFromData } from "../../common/lockups/lockups"; +import { newLocationTracker } from "../../common/metrics/helpers/location"; +export class CategoryTabsIntentController { + constructor() { + this.$intentKind = "CategoryTabsIntent"; + } + async perform(intent, objectGraphWithoutActiveIntent) { + return await withActiveIntent(objectGraphWithoutActiveIntent, intent, async (objectGraph) => { + const editorialItemId = objectGraph.bag.webNavigationCategoryTabsEditorialItemId; + if (!isSome(editorialItemId)) { + return []; + } + const attributes = ["editorialArtwork"]; + const request = new Request(objectGraph) + .withIdOfType(editorialItemId, "collections") + .includingScopedAttributes("editorial-items", attributes) + .includingScopedAttributes("editorial-pages", attributes) + .addingQuery("sparseLimit[card-contents]", "0") + .addingQuery("platform", "web") + .addingQuery("previewPlatform", objectGraph.activeIntent.platform); + const response = await fetchData(objectGraph, request); + const contents = dataCollectionFromDataContainer(response); + return contents.map((item) => { + const primaryContent = relationshipData(objectGraph, item, "primary-content"); + const dataSource = primaryContent || item; + const metricsBase = { + pageInformation: null, + locationTracker: newLocationTracker(), + id: item.id, + }; + const formattedArtwork = getFormattedArtwork(objectGraph, item); + return { + action: actionFromData(objectGraph, dataSource, metricsBase, objectGraph.host.clientIdentifier), + isActive: intent.id === dataSource.id, + artwork: formattedArtwork, + }; + }); + }); + } +} +function getFormattedArtwork(objectGraph, data) { + const artwork = attributeAsDictionary(data, "artwork", null) || attributeAsDictionary(data, "editorialArtwork"); + if (!isDefinedNonNullNonEmpty(artwork)) { + return undefined; + } + const editorialArtwork = attributeAsDictionary(data, "editorialArtwork"); + const icon = asDictionary(editorialArtwork, "brandLogo", null); + return artworkFromApiArtwork(objectGraph, icon, { + allowingTransparency: true, + useCase: 20 /* ArtworkUseCase.CategoryIcon */, + }); +} +//# sourceMappingURL=category-tabs-intent-controller.js.map
\ No newline at end of file |
