@neosianexus/super-tebex 3.0.3 → 3.0.4

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.
Files changed (2) hide show
  1. package/README.md +404 -125
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -1,27 +1,33 @@
1
- # @neosia/tebex-nextjs
1
+ # @neosianexus/super-tebex
2
2
 
3
- Tebex Headless SDK optimized for Next.js App Router with TanStack Query and Zustand.
3
+ [![npm version](https://img.shields.io/npm/v/@neosianexus/super-tebex?color=blue)](https://www.npmjs.com/package/@neosianexus/super-tebex)
4
+ [![npm downloads](https://img.shields.io/npm/dm/@neosianexus/super-tebex)](https://www.npmjs.com/package/@neosianexus/super-tebex)
5
+ [![Coverage](https://img.shields.io/badge/coverage-97%25-brightgreen)](https://github.com/NeosiaNexus/super-tebex)
6
+ [![TypeScript](https://img.shields.io/badge/TypeScript-5.7-blue?logo=typescript&logoColor=white)](https://www.typescriptlang.org/)
7
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
8
+
9
+ > Tebex Headless SDK optimized for Next.js App Router with TanStack Query and Zustand.
4
10
 
5
11
  ## Features
6
12
 
7
13
  - **TanStack Query v5** - Automatic caching, retry, stale-while-revalidate
8
- - **Zustand v5** - Persisted client state (basket, user)
14
+ - **Zustand v5** - Persisted client state (basket, user) in localStorage
9
15
  - **TypeScript First** - Zero `any`, strict mode, exhaustive types
10
16
  - **Provider Pattern** - Single provider, granular hooks
11
- - **Error Codes** - i18n-friendly error handling with `TebexErrorCode`
17
+ - **Error Codes** - i18n-friendly error handling with `TebexErrorCode` enum
12
18
  - **Optimistic Updates** - Instant UI feedback on basket mutations
13
19
  - **React Query DevTools** - Automatic in development mode
14
20
 
15
21
  ## Installation
16
22
 
17
23
  ```bash
18
- npm install @neosia/tebex-nextjs
24
+ npm install @neosianexus/super-tebex
19
25
  # or
20
- yarn add @neosia/tebex-nextjs
26
+ yarn add @neosianexus/super-tebex
21
27
  # or
22
- pnpm add @neosia/tebex-nextjs
28
+ pnpm add @neosianexus/super-tebex
23
29
  # or
24
- bun add @neosia/tebex-nextjs
30
+ bun add @neosianexus/super-tebex
25
31
  ```
26
32
 
27
33
  ### Peer Dependencies
@@ -47,7 +53,7 @@ Wrap your app with `TebexProvider` in your root layout:
47
53
 
48
54
  ```tsx
49
55
  // app/layout.tsx
50
- import { TebexProvider } from '@neosia/tebex-nextjs';
56
+ import { TebexProvider } from '@neosianexus/super-tebex';
51
57
 
52
58
  export default function RootLayout({ children }: { children: React.ReactNode }) {
53
59
  return (
@@ -80,7 +86,7 @@ export default function RootLayout({ children }: { children: React.ReactNode })
80
86
  ```tsx
81
87
  'use client';
82
88
 
83
- import { useCategories, useBasket, useUser } from '@neosia/tebex-nextjs';
89
+ import { useCategories, useBasket, useUser } from '@neosianexus/super-tebex';
84
90
 
85
91
  export function Shop() {
86
92
  const { username, setUsername } = useUser();
@@ -111,44 +117,79 @@ export function Shop() {
111
117
  }
112
118
  ```
113
119
 
114
- ## Available Hooks
120
+ ---
121
+
122
+ ## API Reference
123
+
124
+ ### Provider & Configuration
125
+
126
+ | Export | Description |
127
+ |--------|-------------|
128
+ | `TebexProvider` | Main provider component - wrap your app with this |
129
+ | `useTebexContext()` | Access QueryClient and config from context |
130
+ | `useTebexConfig()` | Access just the Tebex configuration |
131
+
132
+ #### TebexConfig
133
+
134
+ ```typescript
135
+ interface TebexConfig {
136
+ publicKey: string; // Your Tebex public key
137
+ baseUrl: string; // Your site URL (for checkout redirects)
138
+ urls?: {
139
+ complete?: string; // Success redirect path (default: '/shop/complete')
140
+ cancel?: string; // Cancel redirect path (default: '/shop/cancel')
141
+ };
142
+ onError?: (error: TebexError) => void; // Global error callback
143
+ devtools?: boolean; // Enable React Query DevTools (default: true in dev)
144
+ }
145
+ ```
146
+
147
+ ---
148
+
149
+ ### Hooks
115
150
 
116
- ### Data Fetching Hooks
151
+ #### Data Fetching Hooks
117
152
 
118
153
  | Hook | Description |
119
154
  |------|-------------|
120
- | `useCategories()` | Fetch all categories (with optional packages) |
121
- | `useCategory(id)` | Fetch a single category by ID |
122
- | `usePackages()` | Fetch all packages |
123
- | `usePackage(id)` | Fetch a single package by ID |
155
+ | `useCategories(options?)` | Fetch all categories (with optional packages) |
156
+ | `useCategory(options)` | Fetch a single category by ID |
157
+ | `usePackages(options?)` | Fetch all packages (optionally by category) |
158
+ | `usePackage(options)` | Fetch a single package by ID |
124
159
  | `useWebstore()` | Fetch webstore info (name, currency, domain) |
125
160
 
126
- ### Basket Management
161
+ #### Basket Management Hooks
127
162
 
128
163
  | Hook | Description |
129
164
  |------|-------------|
130
165
  | `useBasket()` | Full basket management with optimistic updates |
131
- | `useCheckout()` | Launch Tebex.js checkout modal |
166
+ | `useCheckout(options?)` | Launch Tebex.js checkout modal |
132
167
  | `useCoupons()` | Apply/remove coupon codes |
133
168
  | `useGiftCards()` | Apply/remove gift cards |
134
169
  | `useCreatorCodes()` | Apply/remove creator codes |
135
170
  | `useGiftPackage()` | Gift a package to another user |
136
171
 
137
- ### User Management
172
+ #### User Management Hooks
138
173
 
139
174
  | Hook | Description |
140
175
  |------|-------------|
141
176
  | `useUser()` | Username management (persisted in localStorage) |
142
177
 
143
- ## Hook Examples
178
+ ---
144
179
 
145
- ### useBasket
180
+ ### Hook Details
146
181
 
147
- ```tsx
182
+ #### useBasket
183
+
184
+ ```typescript
148
185
  const {
186
+ // Data
149
187
  basket, // Basket | null
150
188
  packages, // BasketPackage[]
151
189
  basketIdent, // string | null
190
+ itemCount, // number
191
+ total, // number
192
+ isEmpty, // boolean
152
193
 
153
194
  // Loading states
154
195
  isLoading,
@@ -167,25 +208,20 @@ const {
167
208
  updateQuantity, // (params: UpdateQuantityParams) => Promise<void>
168
209
  clearBasket, // () => void
169
210
  refetch, // () => Promise<...>
170
-
171
- // Computed
172
- itemCount, // number
173
- total, // number
174
- isEmpty, // boolean
175
211
  } = useBasket();
176
212
 
177
213
  // Add package with options
178
214
  await addPackage({
179
215
  packageId: 123,
180
- quantity: 2,
181
- type: 'single', // optional: 'single' | 'subscription'
182
- variableData: { server: 'survival' }, // optional
216
+ quantity: 2, // optional, default: 1
217
+ type: 'single', // optional: 'single' | 'subscription'
218
+ variableData: { server: 'survival' }, // optional
183
219
  });
184
220
  ```
185
221
 
186
- ### useCategories
222
+ #### useCategories
187
223
 
188
- ```tsx
224
+ ```typescript
189
225
  const {
190
226
  categories, // Category[] | null
191
227
  data, // same as categories
@@ -204,9 +240,30 @@ const {
204
240
  });
205
241
  ```
206
242
 
207
- ### useCheckout
243
+ #### usePackages
208
244
 
209
- ```tsx
245
+ ```typescript
246
+ const {
247
+ packages, // Package[] | null
248
+ data, // same as packages
249
+ isLoading,
250
+ isFetching,
251
+ error,
252
+ errorCode,
253
+ refetch,
254
+
255
+ // Helpers
256
+ getById, // (id: number) => Package | undefined
257
+ getByName, // (name: string) => Package | undefined
258
+ } = usePackages({
259
+ categoryId: 123, // optional: filter by category
260
+ enabled: true, // default: true
261
+ });
262
+ ```
263
+
264
+ #### useCheckout
265
+
266
+ ```typescript
210
267
  const {
211
268
  launch, // () => Promise<void>
212
269
  isLaunching,
@@ -220,13 +277,13 @@ const {
220
277
  onClose: () => console.log('Checkout closed'),
221
278
  });
222
279
 
223
- // Requires Tebex.js script in your page
224
- // <script src="https://js.tebex.io/v/1.js" />
280
+ // IMPORTANT: Requires Tebex.js script in your page
281
+ // <script src="https://js.tebex.io/v/1.1.js" async />
225
282
  ```
226
283
 
227
- ### useUser
284
+ #### useUser
228
285
 
229
- ```tsx
286
+ ```typescript
230
287
  const {
231
288
  username, // string | null
232
289
  setUsername, // (username: string) => void
@@ -235,9 +292,9 @@ const {
235
292
  } = useUser();
236
293
  ```
237
294
 
238
- ### useCoupons
295
+ #### useCoupons
239
296
 
240
- ```tsx
297
+ ```typescript
241
298
  const {
242
299
  coupons, // Code[]
243
300
  apply, // (code: string) => Promise<void>
@@ -249,12 +306,75 @@ const {
249
306
  } = useCoupons();
250
307
  ```
251
308
 
309
+ #### useGiftCards
310
+
311
+ ```typescript
312
+ const {
313
+ giftCards, // GiftCardCode[]
314
+ apply, // (code: string) => Promise<void>
315
+ remove, // (code: string) => Promise<void>
316
+ isApplying,
317
+ isRemoving,
318
+ error,
319
+ errorCode,
320
+ } = useGiftCards();
321
+ ```
322
+
323
+ #### useCreatorCodes
324
+
325
+ ```typescript
326
+ const {
327
+ creatorCode, // string | null
328
+ apply, // (code: string) => Promise<void>
329
+ remove, // () => Promise<void>
330
+ isApplying,
331
+ isRemoving,
332
+ error,
333
+ errorCode,
334
+ } = useCreatorCodes();
335
+ ```
336
+
337
+ #### useGiftPackage
338
+
339
+ ```typescript
340
+ const {
341
+ gift, // (params: GiftPackageParams) => Promise<void>
342
+ isGifting,
343
+ error,
344
+ errorCode,
345
+ } = useGiftPackage();
346
+
347
+ // Gift a package to another player
348
+ await gift({
349
+ packageId: 123,
350
+ targetUsername: 'friend_username',
351
+ });
352
+ ```
353
+
354
+ #### useWebstore
355
+
356
+ ```typescript
357
+ const {
358
+ webstore, // Webstore | null
359
+ name, // string | null
360
+ currency, // string | null
361
+ domain, // string | null
362
+ isLoading,
363
+ isFetching,
364
+ error,
365
+ errorCode,
366
+ refetch,
367
+ } = useWebstore();
368
+ ```
369
+
370
+ ---
371
+
252
372
  ## Error Handling
253
373
 
254
374
  All hooks expose `error` (TebexError) and `errorCode` (TebexErrorCode) for i18n-friendly error handling:
255
375
 
256
- ```tsx
257
- import { TebexErrorCode } from '@neosia/tebex-nextjs';
376
+ ```typescript
377
+ import { TebexErrorCode } from '@neosianexus/super-tebex';
258
378
 
259
379
  const { error, errorCode } = useBasket();
260
380
 
@@ -271,112 +391,184 @@ if (errorCode) {
271
391
  }
272
392
  ```
273
393
 
274
- ### Available Error Codes
394
+ ### All Error Codes
275
395
 
276
396
  | Category | Codes |
277
397
  |----------|-------|
278
- | Provider | `PROVIDER_NOT_FOUND`, `INVALID_CONFIG` |
279
- | Auth | `NOT_AUTHENTICATED`, `INVALID_USERNAME` |
280
- | Basket | `BASKET_NOT_FOUND`, `BASKET_CREATION_FAILED`, `BASKET_EXPIRED` |
281
- | Package | `PACKAGE_NOT_FOUND`, `PACKAGE_OUT_OF_STOCK`, `PACKAGE_ALREADY_OWNED`, `INVALID_QUANTITY` |
282
- | Category | `CATEGORY_NOT_FOUND` |
283
- | Coupon | `COUPON_INVALID`, `COUPON_EXPIRED`, `COUPON_ALREADY_USED` |
284
- | Gift Card | `GIFTCARD_INVALID`, `GIFTCARD_INSUFFICIENT_BALANCE` |
285
- | Creator Code | `CREATOR_CODE_INVALID` |
286
- | Checkout | `CHECKOUT_FAILED`, `CHECKOUT_CANCELLED` |
287
- | Network | `NETWORK_ERROR`, `TIMEOUT`, `RATE_LIMITED` |
288
- | Unknown | `UNKNOWN` |
398
+ | **Provider** | `PROVIDER_NOT_FOUND`, `INVALID_CONFIG` |
399
+ | **Auth** | `NOT_AUTHENTICATED`, `INVALID_USERNAME` |
400
+ | **Basket** | `BASKET_NOT_FOUND`, `BASKET_CREATION_FAILED`, `BASKET_EXPIRED`, `BASKET_EMPTY` |
401
+ | **Package** | `PACKAGE_NOT_FOUND`, `PACKAGE_OUT_OF_STOCK`, `PACKAGE_ALREADY_OWNED`, `INVALID_QUANTITY` |
402
+ | **Category** | `CATEGORY_NOT_FOUND` |
403
+ | **Coupon** | `COUPON_INVALID`, `COUPON_EXPIRED`, `COUPON_ALREADY_USED` |
404
+ | **Gift Card** | `GIFTCARD_INVALID`, `GIFTCARD_INSUFFICIENT_BALANCE` |
405
+ | **Creator Code** | `CREATOR_CODE_INVALID` |
406
+ | **Checkout** | `CHECKOUT_FAILED`, `CHECKOUT_CANCELLED`, `TEBEX_JS_NOT_LOADED` |
407
+ | **Network** | `NETWORK_ERROR`, `TIMEOUT`, `RATE_LIMITED` |
408
+ | **Unknown** | `UNKNOWN` |
409
+
410
+ ---
289
411
 
290
412
  ## TypeScript
291
413
 
292
414
  All types are exported:
293
415
 
294
- ```tsx
416
+ ```typescript
295
417
  import type {
296
418
  // Config
297
419
  TebexConfig,
298
420
  TebexUrls,
421
+ ResolvedTebexConfig,
299
422
 
300
423
  // Hook Returns
301
424
  UseBasketReturn,
302
425
  UseCategoriesReturn,
426
+ UseCategoriesOptions,
427
+ UseCategoryReturn,
428
+ UseCategoryOptions,
429
+ UsePackagesReturn,
430
+ UsePackagesOptions,
431
+ UsePackageReturn,
432
+ UsePackageOptions,
303
433
  UseCheckoutReturn,
304
- // ... all hook return types
305
-
306
- // Tebex API types
434
+ UseCheckoutOptions,
435
+ UseCouponsReturn,
436
+ UseGiftCardsReturn,
437
+ UseCreatorCodesReturn,
438
+ UseGiftPackageReturn,
439
+ UseWebstoreReturn,
440
+ UseUserReturn,
441
+
442
+ // Params
443
+ AddPackageParams,
444
+ UpdateQuantityParams,
445
+ GiftPackageParams,
446
+
447
+ // Base types
448
+ BaseQueryReturn,
449
+ BaseMutationReturn,
450
+
451
+ // Tebex API types (re-exported from tebex_headless)
307
452
  Basket,
308
453
  BasketPackage,
309
454
  Category,
310
455
  Package,
456
+ PackageType,
311
457
  Webstore,
458
+ Code,
459
+ GiftCardCode,
312
460
 
313
461
  // Utilities
314
462
  Result,
315
- TebexError,
316
- TebexErrorCode,
317
- } from '@neosia/tebex-nextjs';
463
+ } from '@neosianexus/super-tebex';
464
+
465
+ // Error handling
466
+ import { TebexError, TebexErrorCode } from '@neosianexus/super-tebex';
318
467
 
319
468
  // Type guards
320
- import { isTebexError, isSuccess, isError, isDefined } from '@neosia/tebex-nextjs';
469
+ import {
470
+ isTebexError, // (error: unknown) => error is TebexError
471
+ isSuccess, // (result: Result<T,E>) => result is { ok: true, data: T }
472
+ isError, // (result: Result<T,E>) => result is { ok: false, error: E }
473
+ isDefined, // <T>(value: T | null | undefined) => value is T
474
+ } from '@neosianexus/super-tebex';
475
+
476
+ // Result utilities
477
+ import { ok, err } from '@neosianexus/super-tebex';
321
478
  ```
322
479
 
323
- ## Migration from v2
480
+ ---
324
481
 
325
- ### Breaking Changes
482
+ ## Zustand Stores
326
483
 
327
- | v2 | v3 | Migration |
328
- |----|-----|-----------|
329
- | `initTebex(key)` | `<TebexProvider config={{...}}>` | Wrap app with Provider |
330
- | `initShopUrls(url)` | `config.baseUrl` + `config.urls` | Pass in config |
331
- | `useBasket(username)` | `useBasket()` + `useUser()` | User is separate |
332
- | `error.message` (FR) | `error.code` | Translate codes yourself |
333
- | `sonner` peer dep | Removed | Handle toasts yourself |
334
- | `useShopUserStore` | `useUserStore` | Renamed |
335
- | `useShopBasketStore` | `useBasketStore` | Renamed |
484
+ Direct store access for advanced use cases:
336
485
 
337
- ### Migration Example
486
+ ```typescript
487
+ import { useBasketStore, useUserStore } from '@neosianexus/super-tebex';
338
488
 
339
- **Before (v2):**
489
+ // Access stores directly (outside of hooks)
490
+ const basketIdent = useBasketStore(state => state.basketIdent);
491
+ const setBasketIdent = useBasketStore(state => state.setBasketIdent);
492
+ const clearBasketIdent = useBasketStore(state => state.clearBasketIdent);
340
493
 
341
- ```tsx
342
- // lib/tebex.ts
343
- initTebex(process.env.NEXT_PUBLIC_TEBEX_KEY);
344
- initShopUrls('https://mysite.com');
494
+ const username = useUserStore(state => state.username);
495
+ const setUsername = useUserStore(state => state.setUsername);
496
+ const clearUsername = useUserStore(state => state.clearUsername);
497
+ ```
345
498
 
346
- // Component
347
- const username = useShopUserStore(s => s.username);
348
- const { basket, addPackageToBasket, error } = useBasket(username);
499
+ ---
349
500
 
350
- if (error) toast.error(error.message); // French message
501
+ ## Query Keys
502
+
503
+ For manual cache invalidation:
504
+
505
+ ```typescript
506
+ import { tebexKeys } from '@neosianexus/super-tebex';
507
+ import { useQueryClient } from '@tanstack/react-query';
508
+
509
+ const queryClient = useQueryClient();
510
+
511
+ // Available keys
512
+ tebexKeys.all // ['tebex']
513
+ tebexKeys.categories() // ['tebex', 'categories']
514
+ tebexKeys.categoriesList() // ['tebex', 'categories', 'list']
515
+ tebexKeys.category(id) // ['tebex', 'categories', id]
516
+ tebexKeys.packages() // ['tebex', 'packages']
517
+ tebexKeys.packagesList() // ['tebex', 'packages', 'list']
518
+ tebexKeys.package(id) // ['tebex', 'packages', id]
519
+ tebexKeys.baskets() // ['tebex', 'baskets']
520
+ tebexKeys.basket(ident) // ['tebex', 'baskets', ident]
521
+ tebexKeys.webstore() // ['tebex', 'webstore']
522
+
523
+ // Invalidate specific queries
524
+ queryClient.invalidateQueries({ queryKey: tebexKeys.categories() });
525
+ queryClient.invalidateQueries({ queryKey: tebexKeys.basket(basketIdent) });
351
526
  ```
352
527
 
353
- **After (v3):**
528
+ ---
354
529
 
355
- ```tsx
356
- // app/layout.tsx
357
- <TebexProvider
358
- config={{
359
- publicKey: process.env.NEXT_PUBLIC_TEBEX_KEY!,
360
- baseUrl: 'https://mysite.com',
361
- onError: (err) => toast.error(t(`errors.${err.code}`)),
362
- }}
363
- >
530
+ ## Advanced Usage
531
+
532
+ ### Custom QueryClient
533
+
534
+ ```typescript
535
+ import { QueryClient } from '@tanstack/react-query';
536
+ import { TebexProvider } from '@neosianexus/super-tebex';
537
+
538
+ const queryClient = new QueryClient({
539
+ defaultOptions: {
540
+ queries: {
541
+ staleTime: 30 * 1000, // 30 seconds
542
+ },
543
+ },
544
+ });
545
+
546
+ <TebexProvider config={config} queryClient={queryClient}>
364
547
  {children}
365
548
  </TebexProvider>
549
+ ```
366
550
 
367
- // Component
368
- const { username } = useUser();
369
- const { basket, addPackage, errorCode } = useBasket();
551
+ ### Direct API Client Access
370
552
 
371
- // Errors handled by onError callback or manually with errorCode
553
+ For advanced scenarios requiring direct API access:
554
+
555
+ ```typescript
556
+ import { getTebexClient, isTebexClientInitialized } from '@neosianexus/super-tebex';
557
+
558
+ if (isTebexClientInitialized()) {
559
+ const client = getTebexClient();
560
+ // Use client directly (advanced usage only)
561
+ }
372
562
  ```
373
563
 
564
+ ---
565
+
374
566
  ## Complete Example
375
567
 
376
568
  ```tsx
377
569
  'use client';
378
570
 
379
- import { useCategories, useBasket, useUser, useCheckout } from '@neosia/tebex-nextjs';
571
+ import { useCategories, useBasket, useUser, useCheckout } from '@neosianexus/super-tebex';
380
572
  import { useState } from 'react';
381
573
 
382
574
  export default function ShopPage() {
@@ -496,50 +688,137 @@ export default function ShopPage() {
496
688
  }
497
689
  ```
498
690
 
499
- ## Advanced Usage
691
+ ---
500
692
 
501
- ### Custom QueryClient
693
+ ## Migration from v2
694
+
695
+ ### Breaking Changes
696
+
697
+ | v2 | v3 | Migration |
698
+ |----|-----|-----------|
699
+ | `initTebex(key)` | `<TebexProvider config={{...}}>` | Wrap app with Provider |
700
+ | `initShopUrls(url)` | `config.baseUrl` + `config.urls` | Pass in config |
701
+ | `useBasket(username)` | `useBasket()` + `useUser()` | User is separate |
702
+ | `error.message` (FR) | `error.code` | Translate codes yourself |
703
+ | `sonner` peer dep | Removed | Handle toasts yourself |
704
+ | `useShopUserStore` | `useUserStore` | Renamed |
705
+ | `useShopBasketStore` | `useBasketStore` | Renamed |
706
+
707
+ ### Migration Example
708
+
709
+ **Before (v2):**
502
710
 
503
711
  ```tsx
504
- import { QueryClient } from '@tanstack/react-query';
505
- import { TebexProvider } from '@neosia/tebex-nextjs';
712
+ // lib/tebex.ts
713
+ initTebex(process.env.NEXT_PUBLIC_TEBEX_KEY);
714
+ initShopUrls('https://mysite.com');
506
715
 
507
- const queryClient = new QueryClient({
508
- defaultOptions: {
509
- queries: {
510
- staleTime: 30 * 1000, // 30 seconds
511
- },
512
- },
513
- });
716
+ // Component
717
+ const username = useShopUserStore(s => s.username);
718
+ const { basket, addPackageToBasket, error } = useBasket(username);
514
719
 
515
- <TebexProvider config={config} queryClient={queryClient}>
516
- {children}
517
- </TebexProvider>
720
+ if (error) toast.error(error.message); // French message
518
721
  ```
519
722
 
520
- ### Direct Store Access
723
+ **After (v3):**
521
724
 
522
725
  ```tsx
523
- import { useBasketStore, useUserStore } from '@neosia/tebex-nextjs';
726
+ // app/layout.tsx
727
+ <TebexProvider
728
+ config={{
729
+ publicKey: process.env.NEXT_PUBLIC_TEBEX_KEY!,
730
+ baseUrl: 'https://mysite.com',
731
+ onError: (err) => toast.error(t(`errors.${err.code}`)),
732
+ }}
733
+ >
734
+ {children}
735
+ </TebexProvider>
524
736
 
525
- // Access stores directly (outside of hooks)
526
- const basketIdent = useBasketStore(state => state.basketIdent);
527
- const username = useUserStore(state => state.username);
737
+ // Component
738
+ const { username } = useUser();
739
+ const { basket, addPackage, errorCode } = useBasket();
740
+
741
+ // Errors handled by onError callback or manually with errorCode
528
742
  ```
529
743
 
530
- ### Query Keys
744
+ ---
531
745
 
532
- ```tsx
533
- import { tebexKeys } from '@neosia/tebex-nextjs';
534
- import { useQueryClient } from '@tanstack/react-query';
746
+ ## Quick Reference for AI/LLM
535
747
 
536
- const queryClient = useQueryClient();
748
+ <details>
749
+ <summary><strong>Click to expand - Structured reference for AI assistants</strong></summary>
537
750
 
538
- // Invalidate specific queries
539
- queryClient.invalidateQueries({ queryKey: tebexKeys.categories() });
540
- queryClient.invalidateQueries({ queryKey: tebexKeys.basket(basketIdent) });
751
+ ### Package Info
752
+ - **Name**: `@neosianexus/super-tebex`
753
+ - **Purpose**: Tebex Headless SDK wrapper for React/Next.js
754
+ - **State**: TanStack Query v5 (server) + Zustand v5 (client)
755
+
756
+ ### Common Patterns
757
+
758
+ ```typescript
759
+ // 1. Setup (app/layout.tsx)
760
+ <TebexProvider config={{ publicKey, baseUrl }}>{children}</TebexProvider>
761
+
762
+ // 2. Get categories with packages
763
+ const { categories } = useCategories({ includePackages: true });
764
+
765
+ // 3. Add to basket
766
+ const { addPackage } = useBasket();
767
+ await addPackage({ packageId: 123 });
768
+
769
+ // 4. Checkout
770
+ const { launch, canCheckout } = useCheckout();
771
+ if (canCheckout) await launch();
772
+
773
+ // 5. User management
774
+ const { username, setUsername } = useUser();
775
+ setUsername('player_name');
776
+ ```
777
+
778
+ ### Hook Signatures
779
+
780
+ | Hook | Key Params | Key Returns |
781
+ |------|------------|-------------|
782
+ | `useCategories(opts?)` | `includePackages` | `categories`, `getById`, `getByName` |
783
+ | `useCategory(opts)` | `id` | `category` |
784
+ | `usePackages(opts?)` | `categoryId` | `packages`, `getById`, `getByName` |
785
+ | `usePackage(opts)` | `id` | `package` |
786
+ | `useWebstore()` | - | `webstore`, `name`, `currency`, `domain` |
787
+ | `useBasket()` | - | `basket`, `addPackage`, `removePackage`, `itemCount` |
788
+ | `useCheckout(opts?)` | `onSuccess`, `onError` | `launch`, `canCheckout`, `isLaunching` |
789
+ | `useUser()` | - | `username`, `setUsername`, `isAuthenticated` |
790
+ | `useCoupons()` | - | `coupons`, `apply`, `remove` |
791
+ | `useGiftCards()` | - | `giftCards`, `apply`, `remove` |
792
+ | `useCreatorCodes()` | - | `creatorCode`, `apply`, `remove` |
793
+ | `useGiftPackage()` | - | `gift`, `isGifting` |
794
+
795
+ ### Error Handling Pattern
796
+
797
+ ```typescript
798
+ const { errorCode } = useBasket();
799
+ if (errorCode === TebexErrorCode.BASKET_NOT_FOUND) {
800
+ // Handle expired basket
801
+ }
541
802
  ```
542
803
 
804
+ ### Requirements
805
+ - Must wrap app with `TebexProvider`
806
+ - Checkout requires `<script src="https://js.tebex.io/v/1.1.js" async />`
807
+ - Username required before adding to basket
808
+
809
+ </details>
810
+
811
+ ---
812
+
543
813
  ## License
544
814
 
545
815
  MIT
816
+
817
+ ---
818
+
819
+ ## Links
820
+
821
+ - [GitHub Repository](https://github.com/NeosiaNexus/super-tebex)
822
+ - [NPM Package](https://www.npmjs.com/package/@neosianexus/super-tebex)
823
+ - [Tebex Documentation](https://docs.tebex.io/)
824
+ - [Report Issues](https://github.com/NeosiaNexus/super-tebex/issues)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@neosianexus/super-tebex",
3
- "version": "3.0.3",
3
+ "version": "3.0.4",
4
4
  "description": "Tebex Headless SDK optimized for Next.js App Router with TanStack Query",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",