@neosianexus/super-tebex 3.4.0 → 3.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +16 -8
- package/dist/errors/TebexError.d.ts +9 -0
- package/dist/errors/TebexError.d.ts.map +1 -1
- package/dist/errors/codes.d.ts +6 -0
- package/dist/errors/codes.d.ts.map +1 -1
- package/dist/hooks/useBasket.d.ts.map +1 -1
- package/dist/hooks/useCategories.d.ts.map +1 -1
- package/dist/hooks/useCategory.d.ts.map +1 -1
- package/dist/hooks/useCheckout.d.ts +0 -1
- package/dist/hooks/useCheckout.d.ts.map +1 -1
- package/dist/hooks/useCoupons.d.ts.map +1 -1
- package/dist/hooks/useCreatorCodes.d.ts.map +1 -1
- package/dist/hooks/useGiftCards.d.ts.map +1 -1
- package/dist/hooks/useGiftPackage.d.ts.map +1 -1
- package/dist/hooks/usePackage.d.ts.map +1 -1
- package/dist/hooks/usePackages.d.ts.map +1 -1
- package/dist/hooks/useWebstore.d.ts.map +1 -1
- package/dist/index.cjs +3 -1
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -0
- package/dist/provider/TebexProvider.d.ts.map +1 -1
- package/dist/services/api.d.ts.map +1 -1
- package/dist/stores/basketStore.d.ts +5 -3
- package/dist/stores/basketStore.d.ts.map +1 -1
- package/dist/stores/userStore.d.ts +5 -3
- package/dist/stores/userStore.d.ts.map +1 -1
- package/dist/testing/index.cjs +3 -1
- package/dist/testing/index.cjs.map +1 -0
- package/dist/testing/index.js +3 -1
- package/dist/testing/index.js.map +1 -0
- package/dist/types/guards.d.ts.map +1 -1
- package/package.json +31 -28
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/errors/codes.ts","../src/errors/TebexError.ts","../src/services/api.ts","../src/stores/basketStore.ts","../src/stores/userStore.ts","../src/provider/context.ts","../src/provider/TebexProvider.tsx","../src/queries/keys.ts","../src/types/guards.ts","../src/hooks/useBasket.ts","../src/hooks/useCategories.ts","../src/hooks/useCategory.ts","../src/hooks/useCheckout.ts","../src/hooks/useCoupons.ts","../src/hooks/useCreatorCodes.ts","../src/hooks/useGiftCards.ts","../src/hooks/useGiftPackage.ts","../src/hooks/usePackage.ts","../src/hooks/usePackages.ts","../src/hooks/useUser.ts","../src/hooks/useWebstore.ts","../src/types/result.ts"],"names":["TebexErrorCode","TebexError","_TebexError","code","message","cause","error","response","statusCode","lowerMessage","json","tebexInstance","initTebexClient","publicKey","TebexHeadless","getTebexClient","isTebexClientInitialized","useBasketStore","create","subscribeWithSelector","persist","set","ident","state","persistedState","_state","useUserStore","username","TebexContext","createContext","useTebexContext","context","useContext","useTebexConfig","config","defaultQueryClientConfig","attemptIndex","resolveConfig","baseUrl","completePath","cancelPath","TebexProvider","children","externalQueryClient","resolvedConfig","useMemo","queryClient","useState","QueryClient","useEffect","handler","e","contextValue","jsx","QueryClientProvider","tebexKeys","includePackages","id","categoryId","isTebexError","isSuccess","result","isError","isDefined","value","isNonEmptyString","isPositiveNumber","isPositiveInteger","isValidMinecraftUsername","basketCreationPromise","useBasket","useQueryClient","basketIdent","setBasketIdent","clearBasketIdent","basketIdentRef","useRef","basketQuery","useQuery","failureCount","tebexError","ensureBasket","useCallback","currentIdent","newBasket","addMutation","useMutation","params","quantity","tebex","previousBasket","optimisticPackage","existingIndex","p","newPackages","i","_error","_params","data","removeMutation","packageId","_packageId","updateQuantityMutation","clearBasket","basket","packages","itemCount","acc","pkg","total","combinedError","wrappedError","addPackage","removePackage","updateQuantity","useCategories","options","enabled","query","dataRef","getByName","name","category","getById","getBySlug","slug","useCategory","CHECKOUT_TIMEOUT_MS","checkoutGeneration","useCheckout","isEmpty","launchMutation","tebexGlobal","resolve","reject","tebexCheckout","isSettled","currentGeneration","handleComplete","cleanup","handleError","handleClose","observer","debounceTimer","timeoutId","findTebexModal","setupModalObserver","modalWasOpen","checkModal","launch","useCoupons","applyMutation","couponCode","_couponCode","c","apply","remove","useCreatorCodes","_code","_","useGiftCards","cardNumber","_cardNumber","g","useGiftPackage","giftMutation","gift","usePackage","usePackages","categories","allPackages","useUser","setUsernameStore","clearUsernameStore","setUsername","newUsername","trimmed","clearUsername","isAuthenticated","isCurrencyObject","transformWebstore","webstore","rawCurrency","currencyCode","useWebstore","ok","err"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Enumeration of all possible Tebex error codes.\n * Consumers can use these codes to provide localized error messages.\n */\nexport enum TebexErrorCode {\n // Provider errors (1xx)\n PROVIDER_NOT_FOUND = 'PROVIDER_NOT_FOUND',\n INVALID_CONFIG = 'INVALID_CONFIG',\n\n // Authentication errors (2xx)\n NOT_AUTHENTICATED = 'NOT_AUTHENTICATED',\n INVALID_USERNAME = 'INVALID_USERNAME',\n\n // Basket errors (3xx)\n BASKET_NOT_FOUND = 'BASKET_NOT_FOUND',\n BASKET_CREATION_FAILED = 'BASKET_CREATION_FAILED',\n BASKET_EXPIRED = 'BASKET_EXPIRED',\n BASKET_EMPTY = 'BASKET_EMPTY',\n\n // Package errors (4xx)\n PACKAGE_NOT_FOUND = 'PACKAGE_NOT_FOUND',\n PACKAGE_OUT_OF_STOCK = 'PACKAGE_OUT_OF_STOCK',\n PACKAGE_ALREADY_OWNED = 'PACKAGE_ALREADY_OWNED',\n INVALID_QUANTITY = 'INVALID_QUANTITY',\n\n // Category errors (5xx)\n CATEGORY_NOT_FOUND = 'CATEGORY_NOT_FOUND',\n\n // Coupon/GiftCard errors (6xx)\n COUPON_INVALID = 'COUPON_INVALID',\n COUPON_EXPIRED = 'COUPON_EXPIRED',\n COUPON_ALREADY_USED = 'COUPON_ALREADY_USED',\n GIFTCARD_INVALID = 'GIFTCARD_INVALID',\n GIFTCARD_INSUFFICIENT_BALANCE = 'GIFTCARD_INSUFFICIENT_BALANCE',\n CREATOR_CODE_INVALID = 'CREATOR_CODE_INVALID',\n\n // Checkout errors (7xx)\n CHECKOUT_FAILED = 'CHECKOUT_FAILED',\n CHECKOUT_CANCELLED = 'CHECKOUT_CANCELLED',\n TEBEX_JS_NOT_LOADED = 'TEBEX_JS_NOT_LOADED',\n\n // Network errors (8xx)\n NETWORK_ERROR = 'NETWORK_ERROR',\n TIMEOUT = 'TIMEOUT',\n RATE_LIMITED = 'RATE_LIMITED',\n\n // HTTP errors (9xx)\n SERVER_ERROR = 'SERVER_ERROR',\n FORBIDDEN = 'FORBIDDEN',\n VALIDATION_ERROR = 'VALIDATION_ERROR',\n NOT_FOUND = 'NOT_FOUND',\n BASKET_LOCKED = 'BASKET_LOCKED',\n PACKAGE_DISABLED = 'PACKAGE_DISABLED',\n\n // Unknown\n UNKNOWN = 'UNKNOWN',\n}\n","import { TebexErrorCode } from './codes';\n\n/**\n * Custom error class for Tebex SDK errors.\n * Provides structured error handling with error codes.\n */\nexport class TebexError extends Error {\n public readonly code: TebexErrorCode;\n public readonly cause?: unknown;\n\n constructor(code: TebexErrorCode, message?: string, cause?: unknown) {\n super(message ?? code);\n Object.setPrototypeOf(this, TebexError.prototype);\n this.name = 'TebexError';\n this.code = code;\n this.cause = cause;\n\n if (typeof Error.captureStackTrace === 'function') {\n Error.captureStackTrace(this, TebexError);\n }\n }\n\n private static extractStatusCode(error: unknown): number | null {\n if (typeof error === 'object' && error !== null) {\n if ('response' in error) {\n const response = (error as { response?: { status?: unknown } }).response;\n if (response && typeof response.status === 'number') return response.status;\n }\n if ('status' in error && typeof (error as { status: unknown }).status === 'number') {\n return (error as { status: number }).status;\n }\n }\n return null;\n }\n\n /**\n * Converts an unknown error to a TebexError.\n * If the error is already a TebexError, it returns it as-is.\n */\n static fromUnknown(error: unknown): TebexError {\n if (error instanceof TebexError) {\n return error;\n }\n\n const message = error instanceof Error ? error.message : String(error);\n const statusCode = TebexError.extractStatusCode(error);\n\n if (statusCode !== null) {\n switch (statusCode) {\n case 401:\n case 403:\n return new TebexError(TebexErrorCode.FORBIDDEN, message, error);\n case 404: {\n const lowerMessage = message.toLowerCase();\n if (lowerMessage.includes('basket')) {\n return new TebexError(TebexErrorCode.BASKET_NOT_FOUND, message, error);\n }\n if (lowerMessage.includes('package')) {\n return new TebexError(TebexErrorCode.PACKAGE_NOT_FOUND, message, error);\n }\n return new TebexError(TebexErrorCode.NOT_FOUND, message, error);\n }\n case 410:\n return new TebexError(TebexErrorCode.BASKET_EXPIRED, message, error);\n case 422:\n return new TebexError(TebexErrorCode.VALIDATION_ERROR, message, error);\n case 429:\n return new TebexError(TebexErrorCode.RATE_LIMITED, message, error);\n case 500:\n case 502:\n case 503:\n return new TebexError(TebexErrorCode.SERVER_ERROR, message, error);\n }\n }\n\n if (error instanceof Error) {\n const lowerMessage = message.toLowerCase();\n\n if (lowerMessage.includes('network') || lowerMessage.includes('fetch')) {\n return new TebexError(TebexErrorCode.NETWORK_ERROR, message, error);\n }\n\n if (lowerMessage.includes('timeout')) {\n return new TebexError(TebexErrorCode.TIMEOUT, message, error);\n }\n\n if (lowerMessage.includes('rate limit') || lowerMessage.includes('429')) {\n return new TebexError(TebexErrorCode.RATE_LIMITED, message, error);\n }\n\n if (lowerMessage.includes('basket') && lowerMessage.includes('not found')) {\n return new TebexError(TebexErrorCode.BASKET_NOT_FOUND, message, error);\n }\n\n if (lowerMessage.includes('package') && lowerMessage.includes('not found')) {\n return new TebexError(TebexErrorCode.PACKAGE_NOT_FOUND, message, error);\n }\n\n if (lowerMessage.includes('coupon') && lowerMessage.includes('invalid')) {\n return new TebexError(TebexErrorCode.COUPON_INVALID, message, error);\n }\n\n if (lowerMessage.includes('coupon') && lowerMessage.includes('expired')) {\n return new TebexError(TebexErrorCode.COUPON_EXPIRED, message, error);\n }\n\n if (lowerMessage.includes('gift') && lowerMessage.includes('invalid')) {\n return new TebexError(TebexErrorCode.GIFTCARD_INVALID, message, error);\n }\n\n return new TebexError(TebexErrorCode.UNKNOWN, message, error);\n }\n\n return new TebexError(TebexErrorCode.UNKNOWN, message);\n }\n\n /**\n * Creates a TebexError from a JSON representation.\n */\n static fromJSON(json: { code: TebexErrorCode; message?: string }): TebexError {\n return new TebexError(json.code, json.message ?? json.code);\n }\n\n /**\n * Returns a JSON representation of the error.\n */\n toJSON(): { name: string; code: TebexErrorCode; message: string; cause?: string } {\n return {\n name: this.name,\n code: this.code,\n message: this.message,\n ...(this.cause instanceof Error ? { cause: this.cause.message } : {}),\n };\n }\n}\n","'use client';\n\nimport { TebexHeadless } from 'tebex_headless';\nimport { TebexError } from '../errors/TebexError';\nimport { TebexErrorCode } from '../errors/codes';\n\nlet tebexInstance: TebexHeadless | null = null;\n\n/**\n * Initializes the Tebex headless client with the given public key.\n * This must be called before using any Tebex hooks.\n */\nexport function initTebexClient(publicKey: string): void {\n tebexInstance = new TebexHeadless(publicKey);\n}\n\n/**\n * Returns the initialized Tebex client.\n * Throws if the client has not been initialized.\n */\nexport function getTebexClient(): TebexHeadless {\n if (tebexInstance === null) {\n throw new TebexError(TebexErrorCode.PROVIDER_NOT_FOUND, 'Tebex client not initialized. Ensure TebexProvider wraps your component tree.');\n }\n return tebexInstance;\n}\n\n/**\n * Checks if the Tebex client is initialized.\n */\nexport function isTebexClientInitialized(): boolean {\n return tebexInstance !== null;\n}\n\n/**\n * Resets the Tebex client. Useful for testing.\n */\nexport function resetTebexClient(): void {\n tebexInstance = null;\n}\n","'use client';\n\nimport { create } from 'zustand';\nimport { persist, subscribeWithSelector } from 'zustand/middleware';\n\n/**\n * Basket store state interface.\n */\ninterface BasketStoreState {\n readonly basketIdent: string | null;\n}\n\n/**\n * Basket store actions interface.\n */\ninterface BasketStoreActions {\n readonly setBasketIdent: (ident: string) => void;\n readonly clearBasketIdent: () => void;\n}\n\n/**\n * Complete basket store type.\n */\ntype BasketStore = BasketStoreState & BasketStoreActions;\n\n/**\n * Zustand store for basket ident persistence.\n * Uses localStorage to persist the basket ident across sessions.\n */\nexport const useBasketStore = create<BasketStore>()(\n subscribeWithSelector(\n persist(\n set => ({\n basketIdent: null,\n setBasketIdent: (ident: string) => {\n set({ basketIdent: ident });\n },\n clearBasketIdent: () => {\n set({ basketIdent: null });\n },\n }),\n {\n name: 'tebex-basket-store',\n // Skip hydration — rehydrated manually in TebexProvider\n skipHydration: true,\n version: 1,\n partialize: (state: BasketStore) => ({ basketIdent: state.basketIdent }),\n migrate: (persistedState: unknown) => {\n return persistedState as Pick<BasketStoreState, 'basketIdent'>;\n },\n onRehydrateStorage: () => {\n return (_state: unknown, error?: unknown) => {\n if (error !== undefined) {\n // eslint-disable-next-line no-console\n console.warn('[tebex] Failed to rehydrate basket store:', error);\n }\n };\n },\n },\n ),\n ),\n);\n\nexport type { BasketStore, BasketStoreActions, BasketStoreState };\n","'use client';\n\nimport { create } from 'zustand';\nimport { persist, subscribeWithSelector } from 'zustand/middleware';\n\nimport { useBasketStore } from './basketStore';\n\n/**\n * User store state interface.\n */\ninterface UserStoreState {\n readonly username: string | null;\n}\n\n/**\n * User store actions interface.\n */\ninterface UserStoreActions {\n readonly setUsername: (username: string) => void;\n readonly clearUsername: () => void;\n}\n\n/**\n * Complete user store type.\n */\ntype UserStore = UserStoreState & UserStoreActions;\n\n/**\n * Zustand store for user data persistence.\n * Uses localStorage to persist the username (Minecraft username) across sessions.\n */\nexport const useUserStore = create<UserStore>()(\n subscribeWithSelector(\n persist(\n set => ({\n username: null,\n setUsername: (username: string) => {\n set({ username });\n },\n clearUsername: () => {\n set({ username: null });\n useBasketStore.getState().clearBasketIdent();\n },\n }),\n {\n name: 'tebex-user-store',\n // Skip hydration — rehydrated manually in TebexProvider\n skipHydration: true,\n version: 1,\n partialize: (state: UserStore) => ({ username: state.username }),\n migrate: (persistedState: unknown) => {\n return persistedState as Pick<UserStoreState, 'username'>;\n },\n onRehydrateStorage: () => {\n return (_state: unknown, error?: unknown) => {\n if (error !== undefined) {\n // eslint-disable-next-line no-console\n console.warn('[tebex] Failed to rehydrate user store:', error);\n }\n };\n },\n },\n ),\n ),\n);\n\nexport type { UserStore, UserStoreActions, UserStoreState };\n","'use client';\n\nimport type { QueryClient } from '@tanstack/react-query';\nimport { createContext, useContext } from 'react';\n\nimport { TebexError } from '../errors/TebexError';\nimport { TebexErrorCode } from '../errors/codes';\nimport type { ResolvedTebexConfig } from '../types/config';\n\n/**\n * Context value provided by TebexProvider.\n */\nexport interface TebexContextValue {\n readonly config: ResolvedTebexConfig;\n readonly queryClient: QueryClient;\n}\n\n/**\n * Tebex context for sharing configuration and QueryClient.\n * Used by both TebexProvider and TebexMockProvider.\n */\nexport const TebexContext = createContext<TebexContextValue | null>(null);\n\n/**\n * Hook to access the Tebex context.\n * Must be used within a TebexProvider or TebexMockProvider.\n *\n * @throws TebexError if used outside of a provider\n */\nexport function useTebexContext(): TebexContextValue {\n const context = useContext(TebexContext);\n\n if (context === null) {\n throw new TebexError(\n TebexErrorCode.PROVIDER_NOT_FOUND,\n 'useTebexContext must be used within TebexProvider or TebexMockProvider',\n );\n }\n\n return context;\n}\n\n/**\n * Hook to access just the Tebex configuration.\n * Useful when you don't need the QueryClient.\n */\nexport function useTebexConfig(): ResolvedTebexConfig {\n const { config } = useTebexContext();\n return config;\n}\n","'use client';\n\nimport { QueryClient, QueryClientProvider, type QueryClientConfig } from '@tanstack/react-query';\nimport { useEffect, useMemo, useState, type ReactNode } from 'react';\n\nimport { initTebexClient } from '../services/api';\nimport { useBasketStore } from '../stores/basketStore';\nimport { useUserStore } from '../stores/userStore';\nimport type { ResolvedTebexConfig, TebexConfig } from '../types/config';\nimport { TebexContext, type TebexContextValue } from './context';\n\n/**\n * Default query client configuration optimized for e-commerce.\n */\nconst defaultQueryClientConfig: QueryClientConfig = {\n defaultOptions: {\n queries: {\n staleTime: 60 * 1000, // 1 minute\n gcTime: 5 * 60 * 1000, // 5 minutes (formerly cacheTime)\n retry: 3,\n retryDelay: attemptIndex => Math.min(1000 * 2 ** attemptIndex, 30000),\n refetchOnWindowFocus: false,\n refetchOnReconnect: true,\n },\n mutations: {\n retry: 2,\n retryDelay: attemptIndex => Math.min(500 * 2 ** attemptIndex, 5000),\n },\n },\n};\n\n/**\n * Resolves the TebexConfig with default values.\n */\nfunction resolveConfig(config: TebexConfig): ResolvedTebexConfig {\n const baseUrl = config.baseUrl.replace(/\\/$/, ''); // Remove trailing slash\n const completePath = config.urls?.complete ?? '/shop/complete';\n const cancelPath = config.urls?.cancel ?? '/shop/cancel';\n\n return {\n publicKey: config.publicKey,\n baseUrl,\n completeUrl: `${baseUrl}${completePath}`,\n cancelUrl: `${baseUrl}${cancelPath}`,\n onError: config.onError,\n };\n}\n\n/**\n * Props for TebexProvider component.\n */\ninterface TebexProviderProps {\n readonly children: ReactNode;\n readonly config: TebexConfig;\n /** Optional custom QueryClient. If not provided, a default one will be created. */\n readonly queryClient?: QueryClient | undefined;\n}\n\n/**\n * TebexProvider - Main provider component for the Tebex SDK.\n *\n * This provider must wrap your application to use any Tebex hooks.\n * It initializes the Tebex client, sets up React Query, and provides\n * the configuration context.\n *\n * NOTE: React Query Devtools are NOT included in this library to avoid\n * production build issues with jsxDEV. If you need devtools, add them\n * manually in your application:\n *\n * @example\n * ```tsx\n * import { ReactQueryDevtools } from '@tanstack/react-query-devtools';\n *\n * // In your app layout or root component:\n * <TebexProvider config={config}>\n * {children}\n * {process.env.NODE_ENV === 'development' && (\n * <ReactQueryDevtools initialIsOpen={false} />\n * )}\n * </TebexProvider>\n * ```\n *\n * @example\n * ```tsx\n * <TebexProvider\n * config={{\n * publicKey: process.env.NEXT_PUBLIC_TEBEX_KEY!,\n * baseUrl: 'https://mysite.com',\n * onError: (error) => toast.error(t(`errors.${error.code}`)),\n * }}\n * >\n * {children}\n * </TebexProvider>\n * ```\n */\nexport function TebexProvider({\n children,\n config,\n queryClient: externalQueryClient,\n}: TebexProviderProps): ReactNode {\n const resolvedConfig = useMemo(() => resolveConfig(config), [config]);\n\n const [queryClient] = useState(\n () => externalQueryClient ?? new QueryClient(defaultQueryClientConfig),\n );\n\n // Runs once on first render via useState initializer\n useState(() => {\n initTebexClient(resolvedConfig.publicKey);\n });\n\n useEffect(() => {\n void useBasketStore.persist.rehydrate();\n void useUserStore.persist.rehydrate();\n }, []);\n\n useEffect(() => {\n const handler = (e: StorageEvent): void => {\n if (e.key === 'tebex-basket-store' || e.key === 'tebex-user-store') {\n void useBasketStore.persist.rehydrate();\n void useUserStore.persist.rehydrate();\n }\n };\n window.addEventListener('storage', handler);\n return () => { window.removeEventListener('storage', handler); };\n }, []);\n\n const contextValue = useMemo<TebexContextValue>(\n () => ({\n config: resolvedConfig,\n queryClient,\n }),\n [resolvedConfig, queryClient],\n );\n\n return (\n <TebexContext.Provider value={contextValue}>\n <QueryClientProvider client={queryClient}>{children}</QueryClientProvider>\n </TebexContext.Provider>\n );\n}\n\nexport { useTebexConfig, useTebexContext } from './context';\n","/**\n * Query keys factory for TanStack Query.\n * Follows the recommended pattern for granular cache invalidation.\n *\n * @see https://tkdodo.eu/blog/effective-react-query-keys\n */\nexport const tebexKeys = {\n /** Root key for all Tebex queries */\n all: ['tebex'] as const,\n\n // ============ Categories ============\n\n /** All category-related queries */\n categories: () => [...tebexKeys.all, 'categories'] as const,\n\n /** Categories list with include packages option */\n categoriesList: (includePackages: boolean) =>\n [...tebexKeys.categories(), 'list', { includePackages }] as const,\n\n /** Single category by ID */\n category: (id: number) => [...tebexKeys.categories(), 'detail', id] as const,\n\n // ============ Packages ============\n\n /** All package-related queries */\n packages: () => [...tebexKeys.all, 'packages'] as const,\n\n /** Packages list, optionally filtered by category */\n packagesList: (categoryId?: number) => [...tebexKeys.packages(), 'list', { categoryId }] as const,\n\n /** Single package by ID */\n package: (id: number) => [...tebexKeys.packages(), 'detail', id] as const,\n\n // ============ Basket ============\n\n /** All basket-related queries */\n baskets: () => [...tebexKeys.all, 'baskets'] as const,\n\n /** Specific basket by ident */\n basket: (ident: string | null) => [...tebexKeys.baskets(), ident] as const,\n\n // ============ Webstore ============\n\n /** Webstore info query */\n webstore: () => [...tebexKeys.all, 'webstore'] as const,\n} as const;\n\n/**\n * Type helper for extracting query key types.\n */\ntype KeyFunctions = Omit<typeof tebexKeys, 'all'>;\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype ExtractReturnType<T> = T extends (...args: any[]) => infer R ? R : never;\nexport type TebexQueryKey =\n | (typeof tebexKeys)['all']\n | ExtractReturnType<KeyFunctions[keyof KeyFunctions]>;\n","import { TebexError } from '../errors/TebexError';\nimport type { Result } from './result';\n\n/**\n * Type guard to check if an error is a TebexError.\n */\nexport function isTebexError(error: unknown): error is TebexError {\n if (error instanceof TebexError) return true;\n return (\n typeof error === 'object' &&\n error !== null &&\n 'name' in error &&\n 'code' in error &&\n (error as { name: unknown }).name === 'TebexError'\n );\n}\n\n/**\n * Type guard to check if a Result is successful.\n */\nexport function isSuccess<T, E>(\n result: Result<T, E>,\n): result is { readonly success: true; readonly data: T } {\n return result.success;\n}\n\n/**\n * Type guard to check if a Result is an error.\n */\nexport function isError<T, E>(\n result: Result<T, E>,\n): result is { readonly success: false; readonly error: E } {\n return !result.success;\n}\n\n/**\n * Type guard to check if a value is defined (not null or undefined).\n */\nexport function isDefined<T>(value: T | null | undefined): value is T {\n return value !== null && value !== undefined;\n}\n\n/**\n * Type guard to check if a value is a non-empty string.\n */\nexport function isNonEmptyString(value: unknown): value is string {\n return typeof value === 'string' && value.length > 0;\n}\n\n/**\n * Type guard to check if a value is a positive number.\n */\nexport function isPositiveNumber(value: unknown): value is number {\n return typeof value === 'number' && value > 0 && Number.isFinite(value);\n}\n\n/**\n * Type guard to check if a value is a positive integer.\n */\nexport function isPositiveInteger(value: unknown): value is number {\n return typeof value === 'number' && Number.isInteger(value) && value > 0;\n}\n\n/**\n * Validates a Minecraft username format.\n * Valid usernames are 3-16 characters, alphanumeric with underscores.\n */\nexport function isValidMinecraftUsername(value: unknown): value is string {\n if (typeof value !== 'string') return false;\n return /^[a-zA-Z0-9_]{3,16}$/.test(value);\n}\n","'use client';\n\nimport { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';\nimport { useCallback, useEffect, useMemo, useRef } from 'react';\nimport type { Basket, BasketPackage } from 'tebex_headless';\n\nimport { TebexError } from '../errors/TebexError';\nimport { TebexErrorCode } from '../errors/codes';\nimport { useTebexConfig } from '../provider/TebexProvider';\nimport { tebexKeys } from '../queries/keys';\nimport { getTebexClient } from '../services/api';\nimport { useBasketStore } from '../stores/basketStore';\nimport { useUserStore } from '../stores/userStore';\nimport { isPositiveInteger } from '../types/guards';\nimport type { AddPackageParams, UpdateQuantityParams, UseBasketReturn } from '../types/hooks';\n\n/**\n * Singleton promise for basket creation to prevent race conditions.\n * Concurrent addPackage calls share the same creation promise\n * instead of creating multiple baskets.\n */\nlet basketCreationPromise: Promise<string> | null = null;\n\n/** Mutation context for optimistic update rollback. */\ninterface BasketMutationContext {\n previousBasket: Basket | null | undefined;\n ident: string | null;\n}\n\n/**\n * Hook to manage the shopping basket with optimistic updates.\n *\n * @returns Basket data, actions, and computed values\n *\n * @example\n * ```tsx\n * const {\n * basket,\n * packages,\n * addPackage,\n * removePackage,\n * itemCount,\n * total,\n * isAddingPackage,\n * } = useBasket();\n *\n * const handleAddToCart = async (packageId: number) => {\n * await addPackage({ packageId, quantity: 1 });\n * };\n * ```\n */\nexport function useBasket(): UseBasketReturn {\n const config = useTebexConfig();\n const queryClient = useQueryClient();\n\n const basketIdent = useBasketStore(state => state.basketIdent);\n const setBasketIdent = useBasketStore(state => state.setBasketIdent);\n const clearBasketIdent = useBasketStore(state => state.clearBasketIdent);\n const username = useUserStore(state => state.username);\n\n // Ref to avoid stale closure in mutation callbacks\n const basketIdentRef = useRef(basketIdent);\n basketIdentRef.current = basketIdent;\n\n const basketQuery = useQuery({\n queryKey: tebexKeys.basket(basketIdent),\n queryFn: async (): Promise<Basket | null> => {\n if (basketIdent === null) {\n return null;\n }\n const tebex = getTebexClient();\n return tebex.getBasket(basketIdent);\n },\n enabled: basketIdent !== null,\n retry: (failureCount, error) => {\n const tebexError = TebexError.fromUnknown(error);\n if (\n tebexError.code === TebexErrorCode.BASKET_NOT_FOUND ||\n tebexError.code === TebexErrorCode.BASKET_EXPIRED\n ) {\n return false;\n }\n return failureCount < 3;\n },\n });\n\n useEffect(() => {\n if (basketQuery.error !== null) {\n const tebexError = TebexError.fromUnknown(basketQuery.error);\n if (\n tebexError.code === TebexErrorCode.BASKET_NOT_FOUND ||\n tebexError.code === TebexErrorCode.BASKET_EXPIRED\n ) {\n clearBasketIdent();\n }\n }\n }, [basketQuery.error, clearBasketIdent]);\n\n const ensureBasket = useCallback(async (): Promise<string> => {\n const currentIdent = useBasketStore.getState().basketIdent;\n if (currentIdent !== null) return currentIdent;\n\n if (basketCreationPromise !== null) return basketCreationPromise;\n\n const createBasket = async (): Promise<string> => {\n if (username === null || username.length === 0) {\n throw new TebexError(\n TebexErrorCode.NOT_AUTHENTICATED,\n 'Username is required to create a basket',\n );\n }\n\n const tebex = getTebexClient();\n const newBasket = await tebex.createMinecraftBasket(\n username,\n config.completeUrl,\n config.cancelUrl,\n );\n\n setBasketIdent(newBasket.ident);\n return newBasket.ident;\n };\n\n basketCreationPromise = createBasket().finally(() => {\n basketCreationPromise = null;\n });\n\n return basketCreationPromise;\n }, [username, config.completeUrl, config.cancelUrl, setBasketIdent]);\n\n const addMutation = useMutation<Basket, Error, AddPackageParams, BasketMutationContext>({\n scope: { id: 'basket-mutations' },\n mutationFn: async (params: AddPackageParams): Promise<Basket> => {\n const quantity = params.quantity ?? 1;\n\n if (!isPositiveInteger(quantity)) {\n throw new TebexError(\n TebexErrorCode.INVALID_QUANTITY,\n 'Quantity must be a positive integer',\n );\n }\n\n const ident = await ensureBasket();\n const tebex = getTebexClient();\n\n await tebex.addPackageToBasket(\n ident,\n params.packageId,\n quantity,\n params.type,\n params.variableData,\n );\n\n return tebex.getBasket(ident);\n },\n onMutate: async (params): Promise<BasketMutationContext> => {\n const ident = basketIdentRef.current;\n\n if (ident === null) {\n return { previousBasket: undefined, ident };\n }\n\n await queryClient.cancelQueries({ queryKey: tebexKeys.basket(ident) });\n const previousBasket = queryClient.getQueryData<Basket | null>(tebexKeys.basket(ident));\n\n if (previousBasket !== null && previousBasket !== undefined) {\n const optimisticPackage: BasketPackage = {\n id: params.packageId,\n name: 'Loading...',\n description: '',\n image: null,\n in_basket: {\n quantity: params.quantity ?? 1,\n price: 0,\n gift_username_id: null,\n gift_username: null,\n },\n };\n\n const existingIndex = previousBasket.packages.findIndex(p => p.id === params.packageId);\n\n const newPackages =\n existingIndex >= 0\n ? previousBasket.packages.map((p, i) =>\n i === existingIndex\n ? {\n ...p,\n in_basket: {\n ...p.in_basket,\n quantity: p.in_basket.quantity + (params.quantity ?? 1),\n },\n }\n : p,\n )\n : [...previousBasket.packages, optimisticPackage];\n\n queryClient.setQueryData<Basket>(tebexKeys.basket(ident), {\n ...previousBasket,\n packages: newPackages,\n });\n }\n\n return { previousBasket, ident };\n },\n onError: (_error, _params, context) => {\n if (context?.previousBasket !== undefined && context.ident !== null) {\n queryClient.setQueryData(tebexKeys.basket(context.ident), context.previousBasket);\n }\n config.onError?.(TebexError.fromUnknown(_error));\n },\n onSuccess: (data, _params, context) => {\n const ident = context.ident ?? basketIdentRef.current;\n if (ident !== null) {\n queryClient.setQueryData(tebexKeys.basket(ident), data);\n }\n },\n });\n\n const removeMutation = useMutation<Basket, Error, number, BasketMutationContext>({\n scope: { id: 'basket-mutations' },\n mutationFn: async (packageId: number): Promise<Basket> => {\n if (basketIdent === null) {\n throw new TebexError(TebexErrorCode.BASKET_NOT_FOUND);\n }\n const tebex = getTebexClient();\n await tebex.removePackage(basketIdent, packageId);\n return tebex.getBasket(basketIdent);\n },\n onMutate: async (packageId): Promise<BasketMutationContext> => {\n const ident = basketIdentRef.current;\n\n if (ident === null) {\n return { previousBasket: undefined, ident };\n }\n\n await queryClient.cancelQueries({ queryKey: tebexKeys.basket(ident) });\n\n const previousBasket = queryClient.getQueryData<Basket | null>(tebexKeys.basket(ident));\n\n if (previousBasket !== null && previousBasket !== undefined) {\n queryClient.setQueryData<Basket>(tebexKeys.basket(ident), {\n ...previousBasket,\n packages: previousBasket.packages.filter(p => p.id !== packageId),\n });\n }\n\n return { previousBasket, ident };\n },\n onError: (_error, _packageId, context) => {\n if (context?.previousBasket !== undefined && context.ident !== null) {\n queryClient.setQueryData(tebexKeys.basket(context.ident), context.previousBasket);\n }\n config.onError?.(TebexError.fromUnknown(_error));\n },\n onSuccess: (data, _packageId, context) => {\n const ident = context.ident ?? basketIdentRef.current;\n if (ident !== null) {\n queryClient.setQueryData(tebexKeys.basket(ident), data);\n }\n },\n });\n\n const updateQuantityMutation = useMutation<Basket, Error, UpdateQuantityParams, BasketMutationContext>({\n scope: { id: 'basket-mutations' },\n mutationFn: async (params: UpdateQuantityParams): Promise<Basket> => {\n if (!isPositiveInteger(params.quantity)) {\n throw new TebexError(\n TebexErrorCode.INVALID_QUANTITY,\n 'Quantity must be a positive integer',\n );\n }\n\n if (basketIdent === null) {\n throw new TebexError(TebexErrorCode.BASKET_NOT_FOUND);\n }\n const tebex = getTebexClient();\n await tebex.updateQuantity(basketIdent, params.packageId, params.quantity);\n return tebex.getBasket(basketIdent);\n },\n onMutate: async (params): Promise<BasketMutationContext> => {\n const ident = basketIdentRef.current;\n\n if (ident === null) {\n return { previousBasket: undefined, ident };\n }\n\n await queryClient.cancelQueries({ queryKey: tebexKeys.basket(ident) });\n\n const previousBasket = queryClient.getQueryData<Basket | null>(tebexKeys.basket(ident));\n\n if (previousBasket !== null && previousBasket !== undefined) {\n queryClient.setQueryData<Basket>(tebexKeys.basket(ident), {\n ...previousBasket,\n packages: previousBasket.packages.map(p =>\n p.id === params.packageId\n ? { ...p, in_basket: { ...p.in_basket, quantity: params.quantity } }\n : p,\n ),\n });\n }\n\n return { previousBasket, ident };\n },\n onError: (_error, _params, context) => {\n if (context?.previousBasket !== undefined && context.ident !== null) {\n queryClient.setQueryData(tebexKeys.basket(context.ident), context.previousBasket);\n }\n config.onError?.(TebexError.fromUnknown(_error));\n },\n onSuccess: (data, _params, context) => {\n const ident = context.ident ?? basketIdentRef.current;\n if (ident !== null) {\n queryClient.setQueryData(tebexKeys.basket(ident), data);\n }\n },\n });\n\n const clearBasket = useCallback(() => {\n clearBasketIdent();\n queryClient.removeQueries({ queryKey: tebexKeys.baskets() });\n }, [clearBasketIdent, queryClient]);\n\n const basket = basketQuery.data ?? null;\n\n const packages = useMemo(() => basket?.packages ?? [], [basket?.packages]);\n\n const itemCount = useMemo(\n () => packages.reduce((acc, pkg) => acc + pkg.in_basket.quantity, 0),\n [packages],\n );\n\n const total = useMemo(() => basket?.total_price ?? 0, [basket?.total_price]);\n\n const combinedError =\n basketQuery.error ??\n addMutation.error ??\n removeMutation.error ??\n updateQuantityMutation.error;\n const wrappedError = useMemo(\n () => (combinedError !== null ? TebexError.fromUnknown(combinedError) : null),\n [combinedError],\n );\n\n const addPackage = useCallback(\n async (params: AddPackageParams): Promise<void> => {\n await addMutation.mutateAsync(params);\n },\n [addMutation],\n );\n\n const removePackage = useCallback(\n async (packageId: number): Promise<void> => {\n await removeMutation.mutateAsync(packageId);\n },\n [removeMutation],\n );\n\n const updateQuantity = useCallback(\n async (params: UpdateQuantityParams): Promise<void> => {\n await updateQuantityMutation.mutateAsync(params);\n },\n [updateQuantityMutation],\n );\n\n return {\n basket,\n data: basket,\n basketIdent,\n packages,\n isLoading: basketQuery.isLoading,\n isFetching: basketQuery.isFetching,\n isAddingPackage: addMutation.isPending,\n isRemovingPackage: removeMutation.isPending,\n isUpdatingQuantity: updateQuantityMutation.isPending,\n error: wrappedError,\n errorCode: wrappedError?.code ?? null,\n addPackage,\n removePackage,\n updateQuantity,\n clearBasket,\n refetch: basketQuery.refetch,\n itemCount,\n total,\n isEmpty: packages.length === 0,\n };\n}\n","'use client';\n\nimport { useQuery } from '@tanstack/react-query';\nimport { useCallback, useMemo, useRef } from 'react';\nimport type { Category } from 'tebex_headless';\n\nimport { TebexError } from '../errors/TebexError';\nimport { tebexKeys } from '../queries/keys';\nimport { getTebexClient } from '../services/api';\nimport type { UseCategoriesOptions, UseCategoriesReturn } from '../types/hooks';\n\n/**\n * Hook to fetch all categories from the Tebex store.\n *\n * @param options - Configuration options\n * @returns Categories data and helper methods\n *\n * @example\n * ```tsx\n * const { categories, isLoading, getByName } = useCategories();\n *\n * if (isLoading) return <Spinner />;\n *\n * const vipCategory = getByName('VIP');\n * ```\n */\nexport function useCategories(options: UseCategoriesOptions = {}): UseCategoriesReturn {\n const { includePackages = true, enabled = true } = options;\n\n const query = useQuery({\n queryKey: tebexKeys.categoriesList(includePackages),\n queryFn: async (): Promise<Category[]> => {\n const tebex = getTebexClient();\n return tebex.getCategories(includePackages);\n },\n enabled,\n staleTime: 5 * 60 * 1000,\n });\n\n const error = useMemo(\n () => (query.error !== null ? TebexError.fromUnknown(query.error) : null),\n [query.error],\n );\n\n const dataRef = useRef(query.data);\n dataRef.current = query.data;\n\n const getByName = useCallback(\n (name: string) =>\n dataRef.current?.find(category => category.name.toLowerCase() === name.toLowerCase()),\n [],\n );\n\n const getById = useCallback(\n (id: number) => dataRef.current?.find(category => category.id === id),\n [],\n );\n\n const getBySlug = useCallback(\n (slug: string) => dataRef.current?.find(category => category.slug === slug),\n [],\n );\n\n return {\n categories: query.data ?? null,\n data: query.data ?? null,\n isLoading: query.isLoading,\n isFetching: query.isFetching,\n error,\n errorCode: error?.code ?? null,\n refetch: query.refetch,\n getByName,\n getById,\n getBySlug,\n };\n}\n","'use client';\n\nimport { useQuery } from '@tanstack/react-query';\nimport { useMemo } from 'react';\nimport type { Category } from 'tebex_headless';\n\nimport { TebexError } from '../errors/TebexError';\nimport { tebexKeys } from '../queries/keys';\nimport { getTebexClient } from '../services/api';\nimport type { UseCategoryOptions, UseCategoryReturn } from '../types/hooks';\n\n/**\n * Hook to fetch a single category by ID.\n *\n * @param options - Configuration options including the category ID\n * @returns Category data\n *\n * @example\n * ```tsx\n * const { category, isLoading } = useCategory({ id: 123 });\n *\n * if (isLoading) return <Spinner />;\n * if (!category) return <NotFound />;\n *\n * return <CategoryDisplay category={category} />;\n * ```\n */\nexport function useCategory(options: UseCategoryOptions): UseCategoryReturn {\n const { id, enabled = true } = options;\n\n const query = useQuery({\n queryKey: tebexKeys.category(id),\n queryFn: async (): Promise<Category> => {\n const tebex = getTebexClient();\n return tebex.getCategory(id);\n },\n enabled: enabled && id > 0 && Number.isInteger(id),\n staleTime: 5 * 60 * 1000,\n });\n\n const error = useMemo(\n () => (query.error !== null ? TebexError.fromUnknown(query.error) : null),\n [query.error],\n );\n\n return {\n category: query.data ?? null,\n data: query.data ?? null,\n isLoading: query.isLoading,\n isFetching: query.isFetching,\n error,\n errorCode: error?.code ?? null,\n refetch: query.refetch,\n };\n}\n","'use client';\n\nimport { useMutation } from '@tanstack/react-query';\nimport { useCallback, useMemo } from 'react';\n\nimport { TebexError } from '../errors/TebexError';\nimport { TebexErrorCode } from '../errors/codes';\nimport { useTebexConfig } from '../provider/TebexProvider';\nimport type { UseCheckoutOptions, UseCheckoutReturn } from '../types/hooks';\nimport { useBasket } from './useBasket';\n\n/**\n * Tebex.js checkout interface.\n * Loaded from https://js.tebex.io/v/1.js\n */\ninterface TebexCheckout {\n init: (options: { ident: string }) => void;\n launch: () => void;\n on: (event: string, callback: (data?: unknown) => void) => void;\n close: () => void;\n}\n\ndeclare global {\n interface Window {\n Tebex?: {\n checkout: TebexCheckout;\n };\n }\n}\n\n/** Timeout for checkout sessions to prevent promises from hanging forever. */\nconst CHECKOUT_TIMEOUT_MS = 30 * 60 * 1000; // 30 minutes\n\n/**\n * Generation counter to prevent stale event handlers from interfering.\n * Each new checkout launch increments this counter, and handlers check\n * their generation against the current value before acting.\n */\nlet checkoutGeneration = 0;\n\n/**\n * Hook to launch the Tebex checkout modal.\n *\n * @param options - Checkout callbacks\n * @returns Checkout state and launch function\n *\n * @example\n * ```tsx\n * const { launch, canCheckout, isLaunching } = useCheckout({\n * onSuccess: () => router.push('/thank-you'),\n * onError: (error) => toast.error(error.message),\n * });\n *\n * return (\n * <button onClick={launch} disabled={!canCheckout || isLaunching}>\n * Checkout\n * </button>\n * );\n * ```\n */\nexport function useCheckout(options: UseCheckoutOptions = {}): UseCheckoutReturn {\n const { basket, basketIdent, clearBasket, isEmpty } = useBasket();\n const config = useTebexConfig();\n\n const launchMutation = useMutation({\n mutationFn: async (): Promise<void> => {\n if (basketIdent === null || basket === null) {\n throw new TebexError(TebexErrorCode.BASKET_NOT_FOUND);\n }\n\n if (isEmpty) {\n throw new TebexError(TebexErrorCode.BASKET_EMPTY, 'Basket is empty');\n }\n\n if (typeof window === 'undefined') {\n throw new TebexError(TebexErrorCode.TEBEX_JS_NOT_LOADED, 'Cannot checkout on server side.');\n }\n\n const tebexGlobal = window.Tebex;\n if (tebexGlobal === undefined) {\n throw new TebexError(\n TebexErrorCode.TEBEX_JS_NOT_LOADED,\n 'Tebex.js not loaded. Add <script src=\"https://js.tebex.io/v/1.9.0.js\"></script> to your page.',\n );\n }\n\n return new Promise<void>((resolve, reject) => {\n const tebexCheckout = tebexGlobal.checkout;\n let isSettled = false;\n\n const currentGeneration = ++checkoutGeneration;\n\n const handleComplete = (): void => {\n if (currentGeneration !== checkoutGeneration || isSettled) return;\n isSettled = true;\n cleanup();\n clearBasket();\n options.onSuccess?.();\n resolve();\n };\n\n const handleError = (data?: unknown): void => {\n if (currentGeneration !== checkoutGeneration || isSettled) return;\n isSettled = true;\n cleanup();\n const error = new TebexError(TebexErrorCode.CHECKOUT_FAILED, String(data));\n options.onError?.(error);\n config.onError?.(error);\n reject(error);\n };\n\n const handleClose = (): void => {\n if (currentGeneration !== checkoutGeneration || isSettled) return;\n isSettled = true;\n cleanup();\n options.onClose?.();\n resolve();\n };\n\n let observer: MutationObserver | null = null;\n let debounceTimer: ReturnType<typeof setTimeout> | null = null;\n\n const timeoutId = setTimeout(() => {\n if (!isSettled) {\n isSettled = true;\n cleanup();\n reject(new TebexError(TebexErrorCode.TIMEOUT, 'Checkout session timed out'));\n }\n }, CHECKOUT_TIMEOUT_MS);\n\n // Tebex.js doesn't support off(), so we rely on isSettled flag\n const cleanup = (): void => {\n clearTimeout(timeoutId);\n if (observer !== null) {\n observer.disconnect();\n observer = null;\n }\n if (debounceTimer !== null) {\n clearTimeout(debounceTimer);\n debounceTimer = null;\n }\n };\n\n const findTebexModal = (): Element | null =>\n document.querySelector('iframe[src*=\"tebex\"]') ??\n document.querySelector('[class*=\"tebex-js\"]') ??\n document.querySelector('tebex-checkout[open]');\n\n const setupModalObserver = (): void => {\n let modalWasOpen = false;\n\n const checkModal = (): void => {\n if (isSettled) return;\n\n const modal = findTebexModal();\n\n if (modal !== null) {\n modalWasOpen = true;\n } else if (modalWasOpen) {\n handleClose();\n }\n };\n\n observer = new MutationObserver(() => {\n if (isSettled) return;\n if (debounceTimer !== null) {\n clearTimeout(debounceTimer);\n }\n debounceTimer = setTimeout(checkModal, 50);\n });\n\n observer.observe(document.body, {\n childList: true,\n subtree: true,\n });\n\n if (findTebexModal() !== null) {\n modalWasOpen = true;\n }\n };\n\n tebexCheckout.init({ ident: basketIdent });\n\n tebexCheckout.on('payment:complete', handleComplete);\n tebexCheckout.on('payment:error', handleError);\n tebexCheckout.on('close', handleClose);\n\n tebexCheckout.launch();\n\n setupModalObserver();\n });\n },\n });\n\n const launch = useCallback(async (): Promise<void> => {\n await launchMutation.mutateAsync();\n }, [launchMutation]);\n\n const error = useMemo(\n () => (launchMutation.error !== null ? TebexError.fromUnknown(launchMutation.error) : null),\n [launchMutation.error],\n );\n\n return {\n launch,\n isLaunching: launchMutation.isPending,\n error,\n errorCode: error?.code ?? null,\n canCheckout: basket !== null && !isEmpty,\n checkoutUrl: basket?.links.checkout ?? null,\n };\n}\n","'use client';\n\nimport { useMutation, useQueryClient } from '@tanstack/react-query';\nimport { useCallback, useMemo, useRef } from 'react';\nimport type { Basket } from 'tebex_headless';\n\nimport { TebexError } from '../errors/TebexError';\nimport { TebexErrorCode } from '../errors/codes';\nimport { useTebexConfig } from '../provider/TebexProvider';\nimport { tebexKeys } from '../queries/keys';\nimport { getTebexClient } from '../services/api';\nimport { useBasketStore } from '../stores/basketStore';\nimport type { UseCouponsReturn } from '../types/hooks';\nimport { useBasket } from './useBasket';\n\n/**\n * Hook to manage coupons on the basket with optimistic updates.\n *\n * @returns Coupon state and actions\n *\n * @example\n * ```tsx\n * const { coupons, apply, remove, isApplying } = useCoupons();\n *\n * const handleApply = async (code: string) => {\n * try {\n * await apply(code);\n * toast.success('Coupon applied!');\n * } catch (error) {\n * toast.error('Invalid coupon');\n * }\n * };\n * ```\n */\nexport function useCoupons(): UseCouponsReturn {\n const { basket } = useBasket();\n const basketIdent = useBasketStore(state => state.basketIdent);\n const basketIdentRef = useRef(basketIdent);\n basketIdentRef.current = basketIdent;\n const queryClient = useQueryClient();\n const config = useTebexConfig();\n\n const applyMutation = useMutation({\n scope: { id: 'basket-mutations' },\n mutationFn: async (couponCode: string): Promise<Basket> => {\n const ident = basketIdentRef.current;\n if (ident === null) {\n throw new TebexError(TebexErrorCode.BASKET_NOT_FOUND);\n }\n const tebex = getTebexClient();\n await tebex.apply(ident, 'coupons', { coupon_code: couponCode });\n return tebex.getBasket(ident);\n },\n onMutate: async couponCode => {\n const ident = basketIdentRef.current;\n if (ident === null) return;\n await queryClient.cancelQueries({ queryKey: tebexKeys.basket(ident) });\n const previousBasket = queryClient.getQueryData<Basket>(tebexKeys.basket(ident));\n if (previousBasket !== undefined) {\n queryClient.setQueryData<Basket>(tebexKeys.basket(ident), {\n ...previousBasket,\n coupons: [...previousBasket.coupons, { code: couponCode }],\n });\n }\n\n return { previousBasket, ident };\n },\n onError: (_error, _couponCode, context) => {\n if (context?.previousBasket !== undefined) {\n queryClient.setQueryData(tebexKeys.basket(context.ident), context.previousBasket);\n }\n config.onError?.(TebexError.fromUnknown(_error));\n },\n onSuccess: (data, _couponCode, context) => {\n const ident = context?.ident ?? basketIdentRef.current;\n if (ident !== null) {\n queryClient.setQueryData(tebexKeys.basket(ident), data);\n }\n },\n });\n\n const removeMutation = useMutation({\n scope: { id: 'basket-mutations' },\n mutationFn: async (couponCode: string): Promise<Basket> => {\n const ident = basketIdentRef.current;\n if (ident === null) {\n throw new TebexError(TebexErrorCode.BASKET_NOT_FOUND);\n }\n const tebex = getTebexClient();\n await tebex.remove(ident, 'coupons', { coupon_code: couponCode });\n return tebex.getBasket(ident);\n },\n onMutate: async couponCode => {\n const ident = basketIdentRef.current;\n if (ident === null) return;\n await queryClient.cancelQueries({ queryKey: tebexKeys.basket(ident) });\n const previousBasket = queryClient.getQueryData<Basket>(tebexKeys.basket(ident));\n if (previousBasket !== undefined) {\n queryClient.setQueryData<Basket>(tebexKeys.basket(ident), {\n ...previousBasket,\n coupons: previousBasket.coupons.filter(c => c.code !== couponCode),\n });\n }\n\n return { previousBasket, ident };\n },\n onError: (_error, _couponCode, context) => {\n if (context?.previousBasket !== undefined) {\n queryClient.setQueryData(tebexKeys.basket(context.ident), context.previousBasket);\n }\n config.onError?.(TebexError.fromUnknown(_error));\n },\n onSuccess: (data, _couponCode, context) => {\n const ident = context?.ident ?? basketIdentRef.current;\n if (ident !== null) {\n queryClient.setQueryData(tebexKeys.basket(ident), data);\n }\n },\n });\n\n const apply = useCallback(\n async (couponCode: string): Promise<void> => {\n await applyMutation.mutateAsync(couponCode);\n },\n [applyMutation],\n );\n\n const remove = useCallback(\n async (couponCode: string): Promise<void> => {\n await removeMutation.mutateAsync(couponCode);\n },\n [removeMutation],\n );\n\n const combinedError = applyMutation.error ?? removeMutation.error;\n const error = useMemo(\n () => (combinedError !== null ? TebexError.fromUnknown(combinedError) : null),\n [combinedError],\n );\n\n return {\n coupons: basket?.coupons ?? [],\n apply,\n remove,\n isApplying: applyMutation.isPending,\n isRemoving: removeMutation.isPending,\n error,\n errorCode: error?.code ?? null,\n };\n}\n","'use client';\n\nimport { useMutation, useQueryClient } from '@tanstack/react-query';\nimport { useCallback, useMemo, useRef } from 'react';\nimport type { Basket } from 'tebex_headless';\n\nimport { TebexError } from '../errors/TebexError';\nimport { TebexErrorCode } from '../errors/codes';\nimport { useTebexConfig } from '../provider/TebexProvider';\nimport { tebexKeys } from '../queries/keys';\nimport { getTebexClient } from '../services/api';\nimport { useBasketStore } from '../stores/basketStore';\nimport type { UseCreatorCodesReturn } from '../types/hooks';\nimport { useBasket } from './useBasket';\n\n/**\n * Hook to manage creator codes on the basket with optimistic updates.\n *\n * @returns Creator code state and actions\n *\n * @example\n * ```tsx\n * const { creatorCode, apply, remove, isApplying } = useCreatorCodes();\n *\n * const handleApply = async (code: string) => {\n * try {\n * await apply(code);\n * toast.success('Creator code applied!');\n * } catch (error) {\n * toast.error('Invalid creator code');\n * }\n * };\n * ```\n */\nexport function useCreatorCodes(): UseCreatorCodesReturn {\n const { basket } = useBasket();\n const basketIdent = useBasketStore(state => state.basketIdent);\n const basketIdentRef = useRef(basketIdent);\n basketIdentRef.current = basketIdent;\n const queryClient = useQueryClient();\n const config = useTebexConfig();\n\n const applyMutation = useMutation({\n scope: { id: 'basket-mutations' },\n mutationFn: async (code: string): Promise<Basket> => {\n const ident = basketIdentRef.current;\n if (ident === null) {\n throw new TebexError(TebexErrorCode.BASKET_NOT_FOUND);\n }\n const tebex = getTebexClient();\n await tebex.apply(ident, 'creator-codes', { creator_code: code });\n return tebex.getBasket(ident);\n },\n onMutate: async code => {\n const ident = basketIdentRef.current;\n if (ident === null) return;\n await queryClient.cancelQueries({ queryKey: tebexKeys.basket(ident) });\n\n const previousBasket = queryClient.getQueryData<Basket>(tebexKeys.basket(ident));\n if (previousBasket !== undefined) {\n queryClient.setQueryData<Basket>(tebexKeys.basket(ident), {\n ...previousBasket,\n creator_code: code,\n });\n }\n\n return { previousBasket, ident };\n },\n onError: (_error, _code, context) => {\n if (context?.previousBasket !== undefined) {\n queryClient.setQueryData(tebexKeys.basket(context.ident), context.previousBasket);\n }\n config.onError?.(TebexError.fromUnknown(_error));\n },\n onSuccess: (data, _code, context) => {\n const ident = context?.ident ?? basketIdentRef.current;\n if (ident !== null) {\n queryClient.setQueryData(tebexKeys.basket(ident), data);\n }\n },\n });\n\n const removeMutation = useMutation({\n scope: { id: 'basket-mutations' },\n mutationFn: async (): Promise<Basket> => {\n const ident = basketIdentRef.current;\n if (ident === null) {\n throw new TebexError(TebexErrorCode.BASKET_NOT_FOUND);\n }\n const tebex = getTebexClient();\n await tebex.remove(ident, 'creator-codes', { creator_code: '' });\n return tebex.getBasket(ident);\n },\n onMutate: async () => {\n const ident = basketIdentRef.current;\n if (ident === null) return;\n await queryClient.cancelQueries({ queryKey: tebexKeys.basket(ident) });\n\n const previousBasket = queryClient.getQueryData<Basket>(tebexKeys.basket(ident));\n if (previousBasket !== undefined) {\n queryClient.setQueryData<Basket>(tebexKeys.basket(ident), {\n ...previousBasket,\n creator_code: '',\n });\n }\n\n return { previousBasket, ident };\n },\n onError: (_error, _, context) => {\n if (context?.previousBasket !== undefined) {\n queryClient.setQueryData(tebexKeys.basket(context.ident), context.previousBasket);\n }\n config.onError?.(TebexError.fromUnknown(_error));\n },\n onSuccess: (data, _, context) => {\n const ident = context?.ident ?? basketIdentRef.current;\n if (ident !== null) {\n queryClient.setQueryData(tebexKeys.basket(ident), data);\n }\n },\n });\n\n const apply = useCallback(\n async (code: string): Promise<void> => {\n await applyMutation.mutateAsync(code);\n },\n [applyMutation],\n );\n\n const remove = useCallback(async (): Promise<void> => {\n await removeMutation.mutateAsync();\n }, [removeMutation]);\n\n const combinedError = applyMutation.error ?? removeMutation.error;\n const error = useMemo(\n () => (combinedError !== null ? TebexError.fromUnknown(combinedError) : null),\n [combinedError],\n );\n\n return {\n creatorCode: basket?.creator_code ?? null,\n apply,\n remove,\n isApplying: applyMutation.isPending,\n isRemoving: removeMutation.isPending,\n error,\n errorCode: error?.code ?? null,\n };\n}\n","'use client';\n\nimport { useMutation, useQueryClient } from '@tanstack/react-query';\nimport { useCallback, useMemo, useRef } from 'react';\nimport type { Basket } from 'tebex_headless';\n\nimport { TebexError } from '../errors/TebexError';\nimport { TebexErrorCode } from '../errors/codes';\nimport { useTebexConfig } from '../provider/TebexProvider';\nimport { tebexKeys } from '../queries/keys';\nimport { getTebexClient } from '../services/api';\nimport { useBasketStore } from '../stores/basketStore';\nimport type { UseGiftCardsReturn } from '../types/hooks';\nimport { useBasket } from './useBasket';\n\n/**\n * Hook to manage gift cards on the basket with optimistic updates.\n *\n * @returns Gift card state and actions\n *\n * @example\n * ```tsx\n * const { giftCards, apply, remove, isApplying } = useGiftCards();\n *\n * const handleApply = async (cardNumber: string) => {\n * try {\n * await apply(cardNumber);\n * toast.success('Gift card applied!');\n * } catch (error) {\n * toast.error('Invalid gift card');\n * }\n * };\n * ```\n */\nexport function useGiftCards(): UseGiftCardsReturn {\n const { basket } = useBasket();\n const basketIdent = useBasketStore(state => state.basketIdent);\n const basketIdentRef = useRef(basketIdent);\n basketIdentRef.current = basketIdent;\n const queryClient = useQueryClient();\n const config = useTebexConfig();\n\n const applyMutation = useMutation({\n scope: { id: 'basket-mutations' },\n mutationFn: async (cardNumber: string): Promise<Basket> => {\n const ident = basketIdentRef.current;\n if (ident === null) {\n throw new TebexError(TebexErrorCode.BASKET_NOT_FOUND);\n }\n const tebex = getTebexClient();\n await tebex.apply(ident, 'giftcards', { card_number: cardNumber });\n return tebex.getBasket(ident);\n },\n onMutate: async cardNumber => {\n const ident = basketIdentRef.current;\n if (ident === null) return;\n await queryClient.cancelQueries({ queryKey: tebexKeys.basket(ident) });\n\n const previousBasket = queryClient.getQueryData<Basket>(tebexKeys.basket(ident));\n if (previousBasket !== undefined) {\n queryClient.setQueryData<Basket>(tebexKeys.basket(ident), {\n ...previousBasket,\n giftcards: [...previousBasket.giftcards, { card_number: cardNumber }],\n });\n }\n\n return { previousBasket, ident };\n },\n onError: (_error, _cardNumber, context) => {\n if (context?.previousBasket !== undefined) {\n queryClient.setQueryData(tebexKeys.basket(context.ident), context.previousBasket);\n }\n config.onError?.(TebexError.fromUnknown(_error));\n },\n onSuccess: (data, _cardNumber, context) => {\n const ident = context?.ident ?? basketIdentRef.current;\n if (ident !== null) {\n queryClient.setQueryData(tebexKeys.basket(ident), data);\n }\n },\n });\n\n const removeMutation = useMutation({\n scope: { id: 'basket-mutations' },\n mutationFn: async (cardNumber: string): Promise<Basket> => {\n const ident = basketIdentRef.current;\n if (ident === null) {\n throw new TebexError(TebexErrorCode.BASKET_NOT_FOUND);\n }\n const tebex = getTebexClient();\n await tebex.remove(ident, 'giftcards', { card_number: cardNumber });\n return tebex.getBasket(ident);\n },\n onMutate: async cardNumber => {\n const ident = basketIdentRef.current;\n if (ident === null) return;\n await queryClient.cancelQueries({ queryKey: tebexKeys.basket(ident) });\n\n const previousBasket = queryClient.getQueryData<Basket>(tebexKeys.basket(ident));\n if (previousBasket !== undefined) {\n queryClient.setQueryData<Basket>(tebexKeys.basket(ident), {\n ...previousBasket,\n giftcards: previousBasket.giftcards.filter(g => g.card_number !== cardNumber),\n });\n }\n\n return { previousBasket, ident };\n },\n onError: (_error, _cardNumber, context) => {\n if (context?.previousBasket !== undefined) {\n queryClient.setQueryData(tebexKeys.basket(context.ident), context.previousBasket);\n }\n config.onError?.(TebexError.fromUnknown(_error));\n },\n onSuccess: (data, _cardNumber, context) => {\n const ident = context?.ident ?? basketIdentRef.current;\n if (ident !== null) {\n queryClient.setQueryData(tebexKeys.basket(ident), data);\n }\n },\n });\n\n const apply = useCallback(\n async (cardNumber: string): Promise<void> => {\n await applyMutation.mutateAsync(cardNumber);\n },\n [applyMutation],\n );\n\n const remove = useCallback(\n async (cardNumber: string): Promise<void> => {\n await removeMutation.mutateAsync(cardNumber);\n },\n [removeMutation],\n );\n\n const combinedError = applyMutation.error ?? removeMutation.error;\n const error = useMemo(\n () => (combinedError !== null ? TebexError.fromUnknown(combinedError) : null),\n [combinedError],\n );\n\n return {\n giftCards: basket?.giftcards ?? [],\n apply,\n remove,\n isApplying: applyMutation.isPending,\n isRemoving: removeMutation.isPending,\n error,\n errorCode: error?.code ?? null,\n };\n}\n","'use client';\n\nimport { useMutation, useQueryClient } from '@tanstack/react-query';\nimport { useCallback, useMemo, useRef } from 'react';\nimport type { Basket, BasketPackage } from 'tebex_headless';\n\nimport { TebexError } from '../errors/TebexError';\nimport { TebexErrorCode } from '../errors/codes';\nimport { useTebexConfig } from '../provider/TebexProvider';\nimport { tebexKeys } from '../queries/keys';\nimport { getTebexClient } from '../services/api';\nimport { useBasketStore } from '../stores/basketStore';\nimport { useUserStore } from '../stores/userStore';\nimport { isPositiveInteger, isValidMinecraftUsername } from '../types/guards';\nimport type { GiftPackageParams, UseGiftPackageReturn } from '../types/hooks';\n\n/**\n * Hook to gift a package to another player with optimistic updates.\n *\n * @returns Gift package state and action\n *\n * @example\n * ```tsx\n * const { gift, isGifting, error } = useGiftPackage();\n *\n * const handleGift = async () => {\n * await gift({\n * packageId: 123,\n * targetUsername: 'FriendName',\n * quantity: 1,\n * });\n * };\n * ```\n */\nexport function useGiftPackage(): UseGiftPackageReturn {\n const basketIdent = useBasketStore(state => state.basketIdent);\n const basketIdentRef = useRef(basketIdent);\n basketIdentRef.current = basketIdent;\n const setBasketIdent = useBasketStore(state => state.setBasketIdent);\n const username = useUserStore(state => state.username);\n const queryClient = useQueryClient();\n const config = useTebexConfig();\n\n const giftMutation = useMutation({\n scope: { id: 'basket-mutations' },\n mutationFn: async (params: GiftPackageParams): Promise<Basket> => {\n if (username === null || username.length === 0) {\n throw new TebexError(\n TebexErrorCode.NOT_AUTHENTICATED,\n 'Username is required to gift a package',\n );\n }\n\n if (!isValidMinecraftUsername(params.targetUsername)) {\n throw new TebexError(\n TebexErrorCode.INVALID_USERNAME,\n 'Target username must be 3-16 alphanumeric characters',\n );\n }\n\n const quantity = params.quantity ?? 1;\n if (!isPositiveInteger(quantity)) {\n throw new TebexError(\n TebexErrorCode.INVALID_QUANTITY,\n 'Quantity must be a positive integer',\n );\n }\n\n const tebex = getTebexClient();\n\n let ident = useBasketStore.getState().basketIdent;\n if (ident === null) {\n const newBasket = await tebex.createMinecraftBasket(\n username,\n config.completeUrl,\n config.cancelUrl,\n );\n ident = newBasket.ident;\n setBasketIdent(ident);\n }\n\n await tebex.addPackageToBasket(ident, params.packageId, quantity, 'single', {\n gift_username: params.targetUsername,\n });\n\n return tebex.getBasket(ident);\n },\n onMutate: async params => {\n const ident = basketIdentRef.current;\n if (ident === null) return;\n await queryClient.cancelQueries({ queryKey: tebexKeys.basket(ident) });\n const previousBasket = queryClient.getQueryData<Basket>(tebexKeys.basket(ident));\n if (previousBasket !== undefined) {\n const optimisticPackage: BasketPackage = {\n id: params.packageId,\n name: 'Loading...',\n description: '',\n image: null,\n in_basket: {\n quantity: params.quantity ?? 1,\n price: 0,\n gift_username_id: null,\n gift_username: params.targetUsername,\n },\n };\n\n queryClient.setQueryData<Basket>(tebexKeys.basket(ident), {\n ...previousBasket,\n packages: [...previousBasket.packages, optimisticPackage],\n });\n }\n\n return { previousBasket, ident };\n },\n onError: (_error, _params, context) => {\n if (context?.previousBasket !== undefined) {\n queryClient.setQueryData(tebexKeys.basket(context.ident), context.previousBasket);\n }\n config.onError?.(TebexError.fromUnknown(_error));\n },\n onSuccess: (data, _params, context) => {\n const ident = context?.ident ?? basketIdentRef.current;\n if (ident !== null) {\n queryClient.setQueryData(tebexKeys.basket(ident), data);\n }\n },\n });\n\n const gift = useCallback(\n async (params: GiftPackageParams): Promise<void> => {\n await giftMutation.mutateAsync(params);\n },\n [giftMutation],\n );\n\n const error = useMemo(\n () => (giftMutation.error !== null ? TebexError.fromUnknown(giftMutation.error) : null),\n [giftMutation.error],\n );\n\n return {\n gift,\n isGifting: giftMutation.isPending,\n error,\n errorCode: error?.code ?? null,\n };\n}\n","'use client';\n\nimport { useQuery } from '@tanstack/react-query';\nimport { useMemo } from 'react';\nimport type { Package } from 'tebex_headless';\n\nimport { TebexError } from '../errors/TebexError';\nimport { tebexKeys } from '../queries/keys';\nimport { getTebexClient } from '../services/api';\nimport type { UsePackageOptions, UsePackageReturn } from '../types/hooks';\n\n/**\n * Hook to fetch a single package by ID.\n *\n * @param options - Configuration options including the package ID\n * @returns Package data\n *\n * @example\n * ```tsx\n * const { package: pkg, isLoading } = usePackage({ id: 123 });\n *\n * if (isLoading) return <Spinner />;\n * if (!pkg) return <NotFound />;\n *\n * return <PackageDisplay package={pkg} />;\n * ```\n */\nexport function usePackage(options: UsePackageOptions): UsePackageReturn {\n const { id, enabled = true } = options;\n\n const query = useQuery({\n queryKey: tebexKeys.package(id),\n queryFn: async (): Promise<Package> => {\n const tebex = getTebexClient();\n return tebex.getPackage(id);\n },\n enabled: enabled && id > 0 && Number.isInteger(id),\n staleTime: 5 * 60 * 1000,\n });\n\n const error = useMemo(\n () => (query.error !== null ? TebexError.fromUnknown(query.error) : null),\n [query.error],\n );\n\n return {\n package: query.data ?? null,\n data: query.data ?? null,\n isLoading: query.isLoading,\n isFetching: query.isFetching,\n error,\n errorCode: error?.code ?? null,\n refetch: query.refetch,\n };\n}\n","'use client';\n\nimport { useQuery } from '@tanstack/react-query';\nimport { useCallback, useMemo, useRef } from 'react';\nimport type { Package } from 'tebex_headless';\n\nimport { TebexError } from '../errors/TebexError';\nimport { tebexKeys } from '../queries/keys';\nimport { getTebexClient } from '../services/api';\nimport type { UsePackagesOptions, UsePackagesReturn } from '../types/hooks';\n\n/**\n * Hook to fetch all packages from the Tebex store.\n * Optionally filter by category.\n *\n * @param options - Configuration options\n * @returns Packages data and helper methods\n *\n * @example\n * ```tsx\n * const { packages, isLoading, getById } = usePackages();\n *\n * // Or filter by category\n * const { packages } = usePackages({ categoryId: 123 });\n * ```\n */\nexport function usePackages(options: UsePackagesOptions = {}): UsePackagesReturn {\n const { categoryId, enabled = true } = options;\n\n const query = useQuery({\n queryKey: tebexKeys.packagesList(categoryId),\n queryFn: async (): Promise<Package[]> => {\n const tebex = getTebexClient();\n\n if (categoryId !== undefined) {\n const category = await tebex.getCategory(categoryId);\n return category.packages;\n }\n\n const categories = await tebex.getCategories(true);\n const allPackages: Package[] = [];\n\n for (const category of categories) {\n allPackages.push(...category.packages);\n }\n\n return allPackages;\n },\n enabled,\n staleTime: 5 * 60 * 1000,\n });\n\n const error = useMemo(\n () => (query.error !== null ? TebexError.fromUnknown(query.error) : null),\n [query.error],\n );\n\n const dataRef = useRef(query.data);\n dataRef.current = query.data;\n\n const getById = useCallback(\n (id: number) => dataRef.current?.find(pkg => pkg.id === id),\n [],\n );\n\n const getByName = useCallback(\n (name: string) =>\n dataRef.current?.find(pkg => pkg.name.toLowerCase() === name.toLowerCase()),\n [],\n );\n\n return {\n packages: query.data ?? null,\n data: query.data ?? null,\n isLoading: query.isLoading,\n isFetching: query.isFetching,\n error,\n errorCode: error?.code ?? null,\n refetch: query.refetch,\n getById,\n getByName,\n };\n}\n","'use client';\n\nimport { useCallback } from 'react';\n\nimport { useUserStore } from '../stores/userStore';\nimport { isValidMinecraftUsername } from '../types/guards';\nimport type { UseUserReturn } from '../types/hooks';\n\n/**\n * Hook to manage the current user (Minecraft username).\n * Username is persisted in localStorage.\n *\n * @returns User state and actions\n *\n * @example\n * ```tsx\n * const { username, setUsername, isAuthenticated, isValidUsername } = useUser();\n *\n * if (!isAuthenticated) {\n * return <UsernameForm onSubmit={setUsername} />;\n * }\n *\n * return <p>Welcome, {username}!</p>;\n * ```\n */\nexport function useUser(): UseUserReturn {\n const username = useUserStore(state => state.username);\n const setUsernameStore = useUserStore(state => state.setUsername);\n const clearUsernameStore = useUserStore(state => state.clearUsername);\n\n const setUsername = useCallback(\n (newUsername: string): boolean => {\n const trimmed = newUsername.trim();\n if (isValidMinecraftUsername(trimmed)) {\n setUsernameStore(trimmed);\n return true;\n }\n return false;\n },\n [setUsernameStore],\n );\n\n const clearUsername = useCallback(() => {\n clearUsernameStore();\n }, [clearUsernameStore]);\n\n const isAuthenticated = username !== null && username.length > 0;\n\n return {\n username,\n setUsername,\n clearUsername,\n isAuthenticated,\n };\n}\n","'use client';\n\nimport { useQuery } from '@tanstack/react-query';\nimport { useMemo } from 'react';\nimport type { Webstore } from 'tebex_headless';\n\nimport { TebexError } from '../errors/TebexError';\nimport { tebexKeys } from '../queries/keys';\nimport { getTebexClient } from '../services/api';\nimport type { UseWebstoreReturn, WebstoreData } from '../types/hooks';\n\n/**\n * Currency object as returned by the actual Tebex API (differs from type definition).\n */\ninterface CurrencyObject {\n readonly iso_4217: string;\n readonly symbol: string;\n}\n\n/**\n * Type guard for currency objects returned by the Tebex API.\n */\nfunction isCurrencyObject(value: unknown): value is CurrencyObject {\n return (\n typeof value === 'object' &&\n value !== null &&\n 'iso_4217' in value &&\n typeof (value as { iso_4217: unknown }).iso_4217 === 'string'\n );\n}\n\n/**\n * Transforms the Tebex Webstore response to our WebstoreData type.\n */\nfunction transformWebstore(webstore: Webstore): WebstoreData {\n const rawCurrency: unknown = webstore.currency;\n let currencyCode: string;\n if (isCurrencyObject(rawCurrency)) {\n currencyCode = rawCurrency.iso_4217;\n } else if (typeof rawCurrency === 'string') {\n currencyCode = rawCurrency;\n } else {\n currencyCode = 'USD';\n }\n\n return {\n id: webstore.id,\n name: webstore.name,\n description: webstore.description,\n currency: currencyCode,\n domain: webstore.webstore_url,\n logo: webstore.logo.length > 0 ? webstore.logo : null,\n };\n}\n\n/**\n * Hook to fetch webstore information.\n *\n * @returns Webstore data including name, currency, and domain\n *\n * @example\n * ```tsx\n * const { webstore, currency, isLoading } = useWebstore();\n *\n * if (isLoading) return <Spinner />;\n *\n * return (\n * <div>\n * <h1>{webstore?.name}</h1>\n * <p>Currency: {currency}</p>\n * </div>\n * );\n * ```\n */\nexport function useWebstore(): UseWebstoreReturn {\n const query = useQuery({\n queryKey: tebexKeys.webstore(),\n queryFn: async (): Promise<WebstoreData> => {\n const tebex = getTebexClient();\n const webstore = await tebex.getWebstore();\n return transformWebstore(webstore);\n },\n staleTime: 5 * 60 * 1000,\n });\n\n const error = useMemo(\n () => (query.error !== null ? TebexError.fromUnknown(query.error) : null),\n [query.error],\n );\n\n return {\n webstore: query.data ?? null,\n data: query.data ?? null,\n name: query.data?.name ?? null,\n currency: query.data?.currency ?? null,\n domain: query.data?.domain ?? null,\n isLoading: query.isLoading,\n isFetching: query.isFetching,\n error,\n errorCode: error?.code ?? null,\n refetch: query.refetch,\n };\n}\n","import type { TebexError } from '../errors/TebexError';\n\n/**\n * Discriminated union for type-safe result handling.\n * Use this for operations that can fail.\n */\nexport type Result<T, E = TebexError> =\n | { readonly success: true; readonly data: T }\n | { readonly success: false; readonly error: E };\n\n/**\n * Creates a successful result.\n */\nexport function ok<T>(data: T): Result<T, never> {\n return { success: true, data };\n}\n\n/**\n * Creates an error result.\n */\nexport function err<E>(error: E): Result<never, E> {\n return { success: false, error };\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TebexProvider.d.ts","sourceRoot":"","sources":["../../src/provider/TebexProvider.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAA+C,MAAM,uBAAuB,CAAC;AACjG,OAAO,
|
|
1
|
+
{"version":3,"file":"TebexProvider.d.ts","sourceRoot":"","sources":["../../src/provider/TebexProvider.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAA+C,MAAM,uBAAuB,CAAC;AACjG,OAAO,EAAgC,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAKrE,OAAO,KAAK,EAAuB,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAwCxE;;GAEG;AACH,UAAU,kBAAkB;IAC1B,QAAQ,CAAC,QAAQ,EAAE,SAAS,CAAC;IAC7B,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;IAC7B,mFAAmF;IACnF,QAAQ,CAAC,WAAW,CAAC,EAAE,WAAW,GAAG,SAAS,CAAC;CAChD;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,wBAAgB,aAAa,CAAC,EAC5B,QAAQ,EACR,MAAM,EACN,WAAW,EAAE,mBAAmB,GACjC,EAAE,kBAAkB,GAAG,SAAS,CAyChC;AAED,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../src/services/api.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../src/services/api.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAM/C;;;GAGG;AACH,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAEvD;AAED;;;GAGG;AACH,wBAAgB,cAAc,IAAI,aAAa,CAK9C;AAED;;GAEG;AACH,wBAAgB,wBAAwB,IAAI,OAAO,CAElD;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,IAAI,CAEvC"}
|
|
@@ -27,15 +27,17 @@ export declare const useBasketStore: import("zustand").UseBoundStore<Omit<Omit<i
|
|
|
27
27
|
fireImmediately?: boolean;
|
|
28
28
|
} | undefined): () => void;
|
|
29
29
|
};
|
|
30
|
-
}, "persist"> & {
|
|
30
|
+
}, "setState" | "persist"> & {
|
|
31
|
+
setState(partial: BasketStore | Partial<BasketStore> | ((state: BasketStore) => BasketStore | Partial<BasketStore>), replace?: false | undefined): unknown;
|
|
32
|
+
setState(state: BasketStore | ((state: BasketStore) => BasketStore), replace: true): unknown;
|
|
31
33
|
persist: {
|
|
32
|
-
setOptions: (options: Partial<import("zustand/middleware").PersistOptions<BasketStore,
|
|
34
|
+
setOptions: (options: Partial<import("zustand/middleware").PersistOptions<BasketStore, Pick<BasketStoreState, "basketIdent">, unknown>>) => void;
|
|
33
35
|
clearStorage: () => void;
|
|
34
36
|
rehydrate: () => Promise<void> | void;
|
|
35
37
|
hasHydrated: () => boolean;
|
|
36
38
|
onHydrate: (fn: (state: BasketStore) => void) => () => void;
|
|
37
39
|
onFinishHydration: (fn: (state: BasketStore) => void) => () => void;
|
|
38
|
-
getOptions: () => Partial<import("zustand/middleware").PersistOptions<BasketStore,
|
|
40
|
+
getOptions: () => Partial<import("zustand/middleware").PersistOptions<BasketStore, Pick<BasketStoreState, "basketIdent">, unknown>>;
|
|
39
41
|
};
|
|
40
42
|
}>;
|
|
41
43
|
export type { BasketStore, BasketStoreActions, BasketStoreState };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"basketStore.d.ts","sourceRoot":"","sources":["../../src/stores/basketStore.ts"],"names":[],"mappings":"AAKA;;GAEG;AACH,UAAU,gBAAgB;IACxB,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;CACrC;AAED;;GAEG;AACH,UAAU,kBAAkB;IAC1B,QAAQ,CAAC,cAAc,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACjD,QAAQ,CAAC,gBAAgB,EAAE,MAAM,IAAI,CAAC;CACvC;AAED;;GAEG;AACH,KAAK,WAAW,GAAG,gBAAgB,GAAG,kBAAkB,CAAC;AAEzD;;;GAGG;AACH,eAAO,MAAM,cAAc
|
|
1
|
+
{"version":3,"file":"basketStore.d.ts","sourceRoot":"","sources":["../../src/stores/basketStore.ts"],"names":[],"mappings":"AAKA;;GAEG;AACH,UAAU,gBAAgB;IACxB,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;CACrC;AAED;;GAEG;AACH,UAAU,kBAAkB;IAC1B,QAAQ,CAAC,cAAc,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACjD,QAAQ,CAAC,gBAAgB,EAAE,MAAM,IAAI,CAAC;CACvC;AAED;;GAEG;AACH,KAAK,WAAW,GAAG,gBAAgB,GAAG,kBAAkB,CAAC;AAEzD;;;GAGG;AACH,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;EAgC1B,CAAC;AAEF,YAAY,EAAE,WAAW,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,CAAC"}
|
|
@@ -27,15 +27,17 @@ export declare const useUserStore: import("zustand").UseBoundStore<Omit<Omit<imp
|
|
|
27
27
|
fireImmediately?: boolean;
|
|
28
28
|
} | undefined): () => void;
|
|
29
29
|
};
|
|
30
|
-
}, "persist"> & {
|
|
30
|
+
}, "setState" | "persist"> & {
|
|
31
|
+
setState(partial: UserStore | Partial<UserStore> | ((state: UserStore) => UserStore | Partial<UserStore>), replace?: false | undefined): unknown;
|
|
32
|
+
setState(state: UserStore | ((state: UserStore) => UserStore), replace: true): unknown;
|
|
31
33
|
persist: {
|
|
32
|
-
setOptions: (options: Partial<import("zustand/middleware").PersistOptions<UserStore,
|
|
34
|
+
setOptions: (options: Partial<import("zustand/middleware").PersistOptions<UserStore, Pick<UserStoreState, "username">, unknown>>) => void;
|
|
33
35
|
clearStorage: () => void;
|
|
34
36
|
rehydrate: () => Promise<void> | void;
|
|
35
37
|
hasHydrated: () => boolean;
|
|
36
38
|
onHydrate: (fn: (state: UserStore) => void) => () => void;
|
|
37
39
|
onFinishHydration: (fn: (state: UserStore) => void) => () => void;
|
|
38
|
-
getOptions: () => Partial<import("zustand/middleware").PersistOptions<UserStore,
|
|
40
|
+
getOptions: () => Partial<import("zustand/middleware").PersistOptions<UserStore, Pick<UserStoreState, "username">, unknown>>;
|
|
39
41
|
};
|
|
40
42
|
}>;
|
|
41
43
|
export type { UserStore, UserStoreActions, UserStoreState };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"userStore.d.ts","sourceRoot":"","sources":["../../src/stores/userStore.ts"],"names":[],"mappings":"AAOA;;GAEG;AACH,UAAU,cAAc;IACtB,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CAClC;AAED;;GAEG;AACH,UAAU,gBAAgB;IACxB,QAAQ,CAAC,WAAW,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IACjD,QAAQ,CAAC,aAAa,EAAE,MAAM,IAAI,CAAC;CACpC;AAED;;GAEG;AACH,KAAK,SAAS,GAAG,cAAc,GAAG,gBAAgB,CAAC;AAEnD;;;GAGG;AACH,eAAO,MAAM,YAAY
|
|
1
|
+
{"version":3,"file":"userStore.d.ts","sourceRoot":"","sources":["../../src/stores/userStore.ts"],"names":[],"mappings":"AAOA;;GAEG;AACH,UAAU,cAAc;IACtB,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CAClC;AAED;;GAEG;AACH,UAAU,gBAAgB;IACxB,QAAQ,CAAC,WAAW,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IACjD,QAAQ,CAAC,aAAa,EAAE,MAAM,IAAI,CAAC;CACpC;AAED;;GAEG;AACH,KAAK,SAAS,GAAG,cAAc,GAAG,gBAAgB,CAAC;AAEnD;;;GAGG;AACH,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;EAiCxB,CAAC;AAEF,YAAY,EAAE,SAAS,EAAE,gBAAgB,EAAE,cAAc,EAAE,CAAC"}
|
package/dist/testing/index.cjs
CHANGED
|
@@ -1,2 +1,4 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
|
|
2
|
+
'use strict';var reactQuery=require('@tanstack/react-query'),react=require('react'),zustand=require('zustand'),middleware=require('zustand/middleware'),jsxRuntime=require('react/jsx-runtime');var m=react.createContext(null);var o={all:["tebex"],categories:()=>[...o.all,"categories"],categoriesList:e=>[...o.categories(),"list",{includePackages:e}],category:e=>[...o.categories(),"detail",e],packages:()=>[...o.all,"packages"],packagesList:e=>[...o.packages(),"list",{categoryId:e}],package:e=>[...o.packages(),"detail",e],baskets:()=>[...o.all,"baskets"],basket:e=>[...o.baskets(),e],webstore:()=>[...o.all,"webstore"]};var p=zustand.create()(middleware.subscribeWithSelector(middleware.persist(e=>({basketIdent:null,setBasketIdent:t=>{e({basketIdent:t});},clearBasketIdent:()=>{e({basketIdent:null});}}),{name:"tebex-basket-store",skipHydration:true,version:1,partialize:e=>({basketIdent:e.basketIdent}),migrate:e=>e,onRehydrateStorage:()=>(e,t)=>{t!==void 0&&console.warn("[tebex] Failed to rehydrate basket store:",t);}})));var b=zustand.create()(middleware.subscribeWithSelector(middleware.persist(e=>({username:null,setUsername:t=>{e({username:t});},clearUsername:()=>{e({username:null}),p.getState().clearBasketIdent();}}),{name:"tebex-user-store",skipHydration:true,version:1,partialize:e=>({username:e.username}),migrate:e=>e,onRehydrateStorage:()=>(e,t)=>{t!==void 0&&console.warn("[tebex] Failed to rehydrate user store:",t);}})));var y={id:1,name:"Test Store",description:"A test Tebex store for development",currency:"EUR",domain:"test.tebex.io",logo:null},n=[{id:101,name:"VIP Gold",description:"Gold VIP membership with exclusive perks",type:"single",disable_gifting:false,disable_quantity:false,expiration_date:null,base_price:9.99,sales_tax:0,total_price:9.99,currency:"EUR",image:null,category:{id:1,name:"VIP Ranks"},discount:0,created_at:"2024-01-01T00:00:00Z",updated_at:"2024-01-01T00:00:00Z",order:1},{id:102,name:"VIP Diamond",description:"Diamond VIP membership with all perks",type:"single",disable_gifting:false,disable_quantity:false,expiration_date:null,base_price:19.99,sales_tax:0,total_price:19.99,currency:"EUR",image:null,category:{id:1,name:"VIP Ranks"},discount:0,created_at:"2024-01-01T00:00:00Z",updated_at:"2024-01-01T00:00:00Z",order:2},{id:201,name:"Pet Pack",description:"Adorable pet companions",type:"single",disable_gifting:false,disable_quantity:false,expiration_date:null,base_price:4.99,sales_tax:0,total_price:4.99,currency:"EUR",image:null,category:{id:2,name:"Cosmetics"},discount:0,created_at:"2024-01-01T00:00:00Z",updated_at:"2024-01-01T00:00:00Z",order:1},{id:202,name:"Trail Effects",description:"Particle trail effects",type:"single",disable_gifting:false,disable_quantity:false,expiration_date:null,base_price:2.99,sales_tax:0,total_price:2.99,currency:"EUR",image:null,category:{id:2,name:"Cosmetics"},discount:0,created_at:"2024-01-01T00:00:00Z",updated_at:"2024-01-01T00:00:00Z",order:2},{id:301,name:"1000 Coins",description:"In-game currency pack",type:"single",disable_gifting:false,disable_quantity:false,expiration_date:null,base_price:1.99,sales_tax:0,total_price:1.99,currency:"EUR",image:null,category:{id:3,name:"Currency"},discount:0,created_at:"2024-01-01T00:00:00Z",updated_at:"2024-01-01T00:00:00Z",order:1}],g=[{id:1,name:"VIP Ranks",description:"Exclusive VIP memberships",parent:null,order:1,display_type:"grid",slug:"vip-ranks",packages:n.filter(e=>e.category.id===1)},{id:2,name:"Cosmetics",description:"Cosmetic items and effects",parent:null,order:2,display_type:"grid",slug:"cosmetics",packages:n.filter(e=>e.category.id===2)},{id:3,name:"Currency",description:"In-game currency packs",parent:null,order:3,display_type:"grid",slug:"currency",packages:n.filter(e=>e.category.id===3)}],d={ident:"mock-basket-001",complete:false,id:1,country:"US",ip:"127.0.0.1",username_id:null,username:null,cancel_url:"https://example.com/cancel",complete_url:"https://example.com/complete",complete_auto_redirect:false,base_price:0,sales_tax:0,total_price:0,email:"",currency:"EUR",packages:[],coupons:[],giftcards:[],creator_code:"",links:{checkout:"https://checkout.tebex.io/mock"},custom:{}};function M(e,t=1,r=null){return {id:e.id,name:e.name,description:e.description,image:e.image,in_basket:{quantity:t,price:e.base_price*t,gift_username_id:null,gift_username:r}}}function l(e,t){let r=e.map(s=>M(s.package,s.quantity??1,s.giftUsername??null)),a=r.reduce((s,i)=>s+i.in_basket.price,0);return {...d,packages:r,total_price:a,base_price:a,...t}}function f(e){return {code:e}}function x(e){return {card_number:e}}var V={webstore:y,categories:g,packages:n,emptyBasket:d,basketWithOneItem:l([{package:n[0],quantity:1}]),basketWithMultipleItems:l([{package:n[0],quantity:1},{package:n[2],quantity:2}]),basketWithCoupon:{...l([{package:n[0],quantity:1}]),coupons:[f("SAVE10")]},basketWithGiftCard:{...l([{package:n[0],quantity:1}]),giftcards:[x("GIFT-1234-5678")]},basketWithCreatorCode:{...l([{package:n[0],quantity:1}]),creator_code:"STREAMER123"},helpers:{createBasketPackage:M,createMockBasket:l,createMockCoupon:f,createMockGiftCard:x},getPackageById:e=>n.find(t=>t.id===e),getCategoryById:e=>g.find(t=>t.id===e)};function q(){return new reactQuery.QueryClient({defaultOptions:{queries:{staleTime:1/0,gcTime:1/0,retry:false,refetchOnMount:false,refetchOnWindowFocus:false,refetchOnReconnect:false},mutations:{retry:false}}})}function O(e,t){let r=e.replace(/\/$/,"");return {publicKey:"mock-public-key",baseUrl:r,completeUrl:`${r}/shop/complete`,cancelUrl:`${r}/shop/cancel`,onError:t}}function F(e,t){e.setQueryData(o.webstore(),{id:t.webstore.id,name:t.webstore.name,description:t.webstore.description,currency:t.webstore.currency,domain:t.webstore.domain,logo:t.webstore.logo}),e.setQueryData(o.categoriesList(true),t.categories),e.setQueryData(o.categoriesList(false),t.categories.map(a=>({...a,packages:[]})));for(let a of t.categories)e.setQueryData(o.category(a.id),a);e.setQueryData(o.packagesList(),t.packages);let r=new Map;for(let a of t.packages){let s=a.category.id,i=r.get(s)??[];r.set(s,[...i,a]);}for(let[a,s]of r)e.setQueryData(o.packagesList(a),s);for(let a of t.packages)e.setQueryData(o.package(a.id),a);t.basket!==null&&t.basketIdent!==null&&e.setQueryData(o.basket(t.basketIdent),t.basket);}function L({username:e,basketIdent:t}){let r=b(c=>c.setUsername),a=b(c=>c.clearUsername),s=p(c=>c.setBasketIdent),i=p(c=>c.clearBasketIdent);return react.useEffect(()=>{e!==null?r(e):a();},[e,r,a]),react.useEffect(()=>{t!==null?s(t):i();},[t,s,i]),null}function N({children:e,mockData:t,username:r="TestPlayer",withBasket:a=true,baseUrl:s="https://mock.tebex.io",onError:i}){let c=react.useMemo(()=>{let I={...y,...t?.webstore},v=t?.categories??g,U=t?.packages??n,k=null,B=null;return a&&(k=t?.basket?{...d,...t.basket}:d,B=k.ident,r!==null&&(k={...k,username:r})),{webstore:I,categories:v,packages:U,basket:k,basketIdent:B}},[t,a,r]),[u]=react.useState(()=>q()),P=react.useMemo(()=>O(s,i),[s,i]);react.useEffect(()=>{F(u,c);},[u,c]);let S=react.useMemo(()=>({config:P,queryClient:u}),[P,u]);return jsxRuntime.jsx(m.Provider,{value:S,children:jsxRuntime.jsxs(reactQuery.QueryClientProvider,{client:u,children:[jsxRuntime.jsx(L,{username:r,basketIdent:c.basketIdent}),e]})})}function $(){let e=react.useContext(m);return e!==null&&e.config.publicKey==="mock-public-key"}
|
|
3
|
+
exports.TebexMockProvider=N;exports.createBasketPackage=M;exports.createMockBasket=l;exports.createMockCoupon=f;exports.createMockGiftCard=x;exports.defaultMockBasket=d;exports.defaultMockCategories=g;exports.defaultMockPackages=n;exports.defaultMockWebstore=y;exports.mockData=V;exports.useIsMockProvider=$;//# sourceMappingURL=index.cjs.map
|
|
4
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/provider/context.ts","../../src/queries/keys.ts","../../src/stores/basketStore.ts","../../src/stores/userStore.ts","../../src/testing/mockData.ts","../../src/testing/TebexMockProvider.tsx"],"names":["TebexContext","createContext","tebexKeys","includePackages","id","categoryId","ident","useBasketStore","create","subscribeWithSelector","persist","set","state","persistedState","_state","error","useUserStore","username","defaultMockWebstore","defaultMockPackages","defaultMockCategories","p","defaultMockBasket","createBasketPackage","pkg","quantity","giftUsername","createMockBasket","items","overrides","packages","item","totalPrice","sum","createMockCoupon","code","createMockGiftCard","cardNumber","mockData","c","createMockQueryClient","QueryClient","resolveMockConfig","baseUrl","onError","cleanBaseUrl","populateMockData","queryClient","config","cat","category","packagesByCategory","existing","MockStoreSync","basketIdent","setUsername","clearUsername","setBasketIdent","clearBasketIdent","useEffect","TebexMockProvider","children","mockDataConfig","withBasket","resolvedMockData","useMemo","webstore","categories","basket","useState","resolvedConfig","contextValue","jsx","jsxs","QueryClientProvider","useIsMockProvider","context","useContext"],"mappings":"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","file":"index.cjs","sourcesContent":["'use client';\n\nimport type { QueryClient } from '@tanstack/react-query';\nimport { createContext, useContext } from 'react';\n\nimport { TebexError } from '../errors/TebexError';\nimport { TebexErrorCode } from '../errors/codes';\nimport type { ResolvedTebexConfig } from '../types/config';\n\n/**\n * Context value provided by TebexProvider.\n */\nexport interface TebexContextValue {\n readonly config: ResolvedTebexConfig;\n readonly queryClient: QueryClient;\n}\n\n/**\n * Tebex context for sharing configuration and QueryClient.\n * Used by both TebexProvider and TebexMockProvider.\n */\nexport const TebexContext = createContext<TebexContextValue | null>(null);\n\n/**\n * Hook to access the Tebex context.\n * Must be used within a TebexProvider or TebexMockProvider.\n *\n * @throws TebexError if used outside of a provider\n */\nexport function useTebexContext(): TebexContextValue {\n const context = useContext(TebexContext);\n\n if (context === null) {\n throw new TebexError(\n TebexErrorCode.PROVIDER_NOT_FOUND,\n 'useTebexContext must be used within TebexProvider or TebexMockProvider',\n );\n }\n\n return context;\n}\n\n/**\n * Hook to access just the Tebex configuration.\n * Useful when you don't need the QueryClient.\n */\nexport function useTebexConfig(): ResolvedTebexConfig {\n const { config } = useTebexContext();\n return config;\n}\n","/**\n * Query keys factory for TanStack Query.\n * Follows the recommended pattern for granular cache invalidation.\n *\n * @see https://tkdodo.eu/blog/effective-react-query-keys\n */\nexport const tebexKeys = {\n /** Root key for all Tebex queries */\n all: ['tebex'] as const,\n\n // ============ Categories ============\n\n /** All category-related queries */\n categories: () => [...tebexKeys.all, 'categories'] as const,\n\n /** Categories list with include packages option */\n categoriesList: (includePackages: boolean) =>\n [...tebexKeys.categories(), 'list', { includePackages }] as const,\n\n /** Single category by ID */\n category: (id: number) => [...tebexKeys.categories(), 'detail', id] as const,\n\n // ============ Packages ============\n\n /** All package-related queries */\n packages: () => [...tebexKeys.all, 'packages'] as const,\n\n /** Packages list, optionally filtered by category */\n packagesList: (categoryId?: number) => [...tebexKeys.packages(), 'list', { categoryId }] as const,\n\n /** Single package by ID */\n package: (id: number) => [...tebexKeys.packages(), 'detail', id] as const,\n\n // ============ Basket ============\n\n /** All basket-related queries */\n baskets: () => [...tebexKeys.all, 'baskets'] as const,\n\n /** Specific basket by ident */\n basket: (ident: string | null) => [...tebexKeys.baskets(), ident] as const,\n\n // ============ Webstore ============\n\n /** Webstore info query */\n webstore: () => [...tebexKeys.all, 'webstore'] as const,\n} as const;\n\n/**\n * Type helper for extracting query key types.\n */\ntype KeyFunctions = Omit<typeof tebexKeys, 'all'>;\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype ExtractReturnType<T> = T extends (...args: any[]) => infer R ? R : never;\nexport type TebexQueryKey =\n | (typeof tebexKeys)['all']\n | ExtractReturnType<KeyFunctions[keyof KeyFunctions]>;\n","'use client';\n\nimport { create } from 'zustand';\nimport { persist, subscribeWithSelector } from 'zustand/middleware';\n\n/**\n * Basket store state interface.\n */\ninterface BasketStoreState {\n readonly basketIdent: string | null;\n}\n\n/**\n * Basket store actions interface.\n */\ninterface BasketStoreActions {\n readonly setBasketIdent: (ident: string) => void;\n readonly clearBasketIdent: () => void;\n}\n\n/**\n * Complete basket store type.\n */\ntype BasketStore = BasketStoreState & BasketStoreActions;\n\n/**\n * Zustand store for basket ident persistence.\n * Uses localStorage to persist the basket ident across sessions.\n */\nexport const useBasketStore = create<BasketStore>()(\n subscribeWithSelector(\n persist(\n set => ({\n basketIdent: null,\n setBasketIdent: (ident: string) => {\n set({ basketIdent: ident });\n },\n clearBasketIdent: () => {\n set({ basketIdent: null });\n },\n }),\n {\n name: 'tebex-basket-store',\n // Skip hydration — rehydrated manually in TebexProvider\n skipHydration: true,\n version: 1,\n partialize: (state: BasketStore) => ({ basketIdent: state.basketIdent }),\n migrate: (persistedState: unknown) => {\n return persistedState as Pick<BasketStoreState, 'basketIdent'>;\n },\n onRehydrateStorage: () => {\n return (_state: unknown, error?: unknown) => {\n if (error !== undefined) {\n // eslint-disable-next-line no-console\n console.warn('[tebex] Failed to rehydrate basket store:', error);\n }\n };\n },\n },\n ),\n ),\n);\n\nexport type { BasketStore, BasketStoreActions, BasketStoreState };\n","'use client';\n\nimport { create } from 'zustand';\nimport { persist, subscribeWithSelector } from 'zustand/middleware';\n\nimport { useBasketStore } from './basketStore';\n\n/**\n * User store state interface.\n */\ninterface UserStoreState {\n readonly username: string | null;\n}\n\n/**\n * User store actions interface.\n */\ninterface UserStoreActions {\n readonly setUsername: (username: string) => void;\n readonly clearUsername: () => void;\n}\n\n/**\n * Complete user store type.\n */\ntype UserStore = UserStoreState & UserStoreActions;\n\n/**\n * Zustand store for user data persistence.\n * Uses localStorage to persist the username (Minecraft username) across sessions.\n */\nexport const useUserStore = create<UserStore>()(\n subscribeWithSelector(\n persist(\n set => ({\n username: null,\n setUsername: (username: string) => {\n set({ username });\n },\n clearUsername: () => {\n set({ username: null });\n useBasketStore.getState().clearBasketIdent();\n },\n }),\n {\n name: 'tebex-user-store',\n // Skip hydration — rehydrated manually in TebexProvider\n skipHydration: true,\n version: 1,\n partialize: (state: UserStore) => ({ username: state.username }),\n migrate: (persistedState: unknown) => {\n return persistedState as Pick<UserStoreState, 'username'>;\n },\n onRehydrateStorage: () => {\n return (_state: unknown, error?: unknown) => {\n if (error !== undefined) {\n // eslint-disable-next-line no-console\n console.warn('[tebex] Failed to rehydrate user store:', error);\n }\n };\n },\n },\n ),\n ),\n);\n\nexport type { UserStore, UserStoreActions, UserStoreState };\n","import type { Basket, BasketPackage, Category, Code, GiftCardCode, Package } from 'tebex_headless';\n\nimport type { WebstoreData } from '../types/hooks';\n\n/**\n * Mock webstore data for testing.\n */\nexport interface MockWebstoreData extends WebstoreData {\n readonly id: number;\n readonly name: string;\n readonly description: string;\n readonly currency: string;\n readonly domain: string;\n readonly logo: string | null;\n}\n\n/**\n * Mock package data for testing.\n * Extends the base Package type with required fields.\n */\nexport type MockPackage = Package;\n\n/**\n * Mock category data for testing.\n */\nexport type MockCategory = Category;\n\n/**\n * Mock basket data for testing.\n */\nexport type MockBasket = Basket;\n\n/**\n * Configuration for mock data.\n */\nexport interface MockDataConfig {\n readonly webstore?: Partial<MockWebstoreData> | undefined;\n readonly categories?: MockCategory[] | undefined;\n readonly packages?: MockPackage[] | undefined;\n readonly basket?: Partial<MockBasket> | undefined;\n readonly username?: string | null | undefined;\n}\n\n/**\n * Default mock webstore data.\n */\nexport const defaultMockWebstore: MockWebstoreData = {\n id: 1,\n name: 'Test Store',\n description: 'A test Tebex store for development',\n currency: 'EUR',\n domain: 'test.tebex.io',\n logo: null,\n};\n\n/**\n * Default mock packages organized by category.\n */\nexport const defaultMockPackages: MockPackage[] = [\n {\n id: 101,\n name: 'VIP Gold',\n description: 'Gold VIP membership with exclusive perks',\n type: 'single',\n disable_gifting: false,\n disable_quantity: false,\n expiration_date: null,\n base_price: 9.99,\n sales_tax: 0,\n total_price: 9.99,\n currency: 'EUR',\n image: null,\n category: { id: 1, name: 'VIP Ranks' },\n discount: 0,\n created_at: '2024-01-01T00:00:00Z',\n updated_at: '2024-01-01T00:00:00Z',\n order: 1,\n },\n {\n id: 102,\n name: 'VIP Diamond',\n description: 'Diamond VIP membership with all perks',\n type: 'single',\n disable_gifting: false,\n disable_quantity: false,\n expiration_date: null,\n base_price: 19.99,\n sales_tax: 0,\n total_price: 19.99,\n currency: 'EUR',\n image: null,\n category: { id: 1, name: 'VIP Ranks' },\n discount: 0,\n created_at: '2024-01-01T00:00:00Z',\n updated_at: '2024-01-01T00:00:00Z',\n order: 2,\n },\n {\n id: 201,\n name: 'Pet Pack',\n description: 'Adorable pet companions',\n type: 'single',\n disable_gifting: false,\n disable_quantity: false,\n expiration_date: null,\n base_price: 4.99,\n sales_tax: 0,\n total_price: 4.99,\n currency: 'EUR',\n image: null,\n category: { id: 2, name: 'Cosmetics' },\n discount: 0,\n created_at: '2024-01-01T00:00:00Z',\n updated_at: '2024-01-01T00:00:00Z',\n order: 1,\n },\n {\n id: 202,\n name: 'Trail Effects',\n description: 'Particle trail effects',\n type: 'single',\n disable_gifting: false,\n disable_quantity: false,\n expiration_date: null,\n base_price: 2.99,\n sales_tax: 0,\n total_price: 2.99,\n currency: 'EUR',\n image: null,\n category: { id: 2, name: 'Cosmetics' },\n discount: 0,\n created_at: '2024-01-01T00:00:00Z',\n updated_at: '2024-01-01T00:00:00Z',\n order: 2,\n },\n {\n id: 301,\n name: '1000 Coins',\n description: 'In-game currency pack',\n type: 'single',\n disable_gifting: false,\n disable_quantity: false,\n expiration_date: null,\n base_price: 1.99,\n sales_tax: 0,\n total_price: 1.99,\n currency: 'EUR',\n image: null,\n category: { id: 3, name: 'Currency' },\n discount: 0,\n created_at: '2024-01-01T00:00:00Z',\n updated_at: '2024-01-01T00:00:00Z',\n order: 1,\n },\n];\n\n/**\n * Default mock categories with packages.\n */\nexport const defaultMockCategories: MockCategory[] = [\n {\n id: 1,\n name: 'VIP Ranks',\n description: 'Exclusive VIP memberships',\n parent: null,\n order: 1,\n display_type: 'grid',\n slug: 'vip-ranks',\n packages: defaultMockPackages.filter(p => p.category.id === 1),\n },\n {\n id: 2,\n name: 'Cosmetics',\n description: 'Cosmetic items and effects',\n parent: null,\n order: 2,\n display_type: 'grid',\n slug: 'cosmetics',\n packages: defaultMockPackages.filter(p => p.category.id === 2),\n },\n {\n id: 3,\n name: 'Currency',\n description: 'In-game currency packs',\n parent: null,\n order: 3,\n display_type: 'grid',\n slug: 'currency',\n packages: defaultMockPackages.filter(p => p.category.id === 3),\n },\n];\n\n/**\n * Default empty basket.\n */\nexport const defaultMockBasket: MockBasket = {\n ident: 'mock-basket-001',\n complete: false,\n id: 1,\n country: 'US',\n ip: '127.0.0.1',\n username_id: null,\n username: null,\n cancel_url: 'https://example.com/cancel',\n complete_url: 'https://example.com/complete',\n complete_auto_redirect: false,\n base_price: 0,\n sales_tax: 0,\n total_price: 0,\n email: '',\n currency: 'EUR',\n packages: [],\n coupons: [],\n giftcards: [],\n creator_code: '',\n links: {\n checkout: 'https://checkout.tebex.io/mock',\n },\n custom: {},\n};\n\n/**\n * Create a basket package from a mock package.\n */\nexport function createBasketPackage(\n pkg: MockPackage,\n quantity = 1,\n giftUsername: string | null = null,\n): BasketPackage {\n return {\n id: pkg.id,\n name: pkg.name,\n description: pkg.description,\n image: pkg.image,\n in_basket: {\n quantity,\n price: pkg.base_price * quantity,\n gift_username_id: null,\n gift_username: giftUsername,\n },\n };\n}\n\n/**\n * Create a mock basket with items.\n */\nexport function createMockBasket(\n items: { package: MockPackage; quantity?: number; giftUsername?: string | null }[],\n overrides?: Partial<MockBasket>,\n): MockBasket {\n const packages = items.map(item =>\n createBasketPackage(item.package, item.quantity ?? 1, item.giftUsername ?? null),\n );\n\n const totalPrice = packages.reduce((sum, pkg) => sum + pkg.in_basket.price, 0);\n\n return {\n ...defaultMockBasket,\n packages,\n total_price: totalPrice,\n base_price: totalPrice,\n ...overrides,\n };\n}\n\n/**\n * Create a mock coupon.\n */\nexport function createMockCoupon(code: string): Code {\n return {\n code,\n };\n}\n\n/**\n * Create a mock gift card.\n */\nexport function createMockGiftCard(cardNumber: string): GiftCardCode {\n return {\n card_number: cardNumber,\n };\n}\n\n/**\n * Pre-built mock data for common testing scenarios.\n */\nexport const mockData = {\n /** Default webstore */\n webstore: defaultMockWebstore,\n\n /** All categories with packages */\n categories: defaultMockCategories,\n\n /** All packages flat list */\n packages: defaultMockPackages,\n\n /** Empty basket */\n emptyBasket: defaultMockBasket,\n\n /** Basket with one VIP Gold item */\n basketWithOneItem: createMockBasket([{ package: defaultMockPackages[0]!, quantity: 1 }]),\n\n /** Basket with multiple items */\n basketWithMultipleItems: createMockBasket([\n { package: defaultMockPackages[0]!, quantity: 1 },\n { package: defaultMockPackages[2]!, quantity: 2 },\n ]),\n\n /** Basket with coupon applied */\n basketWithCoupon: {\n ...createMockBasket([{ package: defaultMockPackages[0]!, quantity: 1 }]),\n coupons: [createMockCoupon('SAVE10')],\n },\n\n /** Basket with gift card applied */\n basketWithGiftCard: {\n ...createMockBasket([{ package: defaultMockPackages[0]!, quantity: 1 }]),\n giftcards: [createMockGiftCard('GIFT-1234-5678')],\n },\n\n /** Basket with creator code */\n basketWithCreatorCode: {\n ...createMockBasket([{ package: defaultMockPackages[0]!, quantity: 1 }]),\n creator_code: 'STREAMER123',\n },\n\n /** Helper functions */\n helpers: {\n createBasketPackage,\n createMockBasket,\n createMockCoupon,\n createMockGiftCard,\n },\n\n /** Get package by ID */\n getPackageById: (id: number): MockPackage | undefined => {\n return defaultMockPackages.find(p => p.id === id);\n },\n\n /** Get category by ID */\n getCategoryById: (id: number): MockCategory | undefined => {\n return defaultMockCategories.find(c => c.id === id);\n },\n} as const;\n\nexport type { Basket, BasketPackage, Category, Code, GiftCardCode, Package };\n","'use client';\n\nimport { QueryClient, QueryClientProvider } from '@tanstack/react-query';\nimport { useContext, useEffect, useMemo, useState, type ReactNode } from 'react';\n\nimport { TebexError } from '../errors/TebexError';\nimport { TebexContext, type TebexContextValue } from '../provider/context';\nimport { tebexKeys } from '../queries/keys';\nimport { useBasketStore } from '../stores/basketStore';\nimport { useUserStore } from '../stores/userStore';\nimport type { ResolvedTebexConfig } from '../types/config';\nimport {\n defaultMockBasket,\n defaultMockCategories,\n defaultMockPackages,\n defaultMockWebstore,\n type MockBasket,\n type MockCategory,\n type MockDataConfig,\n type MockPackage,\n type MockWebstoreData,\n} from './mockData';\n\n/**\n * Props for TebexMockProvider component.\n */\nexport interface TebexMockProviderProps {\n readonly children: ReactNode;\n\n /**\n * Mock data to use. If not provided, defaults will be used.\n */\n readonly mockData?: MockDataConfig | undefined;\n\n /**\n * Mock username to set in the user store.\n * @default 'TestPlayer'\n */\n readonly username?: string | null | undefined;\n\n /**\n * Whether to initialize a basket.\n * If true and mockData.basket is provided, that basket will be used.\n * If true and no basket is provided, an empty basket will be created.\n * @default true\n */\n readonly withBasket?: boolean | undefined;\n\n /**\n * Base URL for the mock store.\n * @default 'https://mock.tebex.io'\n */\n readonly baseUrl?: string | undefined;\n\n /**\n * Callback when an error occurs.\n */\n readonly onError?: ((error: TebexError) => void) | undefined;\n}\n\n/**\n * Create a QueryClient configured for mocking.\n * - Infinite staleTime so queries never auto-refetch\n * - No retries\n * - Instant garbage collection time for testing\n */\nfunction createMockQueryClient(): QueryClient {\n return new QueryClient({\n defaultOptions: {\n queries: {\n staleTime: Infinity,\n gcTime: Infinity,\n retry: false,\n refetchOnMount: false,\n refetchOnWindowFocus: false,\n refetchOnReconnect: false,\n },\n mutations: {\n retry: false,\n },\n },\n });\n}\n\n/**\n * Resolve mock config with defaults.\n */\nfunction resolveMockConfig(\n baseUrl: string,\n onError?: (error: TebexError) => void,\n): ResolvedTebexConfig {\n const cleanBaseUrl = baseUrl.replace(/\\/$/, '');\n\n return {\n publicKey: 'mock-public-key',\n baseUrl: cleanBaseUrl,\n completeUrl: `${cleanBaseUrl}/shop/complete`,\n cancelUrl: `${cleanBaseUrl}/shop/cancel`,\n onError,\n };\n}\n\n/**\n * Populate the QueryClient with mock data.\n */\nfunction populateMockData(\n queryClient: QueryClient,\n config: {\n webstore: MockWebstoreData;\n categories: MockCategory[];\n packages: MockPackage[];\n basket: MockBasket | null;\n basketIdent: string | null;\n },\n): void {\n // Webstore data\n queryClient.setQueryData(tebexKeys.webstore(), {\n id: config.webstore.id,\n name: config.webstore.name,\n description: config.webstore.description,\n currency: config.webstore.currency,\n domain: config.webstore.domain,\n logo: config.webstore.logo,\n });\n\n // Categories with packages\n queryClient.setQueryData(tebexKeys.categoriesList(true), config.categories);\n\n // Categories without packages\n queryClient.setQueryData(\n tebexKeys.categoriesList(false),\n config.categories.map(cat => ({ ...cat, packages: [] })),\n );\n\n // Individual categories\n for (const category of config.categories) {\n queryClient.setQueryData(tebexKeys.category(category.id), category);\n }\n\n // All packages\n queryClient.setQueryData(tebexKeys.packagesList(), config.packages);\n\n // Packages by category\n const packagesByCategory = new Map<number, MockPackage[]>();\n for (const pkg of config.packages) {\n const categoryId = pkg.category.id;\n const existing = packagesByCategory.get(categoryId) ?? [];\n packagesByCategory.set(categoryId, [...existing, pkg]);\n }\n for (const [categoryId, packages] of packagesByCategory) {\n queryClient.setQueryData(tebexKeys.packagesList(categoryId), packages);\n }\n\n // Individual packages\n for (const pkg of config.packages) {\n queryClient.setQueryData(tebexKeys.package(pkg.id), pkg);\n }\n\n // Basket (if provided)\n if (config.basket !== null && config.basketIdent !== null) {\n queryClient.setQueryData(tebexKeys.basket(config.basketIdent), config.basket);\n }\n}\n\n/**\n * Component to sync mock data with stores.\n */\nfunction MockStoreSync({\n username,\n basketIdent,\n}: {\n username: string | null;\n basketIdent: string | null;\n}): null {\n const setUsername = useUserStore(state => state.setUsername);\n const clearUsername = useUserStore(state => state.clearUsername);\n const setBasketIdent = useBasketStore(state => state.setBasketIdent);\n const clearBasketIdent = useBasketStore(state => state.clearBasketIdent);\n\n useEffect(() => {\n if (username !== null) {\n setUsername(username);\n } else {\n clearUsername();\n }\n }, [username, setUsername, clearUsername]);\n\n useEffect(() => {\n if (basketIdent !== null) {\n setBasketIdent(basketIdent);\n } else {\n clearBasketIdent();\n }\n }, [basketIdent, setBasketIdent, clearBasketIdent]);\n\n return null;\n}\n\n/**\n * TebexMockProvider - A mock provider for testing and Storybook.\n *\n * This provider pre-populates TanStack Query with mock data, allowing\n * you to render components that use Tebex hooks without making real API calls.\n *\n * **Features:**\n * - Pre-populated categories, packages, and webstore data\n * - Optional basket state\n * - No network requests (queries have infinite staleTime)\n * - Same context interface as TebexProvider\n *\n * **Limitations:**\n * - Mutations (addPackage, removePackage, etc.) won't persist changes\n * - For full mutation support, use MSW with the provided handlers\n *\n * @example Basic usage\n * ```tsx\n * import { TebexMockProvider, mockData } from '@neosianexus/super-tebex/testing';\n *\n * <TebexMockProvider>\n * <ShopPage />\n * </TebexMockProvider>\n * ```\n *\n * @example Custom mock data\n * ```tsx\n * <TebexMockProvider\n * mockData={{\n * webstore: { name: 'My Custom Store', currency: 'USD' },\n * basket: mockData.basketWithMultipleItems,\n * }}\n * username=\"CustomPlayer\"\n * >\n * <CheckoutPage />\n * </TebexMockProvider>\n * ```\n *\n * @example Without basket (for category/package browsing)\n * ```tsx\n * <TebexMockProvider withBasket={false}>\n * <CatalogPage />\n * </TebexMockProvider>\n * ```\n */\nexport function TebexMockProvider({\n children,\n mockData: mockDataConfig,\n username = 'TestPlayer',\n withBasket = true,\n baseUrl = 'https://mock.tebex.io',\n onError,\n}: TebexMockProviderProps): ReactNode {\n // Resolve mock data with defaults\n const resolvedMockData = useMemo(() => {\n const webstore: MockWebstoreData = {\n ...defaultMockWebstore,\n ...mockDataConfig?.webstore,\n };\n\n const categories = mockDataConfig?.categories ?? defaultMockCategories;\n const packages = mockDataConfig?.packages ?? defaultMockPackages;\n\n let basket: MockBasket | null = null;\n let basketIdent: string | null = null;\n\n if (withBasket) {\n basket = mockDataConfig?.basket\n ? { ...defaultMockBasket, ...mockDataConfig.basket }\n : defaultMockBasket;\n basketIdent = basket.ident;\n\n // Set username on basket if provided\n if (username !== null) {\n basket = { ...basket, username };\n }\n }\n\n return { webstore, categories, packages, basket, basketIdent };\n }, [mockDataConfig, withBasket, username]);\n\n // Create QueryClient once\n const [queryClient] = useState(() => createMockQueryClient());\n\n // Resolve config\n const resolvedConfig = useMemo(() => resolveMockConfig(baseUrl, onError), [baseUrl, onError]);\n\n // Populate mock data on mount and when data changes\n useEffect(() => {\n populateMockData(queryClient, resolvedMockData);\n }, [queryClient, resolvedMockData]);\n\n // Context value\n const contextValue = useMemo<TebexContextValue>(\n () => ({\n config: resolvedConfig,\n queryClient,\n }),\n [resolvedConfig, queryClient],\n );\n\n return (\n <TebexContext.Provider value={contextValue}>\n <QueryClientProvider client={queryClient}>\n <MockStoreSync username={username} basketIdent={resolvedMockData.basketIdent} />\n {children}\n </QueryClientProvider>\n </TebexContext.Provider>\n );\n}\n\n/**\n * Hook to check if we're inside a mock provider.\n * Useful for conditional logic in components.\n *\n * Note: This hook checks for any Tebex provider (real or mock).\n * The mock provider is identified by its configuration.\n */\nexport function useIsMockProvider(): boolean {\n const context = useContext(TebexContext);\n return context !== null && context.config.publicKey === 'mock-public-key';\n}\n"]}
|
package/dist/testing/index.js
CHANGED
|
@@ -1,2 +1,4 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
import{QueryClient
|
|
2
|
+
import {QueryClientProvider,QueryClient}from'@tanstack/react-query';import {createContext,useMemo,useState,useEffect,useContext}from'react';import {create}from'zustand';import {subscribeWithSelector,persist}from'zustand/middleware';import {jsx,jsxs}from'react/jsx-runtime';var m=createContext(null);var o={all:["tebex"],categories:()=>[...o.all,"categories"],categoriesList:e=>[...o.categories(),"list",{includePackages:e}],category:e=>[...o.categories(),"detail",e],packages:()=>[...o.all,"packages"],packagesList:e=>[...o.packages(),"list",{categoryId:e}],package:e=>[...o.packages(),"detail",e],baskets:()=>[...o.all,"baskets"],basket:e=>[...o.baskets(),e],webstore:()=>[...o.all,"webstore"]};var p=create()(subscribeWithSelector(persist(e=>({basketIdent:null,setBasketIdent:t=>{e({basketIdent:t});},clearBasketIdent:()=>{e({basketIdent:null});}}),{name:"tebex-basket-store",skipHydration:true,version:1,partialize:e=>({basketIdent:e.basketIdent}),migrate:e=>e,onRehydrateStorage:()=>(e,t)=>{t!==void 0&&console.warn("[tebex] Failed to rehydrate basket store:",t);}})));var b=create()(subscribeWithSelector(persist(e=>({username:null,setUsername:t=>{e({username:t});},clearUsername:()=>{e({username:null}),p.getState().clearBasketIdent();}}),{name:"tebex-user-store",skipHydration:true,version:1,partialize:e=>({username:e.username}),migrate:e=>e,onRehydrateStorage:()=>(e,t)=>{t!==void 0&&console.warn("[tebex] Failed to rehydrate user store:",t);}})));var y={id:1,name:"Test Store",description:"A test Tebex store for development",currency:"EUR",domain:"test.tebex.io",logo:null},n=[{id:101,name:"VIP Gold",description:"Gold VIP membership with exclusive perks",type:"single",disable_gifting:false,disable_quantity:false,expiration_date:null,base_price:9.99,sales_tax:0,total_price:9.99,currency:"EUR",image:null,category:{id:1,name:"VIP Ranks"},discount:0,created_at:"2024-01-01T00:00:00Z",updated_at:"2024-01-01T00:00:00Z",order:1},{id:102,name:"VIP Diamond",description:"Diamond VIP membership with all perks",type:"single",disable_gifting:false,disable_quantity:false,expiration_date:null,base_price:19.99,sales_tax:0,total_price:19.99,currency:"EUR",image:null,category:{id:1,name:"VIP Ranks"},discount:0,created_at:"2024-01-01T00:00:00Z",updated_at:"2024-01-01T00:00:00Z",order:2},{id:201,name:"Pet Pack",description:"Adorable pet companions",type:"single",disable_gifting:false,disable_quantity:false,expiration_date:null,base_price:4.99,sales_tax:0,total_price:4.99,currency:"EUR",image:null,category:{id:2,name:"Cosmetics"},discount:0,created_at:"2024-01-01T00:00:00Z",updated_at:"2024-01-01T00:00:00Z",order:1},{id:202,name:"Trail Effects",description:"Particle trail effects",type:"single",disable_gifting:false,disable_quantity:false,expiration_date:null,base_price:2.99,sales_tax:0,total_price:2.99,currency:"EUR",image:null,category:{id:2,name:"Cosmetics"},discount:0,created_at:"2024-01-01T00:00:00Z",updated_at:"2024-01-01T00:00:00Z",order:2},{id:301,name:"1000 Coins",description:"In-game currency pack",type:"single",disable_gifting:false,disable_quantity:false,expiration_date:null,base_price:1.99,sales_tax:0,total_price:1.99,currency:"EUR",image:null,category:{id:3,name:"Currency"},discount:0,created_at:"2024-01-01T00:00:00Z",updated_at:"2024-01-01T00:00:00Z",order:1}],g=[{id:1,name:"VIP Ranks",description:"Exclusive VIP memberships",parent:null,order:1,display_type:"grid",slug:"vip-ranks",packages:n.filter(e=>e.category.id===1)},{id:2,name:"Cosmetics",description:"Cosmetic items and effects",parent:null,order:2,display_type:"grid",slug:"cosmetics",packages:n.filter(e=>e.category.id===2)},{id:3,name:"Currency",description:"In-game currency packs",parent:null,order:3,display_type:"grid",slug:"currency",packages:n.filter(e=>e.category.id===3)}],d={ident:"mock-basket-001",complete:false,id:1,country:"US",ip:"127.0.0.1",username_id:null,username:null,cancel_url:"https://example.com/cancel",complete_url:"https://example.com/complete",complete_auto_redirect:false,base_price:0,sales_tax:0,total_price:0,email:"",currency:"EUR",packages:[],coupons:[],giftcards:[],creator_code:"",links:{checkout:"https://checkout.tebex.io/mock"},custom:{}};function M(e,t=1,r=null){return {id:e.id,name:e.name,description:e.description,image:e.image,in_basket:{quantity:t,price:e.base_price*t,gift_username_id:null,gift_username:r}}}function l(e,t){let r=e.map(s=>M(s.package,s.quantity??1,s.giftUsername??null)),a=r.reduce((s,i)=>s+i.in_basket.price,0);return {...d,packages:r,total_price:a,base_price:a,...t}}function f(e){return {code:e}}function x(e){return {card_number:e}}var V={webstore:y,categories:g,packages:n,emptyBasket:d,basketWithOneItem:l([{package:n[0],quantity:1}]),basketWithMultipleItems:l([{package:n[0],quantity:1},{package:n[2],quantity:2}]),basketWithCoupon:{...l([{package:n[0],quantity:1}]),coupons:[f("SAVE10")]},basketWithGiftCard:{...l([{package:n[0],quantity:1}]),giftcards:[x("GIFT-1234-5678")]},basketWithCreatorCode:{...l([{package:n[0],quantity:1}]),creator_code:"STREAMER123"},helpers:{createBasketPackage:M,createMockBasket:l,createMockCoupon:f,createMockGiftCard:x},getPackageById:e=>n.find(t=>t.id===e),getCategoryById:e=>g.find(t=>t.id===e)};function q(){return new QueryClient({defaultOptions:{queries:{staleTime:1/0,gcTime:1/0,retry:false,refetchOnMount:false,refetchOnWindowFocus:false,refetchOnReconnect:false},mutations:{retry:false}}})}function O(e,t){let r=e.replace(/\/$/,"");return {publicKey:"mock-public-key",baseUrl:r,completeUrl:`${r}/shop/complete`,cancelUrl:`${r}/shop/cancel`,onError:t}}function F(e,t){e.setQueryData(o.webstore(),{id:t.webstore.id,name:t.webstore.name,description:t.webstore.description,currency:t.webstore.currency,domain:t.webstore.domain,logo:t.webstore.logo}),e.setQueryData(o.categoriesList(true),t.categories),e.setQueryData(o.categoriesList(false),t.categories.map(a=>({...a,packages:[]})));for(let a of t.categories)e.setQueryData(o.category(a.id),a);e.setQueryData(o.packagesList(),t.packages);let r=new Map;for(let a of t.packages){let s=a.category.id,i=r.get(s)??[];r.set(s,[...i,a]);}for(let[a,s]of r)e.setQueryData(o.packagesList(a),s);for(let a of t.packages)e.setQueryData(o.package(a.id),a);t.basket!==null&&t.basketIdent!==null&&e.setQueryData(o.basket(t.basketIdent),t.basket);}function L({username:e,basketIdent:t}){let r=b(c=>c.setUsername),a=b(c=>c.clearUsername),s=p(c=>c.setBasketIdent),i=p(c=>c.clearBasketIdent);return useEffect(()=>{e!==null?r(e):a();},[e,r,a]),useEffect(()=>{t!==null?s(t):i();},[t,s,i]),null}function N({children:e,mockData:t,username:r="TestPlayer",withBasket:a=true,baseUrl:s="https://mock.tebex.io",onError:i}){let c=useMemo(()=>{let I={...y,...t?.webstore},v=t?.categories??g,U=t?.packages??n,k=null,B=null;return a&&(k=t?.basket?{...d,...t.basket}:d,B=k.ident,r!==null&&(k={...k,username:r})),{webstore:I,categories:v,packages:U,basket:k,basketIdent:B}},[t,a,r]),[u]=useState(()=>q()),P=useMemo(()=>O(s,i),[s,i]);useEffect(()=>{F(u,c);},[u,c]);let S=useMemo(()=>({config:P,queryClient:u}),[P,u]);return jsx(m.Provider,{value:S,children:jsxs(QueryClientProvider,{client:u,children:[jsx(L,{username:r,basketIdent:c.basketIdent}),e]})})}function $(){let e=useContext(m);return e!==null&&e.config.publicKey==="mock-public-key"}
|
|
3
|
+
export{N as TebexMockProvider,M as createBasketPackage,l as createMockBasket,f as createMockCoupon,x as createMockGiftCard,d as defaultMockBasket,g as defaultMockCategories,n as defaultMockPackages,y as defaultMockWebstore,V as mockData,$ as useIsMockProvider};//# sourceMappingURL=index.js.map
|
|
4
|
+
//# sourceMappingURL=index.js.map
|