import 'reflect-metadata' import { expoClient } from '@better-auth/expo/client' import { createSkerClientPlugin } from '@repo/sdk' import { adminClient, emailOTPClient, genericOAuthClient, jwtClient, organizationClient, phoneNumberClient, usernameClient, } from 'better-auth/client/plugins' import { createAuthClient } from 'better-auth/react' import { fetchWithLogger, TOKEN_KEY } from './fetch-logger' import type { Subscription } from './plugins/stripe' import { stripeClient } from './plugins/stripe-plugin' import { storage } from './storage' import type { ApiError } from './types' // 商户ID配置 - 从环境变量或应用配置中读取 export const OWNER_ID = 't0m9cketSQdCA6cHXI9mXQLJPM9LDIw5' export interface CreditBalance { tokenUsage: number remainingTokenBalance: number currentCreditBalance: number unitPrice: number } export interface SubscriptionListItem extends Subscription { type?: 'metered' | 'licenced' limits?: Record creditBalance?: CreditBalance highestTierPlan?: string highestTierCredits?: number } export interface SubscriptionListParams { query?: { referenceId?: string } } export interface SubscriptionRestoreParams { referenceId?: string subscriptionId?: string } export interface SubscriptionRestoreResponse { success: boolean subscription: { id: string stripeSubscriptionId: string cancelAtPeriodEnd: boolean periodEnd?: Date status: string } } export interface BillingPortalParams { locale?: string referenceId?: string returnUrl?: string } export interface BillingPortalResponse { url: string redirect: boolean } export interface PlansParams { query: { id: string key: string } } export interface CreateSubscriptionParams { priceId: string productId: string successUrl: string cancelUrl: string } export interface UpgradeSubscriptionParams { plan: string subscriptionId: string successUrl: string cancelUrl: string } export interface CancelSubscriptionParams { subscriptionId: string referenceId: string } export interface TopupParams { amount: number priceId: string successUrl: string cancelUrl: string } export interface CheckoutResponse { url?: string } export interface ISubscription { list: (params?: SubscriptionListParams) => Promise<{ data?: SubscriptionListItem[]; error?: ApiError }> plans: (params: PlansParams) => Promise<{ data?: any; error?: ApiError }> create: (params: CreateSubscriptionParams) => Promise<{ data?: CheckoutResponse; error?: ApiError }> upgrade: (params: UpgradeSubscriptionParams) => Promise<{ data?: any; error?: ApiError }> cancel: (params: CancelSubscriptionParams) => Promise<{ data?: any; error?: ApiError }> restore: (params?: SubscriptionRestoreParams) => Promise<{ data?: SubscriptionRestoreResponse; error?: ApiError }> billingPortal: (params?: BillingPortalParams) => Promise<{ data?: BillingPortalResponse; error?: ApiError }> credit: { topup: (params: TopupParams) => Promise<{ data?: CheckoutResponse; error?: ApiError }> } } // 统一的 Token 存储键名(与 fetch-logger.ts 保持一致) export const getAuthToken = async () => (await storage.getItem(TOKEN_KEY)) || '' export const setAuthToken = async (token: string) => { await storage.setItem(TOKEN_KEY, token) } export const authClient = createAuthClient({ baseURL: 'https://api.mixvideo.bowong.cc', trustedOrigins: ['duooomi://', 'https://api.mixvideo.bowong.cc'], storage, scheme: 'duooomi', fetchOptions: { headers: { 'Content-Type': 'application/json', // x-ownerid: 商户ID(如果后端需要) // 如果 MERCHANT_ID 为空,则不添加此 header ...(OWNER_ID && { 'x-ownerid': OWNER_ID }), }, auth: { type: 'Bearer', token: async () => { const Authorization = await getAuthToken() return Authorization }, }, customFetchImpl: fetchWithLogger as typeof fetch, }, plugins: [ createSkerClientPlugin(), stripeClient(), usernameClient(), phoneNumberClient(), emailOTPClient(), genericOAuthClient(), jwtClient(), adminClient(), organizationClient(), expoClient({ storage: storage as any, }), ], }) export const { signIn, signUp, signOut, useSession, $Infer, admin, forgetPassword, resetPassword, emailOtp, changePassword, updateUser } = authClient // 导出 loomart API(来自 createSkerClientPlugin) export const loomart = Reflect.get(authClient, 'loomart') // 导出 subscription API export const subscription: ISubscription = Reflect.get(authClient, 'subscription')