// NOTE: Currently unused. Pro activation lives in the C# asar patch // (EPatchType.ActivatePro). This renderer-side variant patches the account service // prototype to inject the Pro subscription at the source. Kept for future use; // the entry `../activate-pro.js` is excluded from bridge/build.mjs. import { createLogger } from "../installed-apps-sync/logger.js" import { findExportedConstructor, getWebpackRequire, isRecord, } from "../installed-apps-sync/runtime.js" const GLOBAL_FLAG = "__wandActivateProInstalled" const SERVICE_PATCH_KEY = "__wandEnhancerProAccountServicePatched" const ACCOUNT_SERVICE_METHODS = [ "getUserAccount", "setAccountLanguage", "setAccountWandBrandExperience", ] const RETRY_DELAY_MS = 400 const MAX_ATTEMPTS = 90 const DEFAULT_SUBSCRIPTION = Object.freeze({ period: "yearly", state: "active" }) export function installActivatePro(WandEnhancer) { if (globalThis[GLOBAL_FLAG]) { return } globalThis[GLOBAL_FLAG] = true const state = { attempts: 0, log: createLogger(WandEnhancer), } state.log("info", "Activate Pro bootstrap starting.") retryBootstrap(state) } function retryBootstrap(state) { if (patchAccountService(state)) { return } state.attempts += 1 if (state.attempts < MAX_ATTEMPTS) { setTimeout(() => retryBootstrap(state), RETRY_DELAY_MS) return } state.log("error", "Activate Pro bootstrap exhausted; account service not found.") } function patchAccountService(state) { const webpackRequire = getWebpackRequire() if (!webpackRequire) { return false } const ctor = findExportedConstructor( webpackRequire, (prototype) => typeof prototype.getUserAccount === "function" && typeof prototype.setAccountLanguage === "function" && typeof prototype.setAccountWandBrandExperience === "function" ) if (!ctor?.prototype) { return false } const prototype = ctor.prototype if (prototype[SERVICE_PATCH_KEY]) { return true } try { for (const name of ACCOUNT_SERVICE_METHODS) { const original = prototype[name] if (typeof original !== "function") { continue } prototype[name] = function patchedAccountMethod(...args) { return Promise.resolve(original.apply(this, args)).then((account) => normalizeProAccount(account) ) } } Object.defineProperty(prototype, SERVICE_PATCH_KEY, { value: true }) state.log("info", "Pro account service patched.") return true } catch (error) { state.log( "warn", "Failed to patch account service.", error?.stack || String(error) ) return false } } function normalizeProAccount(account) { if (!isRecord(account)) { return account } const nextSubscription = normalizeProSubscription(account.subscription) if (nextSubscription === account.subscription) { return account } return { ...account, subscription: nextSubscription, } } function normalizeProSubscription(subscription) { if (!isRecord(subscription)) { return { ...DEFAULT_SUBSCRIPTION } } const nextSubscription = { ...subscription } let changed = false if ( typeof nextSubscription.period !== "string" || !nextSubscription.period.trim() ) { nextSubscription.period = DEFAULT_SUBSCRIPTION.period changed = true } if (nextSubscription.state !== "active") { nextSubscription.state = DEFAULT_SUBSCRIPTION.state changed = true } return changed ? nextSubscription : subscription }