UNPKG

cordova-plugin-qonversion

Version:
1,182 lines (1,036 loc) 39.2 kB
import { AutomationsEventType, EntitlementRenewState, EntitlementSource, ExperimentGroupType, IntroEligibilityStatus, OfferingTag, PricingPhaseRecurrenceMode, PricingPhaseType, SubscriptionPeriodUnit, ProductType, RemoteConfigurationAssignmentType, RemoteConfigurationSourceType, SKPeriodUnit, SKProductDiscountPaymentMode, SKProductDiscountType, UserPropertyKey, TransactionType, TransactionOwnershipType, TransactionEnvironment, EntitlementGrantType, QonversionErrorCode } from "./enums"; import {IntroEligibility} from "./IntroEligibility"; import {Offering} from "./Offering"; import {Offerings} from "./Offerings"; import {Entitlement} from "./Entitlement"; import {Product} from "./Product"; import {SKProduct} from "./SKProduct"; import {SKProductDiscount} from "./SKProductDiscount"; import {SKSubscriptionPeriod} from "./SKSubscriptionPeriod"; import {SkuDetails} from "./SkuDetails"; import {ActionResult} from "./ActionResult"; import {QonversionError} from "./QonversionError"; import {AutomationsEvent} from "./AutomationsEvent"; import {User} from './User'; import {Experiment} from "./Experiment"; import {ExperimentGroup} from "./ExperimentGroup"; import {SubscriptionPeriod} from "./SubscriptionPeriod"; import {RemoteConfig} from "./RemoteConfig"; import {RemoteConfigList} from "./RemoteConfigList"; import {UserProperties} from './UserProperties'; import {UserProperty} from './UserProperty'; import {RemoteConfigurationSource} from "./RemoteConfigurationSource"; import {Transaction} from "./Transaction"; import {ProductStoreDetails} from "./ProductStoreDetails"; import {ProductOfferDetails} from "./ProductOfferDetails"; import {ProductInAppDetails} from "./ProductInAppDetails"; import {ProductPrice} from "./ProductPrice"; import {ProductPricingPhase} from "./ProductPricingPhase"; import {ProductInstallmentPlanDetails} from "./ProductInstallmentPlanDetails"; import {ScreenPresentationConfig} from './ScreenPresentationConfig'; import {SKPaymentDiscount} from './SKPaymentDiscount'; import {PromotionalOffer} from './PromotionalOffer'; export type QProduct = { id: string; storeId: string; basePlanId?: string | null; type: string; subscriptionPeriod?: QSubscriptionPeriod | null; trialPeriod?: QSubscriptionPeriod | null; skuDetails?: QSkuDetails | null; // android storeDetails?: QProductStoreDetails // android skProduct?: QSKProduct | null // iOS prettyPrice?: string | null; offeringId?: string | null; }; type QProductStoreDetails = { basePlanId?: string | null, productId: string, name: string, title: string description: string, subscriptionOfferDetails?: QProductOfferDetails[] | null, defaultSubscriptionOfferDetails?: QProductOfferDetails | null, basePlanSubscriptionOfferDetails?: QProductOfferDetails | null, inAppOfferDetails?: QProductInAppDetails | null, hasTrialOffer: boolean, hasIntroOffer: boolean, hasTrialOrIntroOffer: boolean, productType: string, isInApp: boolean, isSubscription: boolean, isPrepaid: boolean, isInstallment: boolean, } type QSubscriptionPeriod = { unitCount: number, unit: string, iso: string, } type QProductPricingPhase = { price: QProductPrice, billingPeriod: QSubscriptionPeriod, billingCycleCount: number, recurrenceMode: string, type: string isTrial: boolean, isIntro: boolean, isBasePlan: boolean, } type QProductInstallmentPlanDetails = { commitmentPaymentsCount: number; subsequentCommitmentPaymentsCount: number; } type QProductOfferDetails = { basePlanId: string, offerId?: string | null, offerToken: string, tags: string[], pricingPhases: QProductPricingPhase[], basePlan?: QProductPricingPhase | null, installmentPlanDetails?: QProductInstallmentPlanDetails | null, trialPhase?: QProductPricingPhase | null, introPhase: QProductPricingPhase | null, hasTrial: boolean, hasIntro: boolean, hasTrialOrIntro: boolean, } type QProductPrice = { priceAmountMicros: number, priceCurrencyCode: string, formattedPrice: string, isFree: boolean, currencySymbol: string, } type QProductInAppDetails = { price: QProductPrice, } type QSkuDetails = { description: string; freeTrialPeriod: string; iconUrl: string; introductoryPrice: string; introductoryPriceAmountMicros: number; introductoryPriceCycles: number; introductoryPricePeriod: string; originalJson: string; originalPrice: string; originalPriceAmountMicros: number; price: string; priceAmountMicros: number; priceCurrencyCode: string; sku: string; subscriptionPeriod: string; title: string; type: string; hashCode: number; toString: string; }; type QSKProduct = { subscriptionPeriod: null | QSKSubscriptionPeriod; introductoryPrice: QProductDiscount | null; discounts: Array<QProductDiscount> | null; localizedDescription: string | undefined; localizedTitle: string | undefined; price: string; priceLocale: QLocale; productIdentifier: string | undefined; isDownloadable: boolean | undefined; downloadContentVersion: string | undefined; downloadContentLengths: number[] | undefined; productDiscount: SKProductDiscount | undefined; subscriptionGroupIdentifier: string | undefined; isFamilyShareable: boolean | undefined; }; type QSKSubscriptionPeriod = { numberOfUnits: number; unit: keyof typeof SKPeriodUnit; }; export type QPromotionalOffer = { productDiscount: QProductDiscount, paymentDiscount: QPaymentDiscount, } type QPaymentDiscount = { identifier: string; keyIdentifier: string; nonce: string; signature: string; timestamp: number; }; type QProductDiscount = { subscriptionPeriod: null | QSKSubscriptionPeriod; price: string; numberOfPeriods: number; paymentMode: keyof typeof SKProductDiscountPaymentMode; identifier?: string; type: keyof typeof SKProductDiscountType; priceLocale: QLocale; }; type QLocale = { currencySymbol: string | null; currencyCode: string | null; localeIdentifier: string; }; export type QEntitlement = { id: string; productId: string; active: boolean; renewState: string; source: string; startedTimestamp: number; expirationTimestamp: number; renewsCount: number; trialStartTimestamp: number; firstPurchaseTimestamp: number; lastPurchaseTimestamp: number; lastActivatedOfferCode: string; grantType: string; autoRenewDisableTimestamp: number; transactions: Array<QTransaction>; }; export type QTransaction = { originalTransactionId: string; transactionId: string; offerCode: string; transactionTimestamp: number; expirationTimestamp: number; transactionRevocationTimestamp: number; environment: string; ownershipType: string; type: string; promoOfferId: string; } export type QOfferings = { availableOfferings?: Array<QOffering>; main: QOffering; }; type QOffering = { id: string; tag: keyof typeof OfferingTag; products: Array<QProduct>; }; export type QTrialIntroEligibility = { status: | "non_intro_or_trial_product" | "intro_or_trial_eligible" | "intro_or_trial_ineligible"; }; type QAutomationsEvent = { type: AutomationsEventType; timestamp: number; }; export type QEmptySuccessResult = { success: boolean; }; export type QUser = { qonversionId: string; identityId?: string | null; }; export type QRemoteConfig = { payload: Record<string, Object>; experiment?: QExperiment | null; source: QRemoteConfigurationSource; }; export type QRemoteConfigList = { remoteConfigs: Array<QRemoteConfig>; } type QRemoteConfigurationSource = { id: string; name: string; type: string; assignmentType: string; contextKey: string | null | undefined; }; type QExperiment = { id: string; name: string; group: QExperimentGroup; } type QExperimentGroup = { id: string; name: string; type: string; } type QUserProperty = { key: string; value: string; }; export type QUserProperties = { properties: QUserProperty[]; }; export type QAutomationEvent = { event: string; payload: Record<string, any>; }; const priceMicrosRatio = 1000000; class Mapper { static convertPromoOffer( promoOffer: QPromotionalOffer | null | undefined ): PromotionalOffer | null { if (!promoOffer) { return null; } const productDiscount = this.convertProductDiscount(promoOffer.productDiscount); const paymentDiscount = this.convertPaymentDiscount(promoOffer.paymentDiscount); return new PromotionalOffer(productDiscount, paymentDiscount); } static convertEntitlements( entitlements: Record<string, QEntitlement> | null | undefined ): Map<string, Entitlement> { let mappedPermissions = new Map(); if (!entitlements) { return mappedPermissions; } for (const key of Object.keys(entitlements)) { const entitlement = entitlements[key]; let renewState: EntitlementRenewState; switch (entitlement.renewState) { case EntitlementRenewState.NON_RENEWABLE: renewState = EntitlementRenewState.NON_RENEWABLE; break; case EntitlementRenewState.WILL_RENEW: renewState = EntitlementRenewState.WILL_RENEW; break; case EntitlementRenewState.CANCELED: renewState = EntitlementRenewState.CANCELED; break; case EntitlementRenewState.BILLING_ISSUE: renewState = EntitlementRenewState.BILLING_ISSUE; break; default: renewState = EntitlementRenewState.UNKNOWN; break; } const entitlementSource = this.convertEntitlementSource(entitlement.source); const entitlementGrantType = this.convertEntitlementGrantType(entitlement.grantType); const transactions: Array<Transaction> = []; if (Array.isArray(entitlement.transactions)) { entitlement.transactions.forEach((transaction) => { const mappedTransaction = this.convertTransaction(transaction); transactions.push(mappedTransaction); }); } const mappedPermission = new Entitlement( entitlement.id, entitlement.productId, entitlement.active, renewState, entitlementSource, entitlement.startedTimestamp, entitlement.renewsCount, entitlementGrantType, transactions, entitlement.expirationTimestamp, entitlement.trialStartTimestamp, entitlement.firstPurchaseTimestamp, entitlement.lastPurchaseTimestamp, entitlement.autoRenewDisableTimestamp, entitlement.lastActivatedOfferCode, ); mappedPermissions.set(key, mappedPermission); } return mappedPermissions; } static convertTransaction(transaction: QTransaction): Transaction { const environment = this.convertTransactionEnvironment(transaction.environment); const ownershipType = this.convertTransactionOwnershipType(transaction.ownershipType); const type = this.convertTransactionType(transaction.type); return new Transaction( transaction.originalTransactionId, transaction.transactionId, transaction.transactionTimestamp, environment, ownershipType, type, transaction.expirationTimestamp, transaction.transactionRevocationTimestamp, transaction.offerCode, transaction.promoOfferId, ); } static convertTransactionType(typeKey: string): TransactionType { switch (typeKey) { case "SubscriptionStarted": return TransactionType.SUBSCRIPTION_STARTED; case "SubscriptionRenewed": return TransactionType.SUBSCRIPTION_RENEWED; case "TrialStarted": return TransactionType.TRIAL_STARTED; case "IntroStarted": return TransactionType.INTRO_STARTED; case "IntroRenewed": return TransactionType.INTRO_RENEWED; case "NonConsumablePurchase": return TransactionType.NON_CONSUMABLE_PURCHASE; } return TransactionType.UNKNOWN; } static convertTransactionOwnershipType(ownershipTypeKey: string): TransactionOwnershipType { switch (ownershipTypeKey) { case "Owner": return TransactionOwnershipType.OWNER; case "FamilySharing": return TransactionOwnershipType.FAMILY_SHARING; } return TransactionOwnershipType.OWNER; } static convertTransactionEnvironment(envKey: string): TransactionEnvironment { switch (envKey) { case "Production": return TransactionEnvironment.PRODUCTION; case "Sandbox": return TransactionEnvironment.SANDBOX; } return TransactionEnvironment.PRODUCTION; } static convertEntitlementSource(sourceKey: string): EntitlementSource { switch (sourceKey) { case "Unknown": return EntitlementSource.UNKNOWN; case "AppStore": return EntitlementSource.APP_STORE; case "PlayStore": return EntitlementSource.PLAY_STORE; case "Stripe": return EntitlementSource.STRIPE; case "Manual": return EntitlementSource.MANUAL; } return EntitlementSource.UNKNOWN; } static convertEntitlementGrantType(typeKey: string): EntitlementGrantType { switch (typeKey) { case "Purchase": return EntitlementGrantType.PURCHASE; case "FamilySharing": return EntitlementGrantType.FAMILY_SHARING; case "OfferCode": return EntitlementGrantType.OFFER_CODE; case "Manual": return EntitlementGrantType.MANUAL; } return EntitlementGrantType.PURCHASE; } static convertDefinedUserPropertyKey(sourceKey: string): UserPropertyKey { switch (sourceKey) { case '_q_email': return UserPropertyKey.EMAIL; case '_q_name': return UserPropertyKey.NAME; case '_q_kochava_device_id': return UserPropertyKey.KOCHAVA_DEVICE_ID; case '_q_appsflyer_user_id': return UserPropertyKey.APPS_FLYER_USER_ID; case '_q_adjust_adid': return UserPropertyKey.ADJUST_AD_ID; case '_q_custom_user_id': return UserPropertyKey.CUSTOM_USER_ID; case '_q_fb_attribution': return UserPropertyKey.FACEBOOK_ATTRIBUTION; case '_q_firebase_instance_id': return UserPropertyKey.FIREBASE_APP_INSTANCE_ID; case '_q_app_set_id': return UserPropertyKey.APP_SET_ID; case '_q_advertising_id': return UserPropertyKey.ADVERTISING_ID; case "_q_appmetrica_device_id": return UserPropertyKey.APP_METRICA_DEVICE_ID; case "_q_appmetrica_user_profile_id": return UserPropertyKey.APP_METRICA_USER_PROFILE_ID; case "_q_pushwoosh_hwid": return UserPropertyKey.PUSH_WOOSH_HW_ID; case "_q_pushwoosh_user_id": return UserPropertyKey.PUSH_WOOSH_USER_ID; case "_q_tenjin_aiid": return UserPropertyKey.TENJIN_ANALYTICS_INSTALLATION_ID; } return UserPropertyKey.CUSTOM; } static convertUserProperties(properties: QUserProperties): UserProperties { const mappedProperties = properties.properties.map(propertyData => { const definedKey = Mapper.convertDefinedUserPropertyKey(propertyData.key); return new UserProperty(propertyData.key, propertyData.value, definedKey); }); return new UserProperties(mappedProperties); } static convertProducts(products: Record<string, QProduct> | null | undefined): Map<string, Product> { let mappedProducts = new Map(); if (!products) { return mappedProducts; } for (const key of Object.keys(products)) { const product = products[key]; const mappedProduct = this.convertProduct(product); mappedProducts.set(key, mappedProduct); } return mappedProducts; } static convertProduct(product: QProduct): Product { const productType = Mapper.convertProductType(product.type); const subscriptionPeriod: SubscriptionPeriod | null = Mapper.convertSubscriptionPeriod(product.subscriptionPeriod); const trialPeriod: SubscriptionPeriod | null = Mapper.convertSubscriptionPeriod(product.trialPeriod); const offeringId: string | null = product.offeringId ?? null; let skProduct: SKProduct | null = null; let skuDetails: SkuDetails | null = null; let storeDetails: ProductStoreDetails | null = null; let price: number | undefined; let currencyCode: string | undefined; let storeTitle: string | undefined; let storeDescription: string | undefined; let prettyIntroductoryPrice: string | undefined; if (!!product.skProduct) { skProduct = Mapper.convertSKProduct(product.skProduct as QSKProduct); price = parseFloat(skProduct.price); currencyCode = skProduct.currencyCode; storeTitle = skProduct.localizedTitle; storeDescription = skProduct.localizedDescription; if (skProduct.productDiscount) { prettyIntroductoryPrice = skProduct.productDiscount.currencySymbol + skProduct.productDiscount.price; } } else { let priceMicros = null if (!!product.skuDetails) { skuDetails = Mapper.convertSkuDetails(product.skuDetails as QSkuDetails); storeTitle = skuDetails.title; storeDescription = skuDetails.description; priceMicros = skuDetails.priceAmountMicros; currencyCode = skuDetails.priceCurrencyCode; if (skuDetails.introductoryPrice.length > 0) { prettyIntroductoryPrice = skuDetails.introductoryPrice; } } if (!!product.storeDetails) { storeDetails = Mapper.convertProductStoreDetails(product.storeDetails); storeTitle = storeDetails.title; storeDescription = storeDetails.description; const defaultOffer = storeDetails.defaultSubscriptionOfferDetails; const inAppOffer = storeDetails.inAppOfferDetails; if (defaultOffer) { priceMicros = defaultOffer.basePlan?.price?.priceAmountMicros; currencyCode = defaultOffer.basePlan?.price?.priceCurrencyCode; prettyIntroductoryPrice = defaultOffer.introPhase?.price?.formattedPrice; } else if (inAppOffer) { priceMicros = inAppOffer.price.priceAmountMicros; currencyCode = inAppOffer.price.priceCurrencyCode; prettyIntroductoryPrice = undefined; } } price = priceMicros ? priceMicros / priceMicrosRatio : undefined; } // noinspection UnnecessaryLocalVariableJS const mappedProduct = new Product( product.id, product.storeId, product.basePlanId ?? null, skuDetails, storeDetails, skProduct, offeringId, subscriptionPeriod, trialPeriod, productType, product.prettyPrice ?? null, price, currencyCode, storeTitle, storeDescription, prettyIntroductoryPrice, ); return mappedProduct; } static convertOfferings(offerings: QOfferings | null | undefined): Offerings | null { if (!offerings) { return null; } if ( !Array.isArray(offerings.availableOfferings) || offerings.availableOfferings.length === 0 ) { return null; } let mainOffering: Offering | null = null; if (offerings.main) { mainOffering = this.convertOffering(offerings.main); } const availableOfferings: Array<Offering> = []; offerings.availableOfferings.forEach((offering) => { const mappedOffering = this.convertOffering(offering); availableOfferings.push(mappedOffering); }); return new Offerings(mainOffering, availableOfferings); } static convertOffering(offering: QOffering): Offering { const products: Array<Product> = []; offering.products.forEach((product) => { const mappedProduct = this.convertProduct(product); products.push(mappedProduct); }); const tag = OfferingTag[offering.tag] ?? OfferingTag['0']; return new Offering(offering.id, tag, products); } static convertSkuDetails(skuDetails: QSkuDetails): SkuDetails { return new SkuDetails( skuDetails.description, skuDetails.freeTrialPeriod, skuDetails.iconUrl, skuDetails.introductoryPrice, skuDetails.introductoryPriceAmountMicros, skuDetails.introductoryPriceCycles, skuDetails.introductoryPricePeriod, skuDetails.originalJson, skuDetails.originalPrice, skuDetails.originalPriceAmountMicros, skuDetails.price, skuDetails.priceAmountMicros, skuDetails.priceCurrencyCode, skuDetails.sku, skuDetails.subscriptionPeriod, skuDetails.title, skuDetails.type, skuDetails.hashCode, skuDetails.toString ); } static convertProductType(productType: string): ProductType { let type = ProductType.UNKNOWN switch (productType) { case ProductType.TRIAL: type = ProductType.TRIAL; break; case ProductType.INTRO: type = ProductType.INTRO; break; case ProductType.SUBSCRIPTION: type = ProductType.SUBSCRIPTION; break; case ProductType.IN_APP: type = ProductType.IN_APP; break; } return type; } static convertSubscriptionPeriod(productPeriod: QSubscriptionPeriod | null | undefined): SubscriptionPeriod | null { if (!productPeriod) { return null; } const unit = Mapper.convertSubscriptionPeriodUnit(productPeriod.unit); return new SubscriptionPeriod( productPeriod.unitCount, unit, productPeriod.iso, ) } static convertSubscriptionPeriodUnit(unit: string): SubscriptionPeriodUnit { let result: SubscriptionPeriodUnit = SubscriptionPeriodUnit.UNKNOWN; switch (unit) { case SubscriptionPeriodUnit.DAY: result = SubscriptionPeriodUnit.DAY; break; case SubscriptionPeriodUnit.WEEK: result = SubscriptionPeriodUnit.WEEK; break; case SubscriptionPeriodUnit.MONTH: result = SubscriptionPeriodUnit.MONTH; break; case SubscriptionPeriodUnit.YEAR: result = SubscriptionPeriodUnit.YEAR; break; } return result; } static convertProductPricingPhase(pricingPhase: QProductPricingPhase | null | undefined): ProductPricingPhase | null { if (!pricingPhase) { return null; } const price: ProductPrice = Mapper.convertProductPrice(pricingPhase.price); const billingPeriod = Mapper.convertSubscriptionPeriod(pricingPhase.billingPeriod)!!; const recurrenceMode = Mapper.convertPrisingPhaseRecurrenceMode(pricingPhase.recurrenceMode); const type = Mapper.convertPrisingPhaseType(pricingPhase.type); return new ProductPricingPhase( price, billingPeriod, pricingPhase.billingCycleCount, recurrenceMode, type, pricingPhase.isTrial, pricingPhase.isIntro, pricingPhase.isBasePlan, ); } static convertPrisingPhaseRecurrenceMode(recurrenceMode: string): PricingPhaseRecurrenceMode { let mode: PricingPhaseRecurrenceMode = PricingPhaseRecurrenceMode.UNKNOWN; switch (recurrenceMode) { case PricingPhaseRecurrenceMode.INFINITE_RECURRING: mode = PricingPhaseRecurrenceMode.INFINITE_RECURRING; break; case PricingPhaseRecurrenceMode.FINITE_RECURRING: mode = PricingPhaseRecurrenceMode.FINITE_RECURRING; break; case PricingPhaseRecurrenceMode.NON_RECURRING: mode = PricingPhaseRecurrenceMode.NON_RECURRING; break; } return mode; } static convertPrisingPhaseType(type: string): PricingPhaseType { let result: PricingPhaseType = PricingPhaseType.UNKNOWN switch (type) { case PricingPhaseType.REGULAR: result = PricingPhaseType.REGULAR; break; case PricingPhaseType.FREE_TRIAL: result = PricingPhaseType.FREE_TRIAL; break; case PricingPhaseType.DISCOUNTED_SINGLE_PAYMENT: result = PricingPhaseType.DISCOUNTED_SINGLE_PAYMENT; break; case PricingPhaseType.DISCOUNTED_RECURRING_PAYMENT: result = PricingPhaseType.DISCOUNTED_RECURRING_PAYMENT; break; } return result; } static convertProductInstallmentPlanDetails(installmentPlanDetails: QProductInstallmentPlanDetails | null | undefined): ProductInstallmentPlanDetails | null { if (!installmentPlanDetails) { return null; } return new ProductInstallmentPlanDetails( installmentPlanDetails.commitmentPaymentsCount, installmentPlanDetails.subsequentCommitmentPaymentsCount, ); } static convertProductOfferDetails(offerDetails: QProductOfferDetails): ProductOfferDetails { let basePlan = Mapper.convertProductPricingPhase(offerDetails.basePlan); let trialPhase = Mapper.convertProductPricingPhase(offerDetails.trialPhase); let introPhase = Mapper.convertProductPricingPhase(offerDetails.introPhase); let installmentPlanDetails = Mapper.convertProductInstallmentPlanDetails(offerDetails.installmentPlanDetails); let pricingPhases = offerDetails.pricingPhases.map( pricingPhase => Mapper.convertProductPricingPhase(pricingPhase) ).filter(Boolean) as ProductPricingPhase[]; return new ProductOfferDetails( offerDetails.basePlanId, offerDetails.offerId ?? null, offerDetails.offerToken, offerDetails.tags, pricingPhases, basePlan, installmentPlanDetails, introPhase, trialPhase, offerDetails.hasTrial, offerDetails.hasIntro, offerDetails.hasTrialOrIntro, ); } static convertInAppOfferDetails(inAppOfferDetails: QProductInAppDetails): ProductInAppDetails { let productPrice: ProductPrice = this.convertProductPrice(inAppOfferDetails.price); return new ProductInAppDetails(productPrice); } static convertProductPrice(productPrice: QProductPrice): ProductPrice { return new ProductPrice( productPrice.priceAmountMicros, productPrice.priceCurrencyCode, productPrice.formattedPrice, productPrice.isFree, productPrice.currencySymbol, ) } static convertProductStoreDetails(productStoreDetails: QProductStoreDetails): ProductStoreDetails { let defaultSubscriptionOfferDetails: ProductOfferDetails | null = null; if (productStoreDetails.defaultSubscriptionOfferDetails != null) { defaultSubscriptionOfferDetails = this.convertProductOfferDetails( productStoreDetails.defaultSubscriptionOfferDetails ); } let basePlanSubscriptionOfferDetails: ProductOfferDetails | null = null; if (productStoreDetails.basePlanSubscriptionOfferDetails != null) { basePlanSubscriptionOfferDetails = this.convertProductOfferDetails( productStoreDetails.basePlanSubscriptionOfferDetails ); } let inAppOfferDetails: ProductInAppDetails | null = null; if (productStoreDetails.inAppOfferDetails != null) { inAppOfferDetails = this.convertInAppOfferDetails(productStoreDetails.inAppOfferDetails); } let subscriptionOfferDetails: ProductOfferDetails[] | null = null; if (productStoreDetails.subscriptionOfferDetails != null) { subscriptionOfferDetails = productStoreDetails.subscriptionOfferDetails.map( defaultOfferDetail => this.convertProductOfferDetails(defaultOfferDetail)); } const productType: ProductType = Mapper.convertProductType(productStoreDetails.productType); return new ProductStoreDetails( productStoreDetails.basePlanId ?? null, productStoreDetails.productId, productStoreDetails.name, productStoreDetails.title, productStoreDetails.description, subscriptionOfferDetails, defaultSubscriptionOfferDetails, basePlanSubscriptionOfferDetails, inAppOfferDetails, productStoreDetails.hasTrialOffer, productStoreDetails.hasIntroOffer, productStoreDetails.hasTrialOrIntroOffer, productType, productStoreDetails.isInApp, productStoreDetails.isSubscription, productStoreDetails.isPrepaid, productStoreDetails.isInstallment, ); } static convertSKProduct(skProduct: QSKProduct): SKProduct { let subscriptionPeriod: SKSubscriptionPeriod | undefined; if (skProduct.subscriptionPeriod != null) { subscriptionPeriod = this.convertSKSubscriptionPeriod( skProduct.subscriptionPeriod ); } let discount: SKProductDiscount | undefined; if (skProduct.introductoryPrice) { discount = this.convertProductDiscount(skProduct.introductoryPrice); } let discounts: SKProductDiscount[] | undefined; if (Array.isArray(skProduct.discounts) && skProduct.discounts.length) { discounts = this.convertDiscounts(skProduct.discounts); } return new SKProduct( skProduct.localizedDescription, skProduct.localizedTitle, skProduct.price, skProduct.priceLocale.localeIdentifier, skProduct.productIdentifier, !!skProduct.isDownloadable, skProduct.downloadContentVersion, skProduct.downloadContentLengths, subscriptionPeriod, discount, discounts, skProduct.subscriptionGroupIdentifier, skProduct.isFamilyShareable, skProduct.priceLocale.currencyCode ?? "" ); } static convertSKSubscriptionPeriod( subscriptionPeriod: QSKSubscriptionPeriod ): SKSubscriptionPeriod { return new SKSubscriptionPeriod( subscriptionPeriod.numberOfUnits, SKPeriodUnit[subscriptionPeriod.unit] ); } static convertPaymentDiscount(discount: QPaymentDiscount): SKPaymentDiscount { return new SKPaymentDiscount(discount.identifier, discount.keyIdentifier, discount.nonce, discount.signature, discount.timestamp) } static convertProductDiscount(discount: QProductDiscount): SKProductDiscount { let subscriptionPeriod: SKSubscriptionPeriod | undefined = undefined; if (discount.subscriptionPeriod != null) { subscriptionPeriod = this.convertSKSubscriptionPeriod( discount.subscriptionPeriod ); } return new SKProductDiscount( discount.price, discount.priceLocale.localeIdentifier, discount.numberOfPeriods, subscriptionPeriod, SKProductDiscountPaymentMode[discount.paymentMode], discount.identifier, SKProductDiscountType[discount.type], discount.priceLocale.currencySymbol ?? "" ); } static convertDiscounts( discounts: Array<QProductDiscount> ): SKProductDiscount[] { // noinspection UnnecessaryLocalVariableJS const mappedDiscounts: SKProductDiscount[] = discounts.map((discount) => { return this.convertProductDiscount(discount); }); return mappedDiscounts; } static convertEligibility( eligibilityMap: Record<string, QTrialIntroEligibility> | null | undefined ): Map<string, IntroEligibility> { let mappedEligibility = new Map<string, IntroEligibility>(); if (!eligibilityMap) { return mappedEligibility; } for (const key of Object.keys(eligibilityMap)) { const value = eligibilityMap[key]; const status = Mapper.convertEligibilityStatus(value.status); const eligibilityInfo = new IntroEligibility(status); mappedEligibility.set(key, eligibilityInfo); } return mappedEligibility; } static convertEligibilityStatus(status: string): IntroEligibilityStatus { switch (status) { case "non_intro_or_trial_product": return IntroEligibilityStatus.NON_INTRO_OR_TRIAL_PRODUCT; case "intro_or_trial_eligible": return IntroEligibilityStatus.ELIGIBLE; case "intro_or_trial_ineligible": return IntroEligibilityStatus.INELIGIBLE; default: return IntroEligibilityStatus.UNKNOWN; } } static convertActionResult( payload: Record<string, any> ): ActionResult { return new ActionResult( payload["type"], payload["value"], this.convertQonversionError(payload["error"]) ); } static convertQonversionError( payload: Record<string, string> | undefined ): QonversionError | undefined { if (!payload) return undefined; const code = this.convertErrorCode(payload["code"]); return new QonversionError( code, payload["description"], payload["additionalMessage"], payload["domain"], ); } static convertAutomationsEvent( automationsEvent: QAutomationsEvent ): AutomationsEvent { return new AutomationsEvent( automationsEvent.type, automationsEvent.timestamp ); } static convertUserInfo(user: QUser): User { return new User(user.qonversionId, user.identityId); } static convertRemoteConfig(remoteConfig: QRemoteConfig): RemoteConfig { let experiment = null; if (remoteConfig.experiment) { const groupType = this.convertGroupType(remoteConfig.experiment.group.type); const group = new ExperimentGroup(remoteConfig.experiment.group.id, remoteConfig.experiment.group.name, groupType); experiment = new Experiment(remoteConfig.experiment.id, remoteConfig.experiment.name, group); } const sourceType = this.convertRemoteConfigurationSourceType(remoteConfig.source.type); const assignmentType = this.convertRemoteConfigurationAssignmentType(remoteConfig.source.assignmentType); const source = new RemoteConfigurationSource( remoteConfig.source.id, remoteConfig.source.name, sourceType, assignmentType, remoteConfig.source.contextKey ?? null, ) return new RemoteConfig(remoteConfig.payload, experiment, source); } static convertRemoteConfigList(remoteConfigList: QRemoteConfigList): RemoteConfigList { const remoteConfigs = remoteConfigList.remoteConfigs.map(config => this.convertRemoteConfig(config)); return new RemoteConfigList(remoteConfigs); } static convertRemoteConfigurationSourceType(type: String): RemoteConfigurationSourceType { switch (type) { case "experiment_control_group": return RemoteConfigurationSourceType.EXPERIMENT_CONTROL_GROUP; case "experiment_treatment_group": return RemoteConfigurationSourceType.EXPERIMENT_TREATMENT_GROUP; case "remote_configuration": return RemoteConfigurationSourceType.REMOTE_CONFIGURATION; default: return RemoteConfigurationSourceType.UNKNOWN; } } static convertRemoteConfigurationAssignmentType(type: String): RemoteConfigurationAssignmentType { switch (type) { case "auto": return RemoteConfigurationAssignmentType.AUTO; case "manual": return RemoteConfigurationAssignmentType.MANUAL; default: return RemoteConfigurationAssignmentType.UNKNOWN; } } static convertGroupType(type: String): ExperimentGroupType { switch (type) { case "control": return ExperimentGroupType.CONTROL; case "treatment": return ExperimentGroupType.TREATMENT; default: return ExperimentGroupType.UNKNOWN; } } static convertScreenPresentationConfig(config: ScreenPresentationConfig): Object { return { presentationStyle: config.presentationStyle, animated: config.animated ? '1' : '0', }; } static convertErrorCode(code: string): QonversionErrorCode { switch (code) { case QonversionErrorCode.UNKNOWN: return QonversionErrorCode.UNKNOWN; case QonversionErrorCode.API_RATE_LIMIT_EXCEEDED: return QonversionErrorCode.API_RATE_LIMIT_EXCEEDED; case QonversionErrorCode.APPLE_STORE_ERROR: return QonversionErrorCode.APPLE_STORE_ERROR; case QonversionErrorCode.BACKEND_ERROR: return QonversionErrorCode.BACKEND_ERROR; case QonversionErrorCode.BILLING_UNAVAILABLE: return QonversionErrorCode.BILLING_UNAVAILABLE; case QonversionErrorCode.CLIENT_INVALID: return QonversionErrorCode.CLIENT_INVALID; case QonversionErrorCode.CLOUD_SERVICE_NETWORK_CONNECTION_FAILED: return QonversionErrorCode.CLOUD_SERVICE_NETWORK_CONNECTION_FAILED; case QonversionErrorCode.CLOUD_SERVICE_PERMISSION_DENIED: return QonversionErrorCode.CLOUD_SERVICE_PERMISSION_DENIED; case QonversionErrorCode.CLOUD_SERVICE_REVOKED: return QonversionErrorCode.CLOUD_SERVICE_REVOKED; case QonversionErrorCode.FAILED_TO_RECEIVE_DATA: return QonversionErrorCode.FAILED_TO_RECEIVE_DATA; case QonversionErrorCode.FEATURE_NOT_SUPPORTED: return QonversionErrorCode.FEATURE_NOT_SUPPORTED; case QonversionErrorCode.FRAUD_PURCHASE: return QonversionErrorCode.FRAUD_PURCHASE; case QonversionErrorCode.INCORRECT_REQUEST: return QonversionErrorCode.INCORRECT_REQUEST; case QonversionErrorCode.INTERNAL_ERROR: return QonversionErrorCode.INTERNAL_ERROR; case QonversionErrorCode.INVALID_CLIENT_UID: return QonversionErrorCode.INVALID_CLIENT_UID; case QonversionErrorCode.INVALID_CREDENTIALS: return QonversionErrorCode.INVALID_CREDENTIALS; case QonversionErrorCode.INVALID_STORE_CREDENTIALS: return QonversionErrorCode.INVALID_STORE_CREDENTIALS; case QonversionErrorCode.LAUNCH_ERROR: return QonversionErrorCode.LAUNCH_ERROR; case QonversionErrorCode.NETWORK_CONNECTION_FAILED: return QonversionErrorCode.NETWORK_CONNECTION_FAILED; case QonversionErrorCode.OFFERINGS_NOT_FOUND: return QonversionErrorCode.OFFERINGS_NOT_FOUND; case QonversionErrorCode.PAYMENT_INVALID: return QonversionErrorCode.PAYMENT_INVALID; case QonversionErrorCode.PAYMENT_NOT_ALLOWED: return QonversionErrorCode.PAYMENT_NOT_ALLOWED; case QonversionErrorCode.PLAY_STORE_ERROR: return QonversionErrorCode.PLAY_STORE_ERROR; case QonversionErrorCode.PRIVACY_ACKNOWLEDGEMENT_REQUIRED: return QonversionErrorCode.PRIVACY_ACKNOWLEDGEMENT_REQUIRED; case QonversionErrorCode.PRODUCT_ALREADY_OWNED: return QonversionErrorCode.PRODUCT_ALREADY_OWNED; case QonversionErrorCode.PRODUCT_NOT_FOUND: return QonversionErrorCode.PRODUCT_NOT_FOUND; case QonversionErrorCode.PRODUCT_NOT_OWNED: return QonversionErrorCode.PRODUCT_NOT_OWNED; case QonversionErrorCode.PROJECT_CONFIG_ERROR: return QonversionErrorCode.PROJECT_CONFIG_ERROR; case QonversionErrorCode.PURCHASE_CANCELED: return QonversionErrorCode.PURCHASE_CANCELED; case QonversionErrorCode.PURCHASE_INVALID: return QonversionErrorCode.PURCHASE_INVALID; case QonversionErrorCode.PURCHASE_PENDING: return QonversionErrorCode.PURCHASE_PENDING; case QonversionErrorCode.PURCHASE_UNSPECIFIED: return QonversionErrorCode.PURCHASE_UNSPECIFIED; case QonversionErrorCode.RECEIPT_VALIDATION_ERROR: return QonversionErrorCode.RECEIPT_VALIDATION_ERROR; case QonversionErrorCode.REMOTE_CONFIGURATION_NOT_AVAILABLE: return QonversionErrorCode.REMOTE_CONFIGURATION_NOT_AVAILABLE; case QonversionErrorCode.RESPONSE_PARSING_FAILED: return QonversionErrorCode.RESPONSE_PARSING_FAILED; case QonversionErrorCode.STORE_PRODUCT_NOT_AVAILABLE: return QonversionErrorCode.STORE_PRODUCT_NOT_AVAILABLE; case QonversionErrorCode.UNAUTHORIZED_REQUEST_DATA: return QonversionErrorCode.UNAUTHORIZED_REQUEST_DATA; case QonversionErrorCode.UNKNOWN_CLIENT_PLATFORM: return QonversionErrorCode.UNKNOWN_CLIENT_PLATFORM; } return QonversionErrorCode.UNKNOWN; } } export default Mapper;