From bce557cc2dc767628bed6aac87301a1be7c5431b Mon Sep 17 00:00:00 2001 From: rxliuli Date: Tue, 4 Nov 2025 05:03:50 +0800 Subject: init commit --- .../app-store/tmp/src/common/content/attributes.js | 328 +++++++++++++++++++++ 1 file changed, 328 insertions(+) create mode 100644 node_modules/@jet-app/app-store/tmp/src/common/content/attributes.js (limited to 'node_modules/@jet-app/app-store/tmp/src/common/content/attributes.js') diff --git a/node_modules/@jet-app/app-store/tmp/src/common/content/attributes.js b/node_modules/@jet-app/app-store/tmp/src/common/content/attributes.js new file mode 100644 index 0000000..1cae53a --- /dev/null +++ b/node_modules/@jet-app/app-store/tmp/src/common/content/attributes.js @@ -0,0 +1,328 @@ +import { isNothing, isSome } from "@jet/environment/types/optional"; +import * as derivedData from "../../foundation/json-parsing/derived-data"; +import * as serverData from "../../foundation/json-parsing/server-data"; +import * as mediaAttributes from "../../foundation/media/attributes"; +import * as mediaPlatformAttributes from "../../foundation/media/platform-attributes"; +import { variantAttributeForKey } from "../product-page/product-page-variants"; +import * as contentDeviceFamily from "./device-family"; +/** + * Retrieve the specified attribute from the data, coercing it to a JSONData dictionary + * + * @param data The data from which to retrieve the attribute. + * @param attributePath The path of the attribute. + * @param attributePlatform The specific platform attribute to get content for. Omit to infer from the data's structure. + * @param defaultValue The object to return if the path search fails. + * @returns The dictionary of data + */ +export function contentAttributeAsDictionary(objectGraph, data, attributePath, attributePlatform, defaultValue) { + if (!attributePlatform) { + attributePlatform = bestAttributePlatformFromData(objectGraph, data); + } + if (isNothing(attributePlatform)) { + return null; + } + let value = mediaPlatformAttributes.platformAttributeAsDictionary(data, attributePlatform, attributePath); + if (!value) { + value = mediaAttributes.attributeAsDictionary(data, attributePath, defaultValue); + } + return value; +} +/** + * Retrieve the specified attribute from the data as an array, coercing to an empty array if the object is not an array. + * + * @param data The data from which to retrieve the attribute. + * @param attributePath The path of the attribute. + * @param attributePlatformOverride An override platform, from which to fetch the attribute. + * @returns {any[]} The attribute value as an array. + */ +export function contentAttributeAsArrayOrEmpty(objectGraph, data, attributePath, attributePlatformOverride = undefined) { + const attributePlatform = attributePlatformOverride !== null && attributePlatformOverride !== void 0 ? attributePlatformOverride : bestAttributePlatformFromData(objectGraph, data); + if (isNothing(attributePlatform)) { + return []; + } + let value = mediaPlatformAttributes.platformAttributeAsArrayOrEmpty(data, attributePlatform, attributePath); + if (serverData.isNullOrEmpty(value)) { + value = mediaAttributes.attributeAsArrayOrEmpty(data, attributePath); + } + return value; +} +/** + * Retrieve the specified attribute from the data as an array. + * + * @param data The data from which to retrieve the attribute. + * @param attributePath The path of the attribute. + * @param attributePlatformOverride An override platform, from which to fetch the attribute. + * @returns {any[]} The attribute value as an array. + */ +export function contentAttributeAsArray(objectGraph, data, attributePath, attributePlatformOverride = undefined) { + const attributePlatform = attributePlatformOverride !== null && attributePlatformOverride !== void 0 ? attributePlatformOverride : bestAttributePlatformFromData(objectGraph, data); + if (isNothing(attributePlatform)) { + return null; + } + let value = mediaPlatformAttributes.platformAttributeAsArray(data, attributePlatform, attributePath); + if (isNothing(value)) { + value = mediaAttributes.attributeAsArray(data, attributePath); + } + return value; +} +/** + * Retrieve the specified attribute from the data as a string. + * + * @param data The data from which to retrieve the attribute. + * @param attributePath The object path for the attribute. + * @param attributePlatformOverride An override platform, from which to fetch the attribute. + * @param policy The validation policy to use when resolving this value. + * @returns {string} The attribute value as a string. + */ +export function contentAttributeAsString(objectGraph, data, attributePath, attributePlatformOverride = undefined, policy = "coercible") { + let value; + const attributePlatform = attributePlatformOverride !== null && attributePlatformOverride !== void 0 ? attributePlatformOverride : bestAttributePlatformFromData(objectGraph, data); + if (isSome(attributePlatform)) { + value = mediaPlatformAttributes.platformAttributeAsString(data, attributePlatform, attributePath, policy); + } + if (!value) { + value = mediaAttributes.attributeAsString(data, attributePath, policy); + } + return value; +} +/** + * Retrieve the specified attribute from the data as a boolean. + * + * @param data The data from which to retrieve the attribute. + * @param attributePath The path of the attribute. + * @param policy The validation policy to use when resolving this value. + * @returns {boolean} The attribute value as a boolean. + */ +export function contentAttributeAsBoolean(objectGraph, data, attributePath, attributePlatform, policy = "coercible") { + if (!attributePlatform) { + attributePlatform = bestAttributePlatformFromData(objectGraph, data); + } + if (isNothing(attributePlatform)) { + return null; + } + let value = mediaPlatformAttributes.platformAttributeAsBoolean(data, attributePlatform, attributePath, policy); + if (serverData.isNull(value)) { + value = mediaAttributes.attributeAsBoolean(data, attributePath, policy); + } + return value; +} +/** + * Retrieve the specified attribute from the data as a boolean, which will be `false` if the attribute does not exist. + * + * @param data The data from which to retrieve the attribute. + * @param attributePath The path of the attribute. + * @param attributePlatform The specific platform attribute to get content for. Omit to infer from the data's structure. + * @returns {boolean} The attribute value as a boolean, coercing to `false` if the value is not present.. + */ +export function contentAttributeAsBooleanOrFalse(objectGraph, data, attributePath, attributePlatform) { + if (!attributePlatform) { + attributePlatform = bestAttributePlatformFromData(objectGraph, data); + } + if (isNothing(attributePlatform)) { + return false; + } + let value = mediaPlatformAttributes.platformAttributeAsBoolean(data, attributePlatform, attributePath); + if (serverData.isNull(value)) { + value = mediaAttributes.attributeAsBooleanOrFalse(data, attributePath); + } + return value; +} +/** + * Retrieve the specified attribute from the data as a number. + * + * @param data The data from which to retrieve the attribute. + * @param attributePath The path of the attribute. + * @param policy The validation policy to use when resolving this value. + * @returns {boolean} The attribute value as a number. + */ +export function contentAttributeAsNumber(objectGraph, data, attributePath, policy = "coercible") { + const attributePlatform = bestAttributePlatformFromData(objectGraph, data); + if (isNothing(attributePlatform)) { + return null; + } + let value = mediaPlatformAttributes.platformAttributeAsNumber(data, attributePlatform, attributePath, policy); + if (serverData.isNull(value)) { + value = mediaAttributes.attributeAsNumber(data, attributePath); + } + return value; +} +/** + * Computes the best attribute platform for a given piece of content + * + * @param {Data} data The media API data representing the content + * @returns {AttributePlatform} + */ +export function bestAttributePlatformFromData(objectGraph, data, clientIdentifierOverride) { + const baseCacheKey = "bestAttributePlatformFromData"; + const cacheKey = isSome(clientIdentifierOverride) ? `${baseCacheKey}.${clientIdentifierOverride}` : baseCacheKey; + return derivedData.value(data, cacheKey, () => { + const isIOSOnly = contentDeviceFamily.dataOnlyHasDeviceFamilies(objectGraph, data, ["iphone", "ipad", "ipod"], true); + const isTvOnly = contentDeviceFamily.dataOnlyHasDeviceFamily(objectGraph, data, "tvos"); + const isMacOnly = contentDeviceFamily.dataOnlyHasDeviceFamily(objectGraph, data, "mac"); + const isWatchOnly = contentDeviceFamily.dataOnlyHasDeviceFamily(objectGraph, data, "watch"); + const isVisionOnly = contentDeviceFamily.dataOnlyHasDeviceFamily(objectGraph, data, "realityDevice"); + // 1. The data is for a single platform only. + let dedicatedPlatform = null; + if (isTvOnly) { + dedicatedPlatform = "appletvos"; + } + else if (isMacOnly) { + dedicatedPlatform = "osx"; + } + else if (isIOSOnly) { + dedicatedPlatform = "ios"; + } + else if (isWatchOnly) { + dedicatedPlatform = "watch"; + } + else if (isVisionOnly) { + dedicatedPlatform = "xros"; + } + if (!serverData.isNull(dedicatedPlatform)) { + return dedicatedPlatform; + } + // 2. Loop through our preferred ordering of platforms and use the first one that has platformAttributes present. + const alternatePlatforms = defaultAttributePlatformOrdering(objectGraph, clientIdentifierOverride); + for (const candidatePlatform of alternatePlatforms) { + if (mediaPlatformAttributes.hasPlatformAttribute(data, candidatePlatform)) { + return candidatePlatform; + } + } + // 3. Catch-All + return defaultAttributePlatform(objectGraph); + }); +} +/** + * Computes the best attribute platform for a given Media API Marketplace + * response. Since Marketplace responses don't contain a top-level + * `deviceFamilies` property, this employs an alternative method from + * `bestAttributePlatformFromData()` to get the attribute platform. + * + * @param objectGraph The App Store object graph + * @param data The Media API Marketplace response to search for an attribute platform. + * @returns The most appropriate attribute platform available for the current client. + */ +export function bestAttributePlatformFromMarketplaceData(objectGraph, data) { + // 1. Iterate through the client's preferred platform ordering until we + // find the first one present in the response. + const preferredAttributePlatforms = defaultAttributePlatformOrdering(objectGraph); + for (const attributePlatform of preferredAttributePlatforms) { + const versionsAttributes = contentAttributeAsDictionary(objectGraph, data, "versionAttributes", attributePlatform); + if (serverData.isDefinedNonNullNonEmpty(versionsAttributes)) { + return attributePlatform; + } + } + // 2. Catch-All + return defaultAttributePlatform(objectGraph); +} +/** + * The default attribute platform for the current client + */ +export function defaultAttributePlatform(objectGraph) { + var _a; + if ((_a = objectGraph.activeIntent) === null || _a === void 0 ? void 0 : _a.attributePlatform) { + return objectGraph.activeIntent.attributePlatform; + } + switch (objectGraph.client.deviceType) { + case "phone": + case "pad": + return "ios"; + case "tv": + return "appletvos"; + case "mac": + return "osx"; + case "watch": + return "watch"; + case "vision": + return "xros"; + default: + return null; + } +} +/** + * The preferred ordering to use given our default platform. + */ +function defaultAttributePlatformOrdering(objectGraph, clientIdentifierOverride) { + const defaultPlatform = defaultAttributePlatform(objectGraph); + if (defaultPlatform === null) { + // If the `"web"` client is active and there is not an "active intent" to + // inform a default platform, fall back to a hard-coded ordering + if (objectGraph.client.isWeb) { + return ["ios", "osx", "xros", "watch", "appletvos"]; + } + else { + return []; + } + } + switch (defaultPlatform) { + case "ios": + if (clientIdentifierOverride === "VisionAppStore" /* ClientIdentifier.VisionAppStore */ || + clientIdentifierOverride === "com.apple.visionproapp" /* ClientIdentifier.VisionCompanion */) { + return ["xros", "ios", "appletvos", "osx"]; + } + else { + return ["ios", "appletvos", "osx", "xros"]; + } + case "osx": + return ["osx", "ios", "appletvos", "xros"]; + case "appletvos": + return ["appletvos", "ios", "osx", "xros"]; + case "watch": + // Per Hiren Kotadia on 2019-2-26, watch platform attributes will always be under ios. + // We're going to promote ios to the head of the search list to speed up Media API + // response parsing. We'll keep watch as #2 in the list so that if this changes in + // the future, it should mostly just work. -km + return ["ios", "watch", "osx", "xros"]; + case "xros": + return ["xros", "ios", "appletvos", "osx"]; + default: + return [defaultPlatform]; + } +} +// region Variant Attributes +/** + * Retrieve the attribute for a specific platform's variant attribute as a dictionary, from custom attributes or standard attributes. + * @param data Data to get attribute for. + * @param productVariantData Variant data to use when finding item. + * @param attributeKey The key to fetch in platform attributes. May be converted to custom attribute key. + * @param attributePlatform The platform to fetch attribute for. Defaults to current platform if unspecified. + */ +export function customAttributeAsDictionary(objectGraph, data, productVariantData, attributeKey, attributePlatform) { + // Use `customAttributes.${customAttributeKey}` for platform if present + const customAttributeKey = mediaAttributes.attributeKeyAsCustomAttributeKey(attributeKey); + if (isNothing(customAttributeKey)) { + return null; + } + const customAttributes = contentAttributeAsDictionary(objectGraph, data, "customAttributes", attributePlatform); + const allowNondefaultTreatmentInNondefaultPage = mediaAttributes.attributeAllowsNonDefaultTreatmentInNonDefaultPage(customAttributeKey); + const customAttribute = variantAttributeForKey(objectGraph, customAttributes, productVariantData, customAttributeKey, allowNondefaultTreatmentInNondefaultPage); + if (serverData.isDefinedNonNullNonEmpty(customAttribute)) { + return serverData.asDictionary(customAttribute); + } + // Otherwise, use `${attributeKey}` for platform. + return contentAttributeAsDictionary(objectGraph, data, attributeKey, attributePlatform); +} +/** + * Retrieve the attribute for a specific platform's variant attribute as a dictionary, from custom attributes or standard attributes. + * @param data Data to get attribute for. + * @param productVariantData Variant data to use when finding item. + * @param attributeKey The key to fetch in platform attributes when custom attributes are not present. + * @param attributePlatform The platform to fetch attribute for. Defaults to current platform if unspecified. + */ +export function customAttributeAsString(objectGraph, data, productVariantData, attributeKey, attributePlatform) { + // Use `customAttributes.${customAttributeKey}` for platform if present + const customAttributeKey = mediaAttributes.attributeKeyAsCustomAttributeKey(attributeKey); + if (isNothing(customAttributeKey)) { + return null; + } + const customAttributes = contentAttributeAsDictionary(objectGraph, data, "customAttributes", attributePlatform); + const allowNondefaultTreatmentInNondefaultPage = mediaAttributes.attributeAllowsNonDefaultTreatmentInNonDefaultPage(customAttributeKey); + const customAttribute = variantAttributeForKey(objectGraph, customAttributes, productVariantData, customAttributeKey, allowNondefaultTreatmentInNondefaultPage); + if (serverData.isDefinedNonNullNonEmpty(customAttribute)) { + return serverData.asString(customAttribute); + } + // Otherwise, use `${attributeKey}` for platform. + return contentAttributeAsString(objectGraph, data, attributeKey); +} +// endregion +//# sourceMappingURL=attributes.js.map \ No newline at end of file -- cgit v1.2.3