@neosianexus/super-tebex 3.4.1 → 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.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
package/README.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
[](https://www.npmjs.com/package/@neosianexus/super-tebex)
|
|
4
4
|
[](https://www.npmjs.com/package/@neosianexus/super-tebex)
|
|
5
5
|
[](https://github.com/NeosiaNexus/super-tebex)
|
|
6
|
-
[](https://www.typescriptlang.org/)
|
|
7
7
|
[](https://opensource.org/licenses/MIT)
|
|
8
8
|
|
|
9
9
|
> Tebex Headless SDK optimized for Next.js App Router with TanStack Query and Zustand.
|
|
@@ -278,7 +278,7 @@ const {
|
|
|
278
278
|
});
|
|
279
279
|
|
|
280
280
|
// IMPORTANT: Requires Tebex.js script in your page
|
|
281
|
-
// <script src="https://js.tebex.io/v/1.
|
|
281
|
+
// <script src="https://js.tebex.io/v/1.9.0.js" async />
|
|
282
282
|
```
|
|
283
283
|
|
|
284
284
|
#### useUser
|
|
@@ -286,7 +286,7 @@ const {
|
|
|
286
286
|
```typescript
|
|
287
287
|
const {
|
|
288
288
|
username, // string | null
|
|
289
|
-
setUsername, // (username: string) =>
|
|
289
|
+
setUsername, // (username: string) => boolean
|
|
290
290
|
clearUsername, // () => void
|
|
291
291
|
isAuthenticated, // boolean
|
|
292
292
|
} = useUser();
|
|
@@ -405,6 +405,7 @@ if (errorCode) {
|
|
|
405
405
|
| **Creator Code** | `CREATOR_CODE_INVALID` |
|
|
406
406
|
| **Checkout** | `CHECKOUT_FAILED`, `CHECKOUT_CANCELLED`, `TEBEX_JS_NOT_LOADED` |
|
|
407
407
|
| **Network** | `NETWORK_ERROR`, `TIMEOUT`, `RATE_LIMITED` |
|
|
408
|
+
| **HTTP** | `SERVER_ERROR`, `FORBIDDEN`, `VALIDATION_ERROR`, `NOT_FOUND`, `BASKET_LOCKED`, `PACKAGE_DISABLED` |
|
|
408
409
|
| **Unknown** | `UNKNOWN` |
|
|
409
410
|
|
|
410
411
|
---
|
|
@@ -467,12 +468,19 @@ import { TebexError, TebexErrorCode } from '@neosianexus/super-tebex';
|
|
|
467
468
|
|
|
468
469
|
// Type guards
|
|
469
470
|
import {
|
|
470
|
-
isTebexError,
|
|
471
|
-
isSuccess,
|
|
472
|
-
isError,
|
|
473
|
-
isDefined,
|
|
471
|
+
isTebexError, // (error: unknown) => error is TebexError (duck-typing, cross-realm safe)
|
|
472
|
+
isSuccess, // (result: Result<T,E>) => result is { success: true, data: T }
|
|
473
|
+
isError, // (result: Result<T,E>) => result is { success: false, error: E }
|
|
474
|
+
isDefined, // <T>(value: T | null | undefined) => value is T
|
|
475
|
+
isNonEmptyString, // (value: unknown) => value is string
|
|
476
|
+
isPositiveInteger, // (value: unknown) => value is number
|
|
477
|
+
isPositiveNumber, // (value: unknown) => value is number
|
|
478
|
+
isValidMinecraftUsername, // (value: unknown) => value is string (3-16 chars, alphanumeric + underscore)
|
|
474
479
|
} from '@neosianexus/super-tebex';
|
|
475
480
|
|
|
481
|
+
// Query key type
|
|
482
|
+
import type { TebexQueryKey } from '@neosianexus/super-tebex';
|
|
483
|
+
|
|
476
484
|
// Result utilities
|
|
477
485
|
import { ok, err } from '@neosianexus/super-tebex';
|
|
478
486
|
```
|
|
@@ -803,7 +811,7 @@ if (errorCode === TebexErrorCode.BASKET_NOT_FOUND) {
|
|
|
803
811
|
|
|
804
812
|
### Requirements
|
|
805
813
|
- Must wrap app with `TebexProvider`
|
|
806
|
-
- Checkout requires `<script src="https://js.tebex.io/v/1.
|
|
814
|
+
- Checkout requires `<script src="https://js.tebex.io/v/1.9.0.js" async />`
|
|
807
815
|
- Username required before adding to basket
|
|
808
816
|
|
|
809
817
|
</details>
|
|
@@ -7,11 +7,19 @@ export declare class TebexError extends Error {
|
|
|
7
7
|
readonly code: TebexErrorCode;
|
|
8
8
|
readonly cause?: unknown;
|
|
9
9
|
constructor(code: TebexErrorCode, message?: string, cause?: unknown);
|
|
10
|
+
private static extractStatusCode;
|
|
10
11
|
/**
|
|
11
12
|
* Converts an unknown error to a TebexError.
|
|
12
13
|
* If the error is already a TebexError, it returns it as-is.
|
|
13
14
|
*/
|
|
14
15
|
static fromUnknown(error: unknown): TebexError;
|
|
16
|
+
/**
|
|
17
|
+
* Creates a TebexError from a JSON representation.
|
|
18
|
+
*/
|
|
19
|
+
static fromJSON(json: {
|
|
20
|
+
code: TebexErrorCode;
|
|
21
|
+
message?: string;
|
|
22
|
+
}): TebexError;
|
|
15
23
|
/**
|
|
16
24
|
* Returns a JSON representation of the error.
|
|
17
25
|
*/
|
|
@@ -19,6 +27,7 @@ export declare class TebexError extends Error {
|
|
|
19
27
|
name: string;
|
|
20
28
|
code: TebexErrorCode;
|
|
21
29
|
message: string;
|
|
30
|
+
cause?: string;
|
|
22
31
|
};
|
|
23
32
|
}
|
|
24
33
|
//# sourceMappingURL=TebexError.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TebexError.d.ts","sourceRoot":"","sources":["../../src/errors/TebexError.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAEzC;;;GAGG;AACH,qBAAa,UAAW,SAAQ,KAAK;IACnC,SAAgB,IAAI,EAAE,cAAc,CAAC;IACrC,SAAgB,KAAK,CAAC,EAAE,OAAO,CAAC;gBAEpB,IAAI,EAAE,cAAc,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO;
|
|
1
|
+
{"version":3,"file":"TebexError.d.ts","sourceRoot":"","sources":["../../src/errors/TebexError.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAEzC;;;GAGG;AACH,qBAAa,UAAW,SAAQ,KAAK;IACnC,SAAgB,IAAI,EAAE,cAAc,CAAC;IACrC,SAAgB,KAAK,CAAC,EAAE,OAAO,CAAC;gBAEpB,IAAI,EAAE,cAAc,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO;IAYnE,OAAO,CAAC,MAAM,CAAC,iBAAiB;IAahC;;;OAGG;IACH,MAAM,CAAC,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,UAAU;IA6E9C;;OAEG;IACH,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE;QAAE,IAAI,EAAE,cAAc,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,UAAU;IAI7E;;OAEG;IACH,MAAM,IAAI;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,cAAc,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE;CAQlF"}
|
package/dist/errors/codes.d.ts
CHANGED
|
@@ -28,6 +28,12 @@ export declare enum TebexErrorCode {
|
|
|
28
28
|
NETWORK_ERROR = "NETWORK_ERROR",
|
|
29
29
|
TIMEOUT = "TIMEOUT",
|
|
30
30
|
RATE_LIMITED = "RATE_LIMITED",
|
|
31
|
+
SERVER_ERROR = "SERVER_ERROR",
|
|
32
|
+
FORBIDDEN = "FORBIDDEN",
|
|
33
|
+
VALIDATION_ERROR = "VALIDATION_ERROR",
|
|
34
|
+
NOT_FOUND = "NOT_FOUND",
|
|
35
|
+
BASKET_LOCKED = "BASKET_LOCKED",
|
|
36
|
+
PACKAGE_DISABLED = "PACKAGE_DISABLED",
|
|
31
37
|
UNKNOWN = "UNKNOWN"
|
|
32
38
|
}
|
|
33
39
|
//# sourceMappingURL=codes.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"codes.d.ts","sourceRoot":"","sources":["../../src/errors/codes.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,oBAAY,cAAc;IAExB,kBAAkB,uBAAuB;IACzC,cAAc,mBAAmB;IAGjC,iBAAiB,sBAAsB;IACvC,gBAAgB,qBAAqB;IAGrC,gBAAgB,qBAAqB;IACrC,sBAAsB,2BAA2B;IACjD,cAAc,mBAAmB;IACjC,YAAY,iBAAiB;IAG7B,iBAAiB,sBAAsB;IACvC,oBAAoB,yBAAyB;IAC7C,qBAAqB,0BAA0B;IAC/C,gBAAgB,qBAAqB;IAGrC,kBAAkB,uBAAuB;IAGzC,cAAc,mBAAmB;IACjC,cAAc,mBAAmB;IACjC,mBAAmB,wBAAwB;IAC3C,gBAAgB,qBAAqB;IACrC,6BAA6B,kCAAkC;IAC/D,oBAAoB,yBAAyB;IAG7C,eAAe,oBAAoB;IACnC,kBAAkB,uBAAuB;IACzC,mBAAmB,wBAAwB;IAG3C,aAAa,kBAAkB;IAC/B,OAAO,YAAY;IACnB,YAAY,iBAAiB;IAG7B,OAAO,YAAY;CACpB"}
|
|
1
|
+
{"version":3,"file":"codes.d.ts","sourceRoot":"","sources":["../../src/errors/codes.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,oBAAY,cAAc;IAExB,kBAAkB,uBAAuB;IACzC,cAAc,mBAAmB;IAGjC,iBAAiB,sBAAsB;IACvC,gBAAgB,qBAAqB;IAGrC,gBAAgB,qBAAqB;IACrC,sBAAsB,2BAA2B;IACjD,cAAc,mBAAmB;IACjC,YAAY,iBAAiB;IAG7B,iBAAiB,sBAAsB;IACvC,oBAAoB,yBAAyB;IAC7C,qBAAqB,0BAA0B;IAC/C,gBAAgB,qBAAqB;IAGrC,kBAAkB,uBAAuB;IAGzC,cAAc,mBAAmB;IACjC,cAAc,mBAAmB;IACjC,mBAAmB,wBAAwB;IAC3C,gBAAgB,qBAAqB;IACrC,6BAA6B,kCAAkC;IAC/D,oBAAoB,yBAAyB;IAG7C,eAAe,oBAAoB;IACnC,kBAAkB,uBAAuB;IACzC,mBAAmB,wBAAwB;IAG3C,aAAa,kBAAkB;IAC/B,OAAO,YAAY;IACnB,YAAY,iBAAiB;IAG7B,YAAY,iBAAiB;IAC7B,SAAS,cAAc;IACvB,gBAAgB,qBAAqB;IACrC,SAAS,cAAc;IACvB,aAAa,kBAAkB;IAC/B,gBAAgB,qBAAqB;IAGrC,OAAO,YAAY;CACpB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useBasket.d.ts","sourceRoot":"","sources":["../../src/hooks/useBasket.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAA0C,eAAe,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"useBasket.d.ts","sourceRoot":"","sources":["../../src/hooks/useBasket.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAA0C,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAe9F;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,SAAS,IAAI,eAAe,CA8U3C"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useCategories.d.ts","sourceRoot":"","sources":["../../src/hooks/useCategories.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAEhF;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,aAAa,CAAC,OAAO,GAAE,oBAAyB,GAAG,mBAAmB,
|
|
1
|
+
{"version":3,"file":"useCategories.d.ts","sourceRoot":"","sources":["../../src/hooks/useCategories.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAEhF;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,aAAa,CAAC,OAAO,GAAE,oBAAyB,GAAG,mBAAmB,CAiDrF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useCategory.d.ts","sourceRoot":"","sources":["../../src/hooks/useCategory.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAE5E;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,kBAAkB,GAAG,iBAAiB,
|
|
1
|
+
{"version":3,"file":"useCategory.d.ts","sourceRoot":"","sources":["../../src/hooks/useCategory.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAE5E;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,kBAAkB,GAAG,iBAAiB,CA2B1E"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useCheckout.d.ts","sourceRoot":"","sources":["../../src/hooks/useCheckout.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAG5E;;;GAGG;AACH,UAAU,aAAa;IACrB,IAAI,EAAE,CAAC,OAAO,EAAE;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;IAC3C,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,EAAE,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,IAAI,CAAC,EAAE,OAAO,KAAK,IAAI,KAAK,IAAI,CAAC;IAChE,KAAK,EAAE,MAAM,IAAI,CAAC;CACnB;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,MAAM;QACd,KAAK,CAAC,EAAE;YACN,QAAQ,EAAE,aAAa,CAAC;SACzB,CAAC;KACH;CACF;
|
|
1
|
+
{"version":3,"file":"useCheckout.d.ts","sourceRoot":"","sources":["../../src/hooks/useCheckout.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAG5E;;;GAGG;AACH,UAAU,aAAa;IACrB,IAAI,EAAE,CAAC,OAAO,EAAE;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;IAC3C,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,EAAE,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,IAAI,CAAC,EAAE,OAAO,KAAK,IAAI,KAAK,IAAI,CAAC;IAChE,KAAK,EAAE,MAAM,IAAI,CAAC;CACnB;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,MAAM;QACd,KAAK,CAAC,EAAE;YACN,QAAQ,EAAE,aAAa,CAAC;SACzB,CAAC;KACH;CACF;AAYD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,WAAW,CAAC,OAAO,GAAE,kBAAuB,GAAG,iBAAiB,CAuJ/E"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useCoupons.d.ts","sourceRoot":"","sources":["../../src/hooks/useCoupons.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAGvD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,UAAU,IAAI,gBAAgB,
|
|
1
|
+
{"version":3,"file":"useCoupons.d.ts","sourceRoot":"","sources":["../../src/hooks/useCoupons.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAGvD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,UAAU,IAAI,gBAAgB,CAmH7C"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useCreatorCodes.d.ts","sourceRoot":"","sources":["../../src/hooks/useCreatorCodes.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AAG5D;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,eAAe,IAAI,qBAAqB,
|
|
1
|
+
{"version":3,"file":"useCreatorCodes.d.ts","sourceRoot":"","sources":["../../src/hooks/useCreatorCodes.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AAG5D;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,eAAe,IAAI,qBAAqB,CAkHvD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useGiftCards.d.ts","sourceRoot":"","sources":["../../src/hooks/useGiftCards.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAGzD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,YAAY,IAAI,kBAAkB,
|
|
1
|
+
{"version":3,"file":"useGiftCards.d.ts","sourceRoot":"","sources":["../../src/hooks/useGiftCards.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAGzD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,YAAY,IAAI,kBAAkB,CAqHjD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useGiftPackage.d.ts","sourceRoot":"","sources":["../../src/hooks/useGiftPackage.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAqB,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAE9E;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,cAAc,IAAI,oBAAoB,
|
|
1
|
+
{"version":3,"file":"useGiftPackage.d.ts","sourceRoot":"","sources":["../../src/hooks/useGiftPackage.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAqB,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAE9E;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,cAAc,IAAI,oBAAoB,CAgHrD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"usePackage.d.ts","sourceRoot":"","sources":["../../src/hooks/usePackage.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAE1E;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,iBAAiB,GAAG,gBAAgB,
|
|
1
|
+
{"version":3,"file":"usePackage.d.ts","sourceRoot":"","sources":["../../src/hooks/usePackage.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAE1E;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,iBAAiB,GAAG,gBAAgB,CA2BvE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"usePackages.d.ts","sourceRoot":"","sources":["../../src/hooks/usePackages.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAE5E;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,WAAW,CAAC,OAAO,GAAE,kBAAuB,GAAG,iBAAiB,
|
|
1
|
+
{"version":3,"file":"usePackages.d.ts","sourceRoot":"","sources":["../../src/hooks/usePackages.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAE5E;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,WAAW,CAAC,OAAO,GAAE,kBAAuB,GAAG,iBAAiB,CAwD/E"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useWebstore.d.ts","sourceRoot":"","sources":["../../src/hooks/useWebstore.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,iBAAiB,EAAgB,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"useWebstore.d.ts","sourceRoot":"","sources":["../../src/hooks/useWebstore.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,iBAAiB,EAAgB,MAAM,gBAAgB,CAAC;AA8CtE;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,WAAW,IAAI,iBAAiB,CA4B/C"}
|
package/dist/index.cjs
CHANGED
|
@@ -1,2 +1,4 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
var{defineProperty:_A,getOwnPropertyNames:yA,getOwnPropertyDescriptor:xA}=Object,cA=Object.prototype.hasOwnProperty;var BA=new WeakMap,dA=(A)=>{var O=BA.get(A),_;if(O)return O;if(O=_A({},"__esModule",{value:!0}),A&&typeof A==="object"||typeof A==="function")yA(A).map((N)=>!cA.call(O,N)&&_A(O,N,{get:()=>A[N],enumerable:!(_=xA(A,N))||_.enumerable}));return BA.set(A,O),O};var bA=(A,O)=>{for(var _ in O)_A(A,_,{get:O[_],enumerable:!0,configurable:!0,set:(N)=>O[_]=()=>N})};var oA={};bA(oA,{useWebstore:()=>wA,useUserStore:()=>h,useUser:()=>QA,useTebexContext:()=>g,useTebexConfig:()=>S,usePackages:()=>jA,usePackage:()=>WA,useGiftPackage:()=>PA,useGiftCards:()=>zA,useCreatorCodes:()=>HA,useCoupons:()=>$A,useCheckout:()=>ZA,useCategory:()=>JA,useCategories:()=>XA,useBasketStore:()=>j,useBasket:()=>I,tebexKeys:()=>R,ok:()=>KA,isTebexError:()=>GA,isTebexClientInitialized:()=>NA,isSuccess:()=>UA,isError:()=>YA,isDefined:()=>VA,getTebexClient:()=>H,err:()=>hA,TebexProvider:()=>FA,TebexErrorCode:()=>i,TebexError:()=>L});module.exports=dA(oA);var n=require("@tanstack/react-query"),T=require("react");var fA=require("tebex_headless"),b=null;function DA(A){b=new fA.TebexHeadless(A)}function H(){if(b===null)throw Error("Tebex client not initialized. Make sure you are using TebexProvider.");return b}function NA(){return b!==null}var u=require("react");var i;((P)=>{P.PROVIDER_NOT_FOUND="PROVIDER_NOT_FOUND";P.INVALID_CONFIG="INVALID_CONFIG";P.NOT_AUTHENTICATED="NOT_AUTHENTICATED";P.INVALID_USERNAME="INVALID_USERNAME";P.BASKET_NOT_FOUND="BASKET_NOT_FOUND";P.BASKET_CREATION_FAILED="BASKET_CREATION_FAILED";P.BASKET_EXPIRED="BASKET_EXPIRED";P.BASKET_EMPTY="BASKET_EMPTY";P.PACKAGE_NOT_FOUND="PACKAGE_NOT_FOUND";P.PACKAGE_OUT_OF_STOCK="PACKAGE_OUT_OF_STOCK";P.PACKAGE_ALREADY_OWNED="PACKAGE_ALREADY_OWNED";P.INVALID_QUANTITY="INVALID_QUANTITY";P.CATEGORY_NOT_FOUND="CATEGORY_NOT_FOUND";P.COUPON_INVALID="COUPON_INVALID";P.COUPON_EXPIRED="COUPON_EXPIRED";P.COUPON_ALREADY_USED="COUPON_ALREADY_USED";P.GIFTCARD_INVALID="GIFTCARD_INVALID";P.GIFTCARD_INSUFFICIENT_BALANCE="GIFTCARD_INSUFFICIENT_BALANCE";P.CREATOR_CODE_INVALID="CREATOR_CODE_INVALID";P.CHECKOUT_FAILED="CHECKOUT_FAILED";P.CHECKOUT_CANCELLED="CHECKOUT_CANCELLED";P.TEBEX_JS_NOT_LOADED="TEBEX_JS_NOT_LOADED";P.NETWORK_ERROR="NETWORK_ERROR";P.TIMEOUT="TIMEOUT";P.RATE_LIMITED="RATE_LIMITED";P.UNKNOWN="UNKNOWN"})(i||={});class L extends Error{code;cause;constructor(A,O,_){super(O??A);if(this.name="TebexError",this.code=A,this.cause=_,typeof Error.captureStackTrace==="function")Error.captureStackTrace(this,L)}static fromUnknown(A){if(A instanceof L)return A;if(A instanceof Error){let O=A.message.toLowerCase();if(O.includes("network")||O.includes("fetch"))return new L("NETWORK_ERROR",A.message,A);if(O.includes("timeout"))return new L("TIMEOUT",A.message,A);if(O.includes("rate limit")||O.includes("429"))return new L("RATE_LIMITED",A.message,A);if(O.includes("basket")&&O.includes("not found"))return new L("BASKET_NOT_FOUND",A.message,A);if(O.includes("package")&&O.includes("not found"))return new L("PACKAGE_NOT_FOUND",A.message,A);if(O.includes("coupon")&&O.includes("invalid"))return new L("COUPON_INVALID",A.message,A);if(O.includes("coupon")&&O.includes("expired"))return new L("COUPON_EXPIRED",A.message,A);if(O.includes("gift")&&O.includes("invalid"))return new L("GIFTCARD_INVALID",A.message,A);return new L("UNKNOWN",A.message,A)}return new L("UNKNOWN",String(A))}toJSON(){return{name:this.name,code:this.code,message:this.message}}}var RA=u.createContext(null);function g(){let A=u.useContext(RA);if(A===null)throw new L("PROVIDER_NOT_FOUND","useTebexContext must be used within TebexProvider or TebexMockProvider");return A}function S(){let{config:A}=g();return A}var LA=require("react/jsx-runtime"),iA={defaultOptions:{queries:{staleTime:60000,gcTime:300000,retry:3,retryDelay:(A)=>Math.min(1000*2**A,30000),refetchOnWindowFocus:!1,refetchOnReconnect:!0},mutations:{retry:2,retryDelay:(A)=>Math.min(500*2**A,5000)}}};function uA(A){let O=A.baseUrl.replace(/\/$/,""),_=A.urls?.complete??"/shop/complete",N=A.urls?.cancel??"/shop/cancel";return{publicKey:A.publicKey,baseUrl:O,completeUrl:`${O}${_}`,cancelUrl:`${O}${N}`,onError:A.onError}}function FA({children:A,config:O,queryClient:_}){let N=T.useMemo(()=>uA(O),[O]),[Y]=T.useState(()=>_??new n.QueryClient(iA));T.useState(()=>{DA(N.publicKey)});let X=T.useMemo(()=>({config:N,queryClient:Y}),[N,Y]);return LA.jsx(RA.Provider,{value:X,children:LA.jsx(n.QueryClientProvider,{client:Y,children:A})})}var f=require("@tanstack/react-query"),w=require("react");var R={all:["tebex"],categories:()=>[...R.all,"categories"],categoriesList:(A)=>[...R.categories(),"list",{includePackages:A}],category:(A)=>[...R.categories(),"detail",A],packages:()=>[...R.all,"packages"],packagesList:(A)=>[...R.packages(),"list",{categoryId:A}],package:(A)=>[...R.packages(),"detail",A],baskets:()=>[...R.all,"baskets"],basket:(A)=>[...R.baskets(),A],webstore:()=>[...R.all,"webstore"]};var EA=require("zustand"),o=require("zustand/middleware"),j=EA.create()(o.subscribeWithSelector(o.persist((A)=>({basketIdent:null,setBasketIdent:(O)=>{A({basketIdent:O})},clearBasketIdent:()=>{A({basketIdent:null})}}),{name:"tebex-basket-store",skipHydration:typeof window>"u"})));var MA=require("zustand"),s=require("zustand/middleware");var h=MA.create()(s.subscribeWithSelector(s.persist((A)=>({username:null,setUsername:(O)=>{A({username:O})},clearUsername:()=>{A({username:null}),j.getState().clearBasketIdent()}}),{name:"tebex-user-store",skipHydration:typeof window>"u"})));function GA(A){return A instanceof L}function UA(A){return A.success}function YA(A){return!A.success}function VA(A){return A!==null&&A!==void 0}function q(A){return typeof A==="number"&&Number.isInteger(A)&&A>0}function m(A){if(typeof A!=="string")return!1;return/^[a-zA-Z0-9_]{3,16}$/.test(A)}function I(){let A=S(),O=f.useQueryClient(),_=j((G)=>G.basketIdent),N=j((G)=>G.setBasketIdent),Y=j((G)=>G.clearBasketIdent),X=h((G)=>G.username),J=f.useQuery({queryKey:R.basket(_),queryFn:async()=>{if(_===null)return null;return H().getBasket(_)},enabled:_!==null,retry:(G,V)=>{let z=L.fromUnknown(V);if(z.code==="BASKET_NOT_FOUND"||z.code==="BASKET_EXPIRED")return!1;return G<3}});w.useEffect(()=>{if(J.error!==null){let G=L.fromUnknown(J.error);if(G.code==="BASKET_NOT_FOUND"||G.code==="BASKET_EXPIRED")Y()}},[J.error,Y]);let W=w.useCallback(async()=>{if(_!==null)return _;if(X===null||X.length===0)throw new L("NOT_AUTHENTICATED","Username is required to create a basket");let V=await H().createMinecraftBasket(X,A.completeUrl,A.cancelUrl);return N(V.ident),V.ident},[_,X,A.completeUrl,A.cancelUrl,N]),U=f.useMutation({mutationFn:async(G)=>{let V=G.quantity??1;if(!q(V))throw new L("INVALID_QUANTITY","Quantity must be a positive integer");let z=await W(),K=H();return await K.addPackageToBasket(z,G.packageId,V,G.type,G.variableData),K.getBasket(z)},onMutate:async(G)=>{await O.cancelQueries({queryKey:R.basket(_)});let V=O.getQueryData(R.basket(_));if(V!==null&&V!==void 0){let z={id:G.packageId,name:"Loading...",description:"",image:null,in_basket:{quantity:G.quantity??1,price:0,gift_username_id:null,gift_username:null}},K=V.packages.findIndex((M)=>M.id===G.packageId),IA=K>=0?V.packages.map((M,P)=>P===K?{...M,in_basket:{...M.in_basket,quantity:M.in_basket.quantity+(G.quantity??1)}}:M):[...V.packages,z];O.setQueryData(R.basket(_),{...V,packages:IA})}return{previousBasket:V}},onError:(G,V,z)=>{if(z?.previousBasket!==void 0)O.setQueryData(R.basket(_),z.previousBasket);A.onError?.(L.fromUnknown(G))},onSuccess:(G)=>{O.setQueryData(R.basket(_),G)}}),$=f.useMutation({mutationFn:async(G)=>{if(_===null)throw new L("BASKET_NOT_FOUND");let V=H();return await V.removePackage(_,G),V.getBasket(_)},onMutate:async(G)=>{await O.cancelQueries({queryKey:R.basket(_)});let V=O.getQueryData(R.basket(_));if(V!==null&&V!==void 0)O.setQueryData(R.basket(_),{...V,packages:V.packages.filter((z)=>z.id!==G)});return{previousBasket:V}},onError:(G,V,z)=>{if(z?.previousBasket!==void 0)O.setQueryData(R.basket(_),z.previousBasket);A.onError?.(L.fromUnknown(G))},onSuccess:(G)=>{O.setQueryData(R.basket(_),G)}}),D=f.useMutation({mutationFn:async(G)=>{if(!q(G.quantity))throw new L("INVALID_QUANTITY","Quantity must be a positive integer");if(_===null)throw new L("BASKET_NOT_FOUND");let V=H();return await V.updateQuantity(_,G.packageId,G.quantity),V.getBasket(_)},onMutate:async(G)=>{await O.cancelQueries({queryKey:R.basket(_)});let V=O.getQueryData(R.basket(_));if(V!==null&&V!==void 0)O.setQueryData(R.basket(_),{...V,packages:V.packages.map((z)=>z.id===G.packageId?{...z,in_basket:{...z.in_basket,quantity:G.quantity}}:z)});return{previousBasket:V}},onError:(G,V,z)=>{if(z?.previousBasket!==void 0)O.setQueryData(R.basket(_),z.previousBasket);A.onError?.(L.fromUnknown(G))},onSuccess:(G)=>{O.setQueryData(R.basket(_),G)}}),F=w.useCallback(()=>{Y(),O.removeQueries({queryKey:R.baskets()})},[Y,O]),Z=J.data??null,Q=w.useMemo(()=>Z?.packages??[],[Z?.packages]),AA=w.useMemo(()=>Q.reduce((G,V)=>G+V.in_basket.quantity,0),[Q]),OA=w.useMemo(()=>Z?.total_price??0,[Z]),v=w.useMemo(()=>J.error!==null?L.fromUnknown(J.error):null,[J.error]),E=w.useCallback(async(G)=>{await U.mutateAsync(G)},[U]),B=w.useCallback(async(G)=>{await $.mutateAsync(G)},[$]),C=w.useCallback(async(G)=>{await D.mutateAsync(G)},[D]);return{basket:Z,data:Z,basketIdent:_,packages:Q,isLoading:J.isLoading,isFetching:J.isFetching,isAddingPackage:U.isPending,isRemovingPackage:$.isPending,isUpdatingQuantity:D.isPending,error:v,errorCode:v?.code??null,addPackage:E,removePackage:B,updateQuantity:C,clearBasket:F,refetch:J.refetch,itemCount:AA,total:OA,isEmpty:Q.length===0}}var TA=require("@tanstack/react-query"),p=require("react");function XA(A={}){let{includePackages:O=!0,enabled:_=!0}=A,N=TA.useQuery({queryKey:R.categoriesList(O),queryFn:async()=>{return H().getCategories(O)},enabled:_}),Y=p.useMemo(()=>N.error!==null?L.fromUnknown(N.error):null,[N.error]),X=p.useMemo(()=>(U)=>N.data?.find(($)=>$.name.toLowerCase()===U.toLowerCase()),[N.data]),J=p.useMemo(()=>(U)=>N.data?.find(($)=>$.id===U),[N.data]),W=p.useMemo(()=>(U)=>N.data?.find(($)=>$.slug===U),[N.data]);return{categories:N.data??null,data:N.data??null,isLoading:N.isLoading,isFetching:N.isFetching,error:Y,errorCode:Y?.code??null,refetch:N.refetch,getByName:X,getById:J,getBySlug:W}}var qA=require("@tanstack/react-query"),vA=require("react");function JA(A){let{id:O,enabled:_=!0}=A,N=qA.useQuery({queryKey:R.category(O),queryFn:async()=>{return H().getCategory(O)},enabled:_}),Y=vA.useMemo(()=>N.error!==null?L.fromUnknown(N.error):null,[N.error]);return{category:N.data??null,data:N.data??null,isLoading:N.isLoading,isFetching:N.isFetching,error:Y,errorCode:Y?.code??null,refetch:N.refetch}}var CA=require("@tanstack/react-query"),a=require("react");function ZA(A={}){let{basket:O,basketIdent:_,clearBasket:N,isEmpty:Y}=I(),X=S(),J=CA.useMutation({mutationFn:async()=>{if(_===null||O===null)throw new L("BASKET_NOT_FOUND");if(Y)throw new L("BASKET_EMPTY","Basket is empty");if(typeof window>"u")throw new L("TEBEX_JS_NOT_LOADED","Cannot checkout on server side.");let $=window.Tebex;if($===void 0)throw new L("TEBEX_JS_NOT_LOADED",'Tebex.js not loaded. Add <script src="https://js.tebex.io/v/1.9.0.js"></script> to your page.');return new Promise((D,F)=>{let Z=$.checkout,Q=!1,AA=()=>{if(Q)return;Q=!0,C(),N(),A.onSuccess?.(),D()},OA=(z)=>{if(Q)return;Q=!0,C();let K=new L("CHECKOUT_FAILED",String(z));A.onError?.(K),X.onError?.(K),F(K)},v=()=>{if(Q)return;Q=!0,C(),A.onClose?.(),D()},E=null,B=null,C=()=>{if(E!==null)E.disconnect(),E=null;if(B!==null)clearTimeout(B),B=null},G=()=>document.querySelector('iframe[src*="tebex"]')??document.querySelector('[class*="tebex-js"]')??document.querySelector("tebex-checkout[open]"),V=()=>{let z=!1,K=()=>{if(Q)return;if(G()!==null)z=!0;else if(z)v()};if(E=new MutationObserver(()=>{if(Q)return;if(B!==null)clearTimeout(B);B=setTimeout(K,50)}),E.observe(document.body,{childList:!0,subtree:!0}),G()!==null)z=!0};Z.init({ident:_}),Z.on("payment:complete",AA),Z.on("payment:error",OA),Z.on("close",v),Z.launch(),V()})}}),W=a.useCallback(async()=>{await J.mutateAsync()},[J]),U=a.useMemo(()=>J.error!==null?L.fromUnknown(J.error):null,[J.error]);return{launch:W,isLaunching:J.isPending,error:U,errorCode:U?.code??null,canCheckout:O!==null&&!Y,checkoutUrl:O?.links.checkout??null}}var k=require("@tanstack/react-query"),l=require("react");function $A(){let{basket:A}=I(),O=j((D)=>D.basketIdent),_=k.useQueryClient(),N=S(),Y=k.useMutation({mutationFn:async(D)=>{if(O===null)throw new L("BASKET_NOT_FOUND");let F=H();return await F.apply(O,"coupons",{coupon_code:D}),F.getBasket(O)},onMutate:async(D)=>{await _.cancelQueries({queryKey:R.basket(O)});let F=_.getQueryData(R.basket(O));if(F!==null&&F!==void 0)_.setQueryData(R.basket(O),{...F,coupons:[...F.coupons,{code:D}]});return{previousBasket:F}},onError:(D,F,Z)=>{if(Z?.previousBasket!==void 0)_.setQueryData(R.basket(O),Z.previousBasket);N.onError?.(L.fromUnknown(D))},onSuccess:(D)=>{_.setQueryData(R.basket(O),D)}}),X=k.useMutation({mutationFn:async(D)=>{if(O===null)throw new L("BASKET_NOT_FOUND");let F=H();return await F.remove(O,"coupons",{coupon_code:D}),F.getBasket(O)},onMutate:async(D)=>{await _.cancelQueries({queryKey:R.basket(O)});let F=_.getQueryData(R.basket(O));if(F!==null&&F!==void 0)_.setQueryData(R.basket(O),{...F,coupons:F.coupons.filter((Z)=>Z.code!==D)});return{previousBasket:F}},onError:(D,F,Z)=>{if(Z?.previousBasket!==void 0)_.setQueryData(R.basket(O),Z.previousBasket);N.onError?.(L.fromUnknown(D))},onSuccess:(D)=>{_.setQueryData(R.basket(O),D)}}),J=l.useCallback(async(D)=>{await Y.mutateAsync(D)},[Y]),W=l.useCallback(async(D)=>{await X.mutateAsync(D)},[X]),U=Y.error??X.error,$=l.useMemo(()=>U!==null?L.fromUnknown(U):null,[U]);return{coupons:A?.coupons??[],apply:J,remove:W,isApplying:Y.isPending,isRemoving:X.isPending,error:$,errorCode:$?.code??null}}var y=require("@tanstack/react-query"),x=require("react");function HA(){let{basket:A}=I(),O=j((D)=>D.basketIdent),_=y.useQueryClient(),N=S(),Y=y.useMutation({mutationFn:async(D)=>{if(O===null)throw new L("BASKET_NOT_FOUND");let F=H();return await F.apply(O,"creator-codes",{creator_code:D}),F.getBasket(O)},onMutate:async(D)=>{await _.cancelQueries({queryKey:R.basket(O)});let F=_.getQueryData(R.basket(O));if(F!==null&&F!==void 0)_.setQueryData(R.basket(O),{...F,creator_code:D});return{previousBasket:F}},onError:(D,F,Z)=>{if(Z?.previousBasket!==void 0)_.setQueryData(R.basket(O),Z.previousBasket);N.onError?.(L.fromUnknown(D))},onSuccess:(D)=>{_.setQueryData(R.basket(O),D)}}),X=y.useMutation({mutationFn:async()=>{if(O===null)throw new L("BASKET_NOT_FOUND");let D=H();return await D.remove(O,"creator-codes",{creator_code:""}),D.getBasket(O)},onMutate:async()=>{await _.cancelQueries({queryKey:R.basket(O)});let D=_.getQueryData(R.basket(O));if(D!==null&&D!==void 0)_.setQueryData(R.basket(O),{...D,creator_code:""});return{previousBasket:D}},onError:(D,F,Z)=>{if(Z?.previousBasket!==void 0)_.setQueryData(R.basket(O),Z.previousBasket);N.onError?.(L.fromUnknown(D))},onSuccess:(D)=>{_.setQueryData(R.basket(O),D)}}),J=x.useCallback(async(D)=>{await Y.mutateAsync(D)},[Y]),W=x.useCallback(async()=>{await X.mutateAsync()},[X]),U=Y.error??X.error,$=x.useMemo(()=>U!==null?L.fromUnknown(U):null,[U]);return{creatorCode:A?.creator_code??null,apply:J,remove:W,isApplying:Y.isPending,isRemoving:X.isPending,error:$,errorCode:$?.code??null}}var c=require("@tanstack/react-query"),d=require("react");function zA(){let{basket:A}=I(),O=j((D)=>D.basketIdent),_=c.useQueryClient(),N=S(),Y=c.useMutation({mutationFn:async(D)=>{if(O===null)throw new L("BASKET_NOT_FOUND");let F=H();return await F.apply(O,"giftcards",{card_number:D}),F.getBasket(O)},onMutate:async(D)=>{await _.cancelQueries({queryKey:R.basket(O)});let F=_.getQueryData(R.basket(O));if(F!==null&&F!==void 0)_.setQueryData(R.basket(O),{...F,giftcards:[...F.giftcards,{card_number:D}]});return{previousBasket:F}},onError:(D,F,Z)=>{if(Z?.previousBasket!==void 0)_.setQueryData(R.basket(O),Z.previousBasket);N.onError?.(L.fromUnknown(D))},onSuccess:(D)=>{_.setQueryData(R.basket(O),D)}}),X=c.useMutation({mutationFn:async(D)=>{if(O===null)throw new L("BASKET_NOT_FOUND");let F=H();return await F.remove(O,"giftcards",{card_number:D}),F.getBasket(O)},onMutate:async(D)=>{await _.cancelQueries({queryKey:R.basket(O)});let F=_.getQueryData(R.basket(O));if(F!==null&&F!==void 0)_.setQueryData(R.basket(O),{...F,giftcards:F.giftcards.filter((Z)=>Z.card_number!==D)});return{previousBasket:F}},onError:(D,F,Z)=>{if(Z?.previousBasket!==void 0)_.setQueryData(R.basket(O),Z.previousBasket);N.onError?.(L.fromUnknown(D))},onSuccess:(D)=>{_.setQueryData(R.basket(O),D)}}),J=d.useCallback(async(D)=>{await Y.mutateAsync(D)},[Y]),W=d.useCallback(async(D)=>{await X.mutateAsync(D)},[X]),U=Y.error??X.error,$=d.useMemo(()=>U!==null?L.fromUnknown(U):null,[U]);return{giftCards:A?.giftcards??[],apply:J,remove:W,isApplying:Y.isPending,isRemoving:X.isPending,error:$,errorCode:$?.code??null}}var t=require("@tanstack/react-query"),r=require("react");function PA(){let A=j((U)=>U.basketIdent),O=j((U)=>U.setBasketIdent),_=h((U)=>U.username),N=t.useQueryClient(),Y=S(),X=t.useMutation({mutationFn:async(U)=>{if(_===null||_.length===0)throw new L("NOT_AUTHENTICATED","Username is required to gift a package");if(!m(U.targetUsername))throw new L("INVALID_USERNAME","Target username must be 3-16 alphanumeric characters");let $=U.quantity??1;if(!q($))throw new L("INVALID_QUANTITY","Quantity must be a positive integer");let D=H(),F=A;if(F===null)F=(await D.createMinecraftBasket(_,Y.completeUrl,Y.cancelUrl)).ident,O(F);return await D.addPackageToBasket(F,U.packageId,$,"single",{gift_username:U.targetUsername}),D.getBasket(F)},onMutate:async(U)=>{await N.cancelQueries({queryKey:R.basket(A)});let $=N.getQueryData(R.basket(A));if($!==null&&$!==void 0){let D={id:U.packageId,name:"Loading...",description:"",image:null,in_basket:{quantity:U.quantity??1,price:0,gift_username_id:null,gift_username:U.targetUsername}};N.setQueryData(R.basket(A),{...$,packages:[...$.packages,D]})}return{previousBasket:$}},onError:(U,$,D)=>{if(D?.previousBasket!==void 0)N.setQueryData(R.basket(A),D.previousBasket);Y.onError?.(L.fromUnknown(U))},onSuccess:(U)=>{N.setQueryData(R.basket(A),U)}}),J=r.useCallback(async(U)=>{await X.mutateAsync(U)},[X]),W=r.useMemo(()=>X.error!==null?L.fromUnknown(X.error):null,[X.error]);return{gift:J,isGifting:X.isPending,error:W,errorCode:W?.code??null}}var gA=require("@tanstack/react-query"),mA=require("react");function WA(A){let{id:O,enabled:_=!0}=A,N=gA.useQuery({queryKey:R.package(O),queryFn:async()=>{return H().getPackage(O)},enabled:_}),Y=mA.useMemo(()=>N.error!==null?L.fromUnknown(N.error):null,[N.error]);return{package:N.data??null,data:N.data??null,isLoading:N.isLoading,isFetching:N.isFetching,error:Y,errorCode:Y?.code??null,refetch:N.refetch}}var pA=require("@tanstack/react-query"),e=require("react");function jA(A={}){let{categoryId:O,enabled:_=!0}=A,N=pA.useQuery({queryKey:R.packagesList(O),queryFn:async()=>{let W=H();if(O!==void 0)return(await W.getCategory(O)).packages;let U=await W.getCategories(!0),$=[];for(let D of U)$.push(...D.packages);return $},enabled:_}),Y=e.useMemo(()=>N.error!==null?L.fromUnknown(N.error):null,[N.error]),X=e.useMemo(()=>(W)=>N.data?.find((U)=>U.id===W),[N.data]),J=e.useMemo(()=>(W)=>N.data?.find((U)=>U.name.toLowerCase()===W.toLowerCase()),[N.data]);return{packages:N.data??null,data:N.data??null,isLoading:N.isLoading,isFetching:N.isFetching,error:Y,errorCode:Y?.code??null,refetch:N.refetch,getById:X,getByName:J}}var SA=require("react");function QA(){let A=h((J)=>J.username),O=h((J)=>J.setUsername),_=h((J)=>J.clearUsername),N=SA.useCallback((J)=>{let W=J.trim();if(m(W))return O(W),!0;return!1},[O]),Y=SA.useCallback(()=>{_()},[_]),X=A!==null&&A.length>0;return{username:A,setUsername:N,clearUsername:Y,isAuthenticated:X}}var kA=require("@tanstack/react-query"),lA=require("react");function nA(A){let O=A.currency;return{id:A.id,name:A.name,description:A.description,currency:O.iso_4217,domain:A.webstore_url,logo:A.logo.length>0?A.logo:null}}function wA(){let A=kA.useQuery({queryKey:R.webstore(),queryFn:async()=>{let N=await H().getWebstore();return nA(N)},staleTime:300000}),O=lA.useMemo(()=>A.error!==null?L.fromUnknown(A.error):null,[A.error]);return{webstore:A.data??null,data:A.data??null,name:A.data?.name??null,currency:A.data?.currency??null,domain:A.data?.domain??null,isLoading:A.isLoading,isFetching:A.isFetching,error:O,errorCode:O?.code??null,refetch:A.refetch}}function KA(A){return{success:!0,data:A}}function hA(A){return{success:!1,error:A}}
|
|
2
|
+
'use strict';var reactQuery=require('@tanstack/react-query'),react=require('react'),tebex_headless=require('tebex_headless'),zustand=require('zustand'),middleware=require('zustand/middleware'),jsxRuntime=require('react/jsx-runtime');var V=(g=>(g.PROVIDER_NOT_FOUND="PROVIDER_NOT_FOUND",g.INVALID_CONFIG="INVALID_CONFIG",g.NOT_AUTHENTICATED="NOT_AUTHENTICATED",g.INVALID_USERNAME="INVALID_USERNAME",g.BASKET_NOT_FOUND="BASKET_NOT_FOUND",g.BASKET_CREATION_FAILED="BASKET_CREATION_FAILED",g.BASKET_EXPIRED="BASKET_EXPIRED",g.BASKET_EMPTY="BASKET_EMPTY",g.PACKAGE_NOT_FOUND="PACKAGE_NOT_FOUND",g.PACKAGE_OUT_OF_STOCK="PACKAGE_OUT_OF_STOCK",g.PACKAGE_ALREADY_OWNED="PACKAGE_ALREADY_OWNED",g.INVALID_QUANTITY="INVALID_QUANTITY",g.CATEGORY_NOT_FOUND="CATEGORY_NOT_FOUND",g.COUPON_INVALID="COUPON_INVALID",g.COUPON_EXPIRED="COUPON_EXPIRED",g.COUPON_ALREADY_USED="COUPON_ALREADY_USED",g.GIFTCARD_INVALID="GIFTCARD_INVALID",g.GIFTCARD_INSUFFICIENT_BALANCE="GIFTCARD_INSUFFICIENT_BALANCE",g.CREATOR_CODE_INVALID="CREATOR_CODE_INVALID",g.CHECKOUT_FAILED="CHECKOUT_FAILED",g.CHECKOUT_CANCELLED="CHECKOUT_CANCELLED",g.TEBEX_JS_NOT_LOADED="TEBEX_JS_NOT_LOADED",g.NETWORK_ERROR="NETWORK_ERROR",g.TIMEOUT="TIMEOUT",g.RATE_LIMITED="RATE_LIMITED",g.SERVER_ERROR="SERVER_ERROR",g.FORBIDDEN="FORBIDDEN",g.VALIDATION_ERROR="VALIDATION_ERROR",g.NOT_FOUND="NOT_FOUND",g.BASKET_LOCKED="BASKET_LOCKED",g.PACKAGE_DISABLED="PACKAGE_DISABLED",g.UNKNOWN="UNKNOWN",g))(V||{});var u=class e extends Error{code;cause;constructor(t,o,r){super(o??t),Object.setPrototypeOf(this,e.prototype),this.name="TebexError",this.code=t,this.cause=r,typeof Error.captureStackTrace=="function"&&Error.captureStackTrace(this,e);}static extractStatusCode(t){if(typeof t=="object"&&t!==null){if("response"in t){let o=t.response;if(o&&typeof o.status=="number")return o.status}if("status"in t&&typeof t.status=="number")return t.status}return null}static fromUnknown(t){if(t instanceof e)return t;let o=t instanceof Error?t.message:String(t),r=e.extractStatusCode(t);if(r!==null)switch(r){case 401:case 403:return new e("FORBIDDEN",o,t);case 404:{let l=o.toLowerCase();return l.includes("basket")?new e("BASKET_NOT_FOUND",o,t):l.includes("package")?new e("PACKAGE_NOT_FOUND",o,t):new e("NOT_FOUND",o,t)}case 410:return new e("BASKET_EXPIRED",o,t);case 422:return new e("VALIDATION_ERROR",o,t);case 429:return new e("RATE_LIMITED",o,t);case 500:case 502:case 503:return new e("SERVER_ERROR",o,t)}if(t instanceof Error){let l=o.toLowerCase();return l.includes("network")||l.includes("fetch")?new e("NETWORK_ERROR",o,t):l.includes("timeout")?new e("TIMEOUT",o,t):l.includes("rate limit")||l.includes("429")?new e("RATE_LIMITED",o,t):l.includes("basket")&&l.includes("not found")?new e("BASKET_NOT_FOUND",o,t):l.includes("package")&&l.includes("not found")?new e("PACKAGE_NOT_FOUND",o,t):l.includes("coupon")&&l.includes("invalid")?new e("COUPON_INVALID",o,t):l.includes("coupon")&&l.includes("expired")?new e("COUPON_EXPIRED",o,t):l.includes("gift")&&l.includes("invalid")?new e("GIFTCARD_INVALID",o,t):new e("UNKNOWN",o,t)}return new e("UNKNOWN",o)}static fromJSON(t){return new e(t.code,t.message??t.code)}toJSON(){return {name:this.name,code:this.code,message:this.message,...this.cause instanceof Error?{cause:this.cause.message}:{}}}};var v=null;function W(e){v=new tebex_headless.TebexHeadless(e);}function C(){if(v===null)throw new u("PROVIDER_NOT_FOUND","Tebex client not initialized. Ensure TebexProvider wraps your component tree.");return v}function j(){return v!==null}var U=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 P=zustand.create()(middleware.subscribeWithSelector(middleware.persist(e=>({username:null,setUsername:t=>{e({username:t});},clearUsername:()=>{e({username:null}),U.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 H=react.createContext(null);function K(){let e=react.useContext(H);if(e===null)throw new u("PROVIDER_NOT_FOUND","useTebexContext must be used within TebexProvider or TebexMockProvider");return e}function B(){let{config:e}=K();return e}var Le={defaultOptions:{queries:{staleTime:60*1e3,gcTime:300*1e3,retry:3,retryDelay:e=>Math.min(1e3*2**e,3e4),refetchOnWindowFocus:false,refetchOnReconnect:true},mutations:{retry:2,retryDelay:e=>Math.min(500*2**e,5e3)}}};function qe(e){let t=e.baseUrl.replace(/\/$/,""),o=e.urls?.complete??"/shop/complete",r=e.urls?.cancel??"/shop/cancel";return {publicKey:e.publicKey,baseUrl:t,completeUrl:`${t}${o}`,cancelUrl:`${t}${r}`,onError:e.onError}}function ee({children:e,config:t,queryClient:o}){let r=react.useMemo(()=>qe(t),[t]),[l]=react.useState(()=>o??new reactQuery.QueryClient(Le));react.useState(()=>{W(r.publicKey);}),react.useEffect(()=>{U.persist.rehydrate(),P.persist.rehydrate();},[]),react.useEffect(()=>{let f=x=>{(x.key==="tebex-basket-store"||x.key==="tebex-user-store")&&(U.persist.rehydrate(),P.persist.rehydrate());};return window.addEventListener("storage",f),()=>{window.removeEventListener("storage",f);}},[]);let k=react.useMemo(()=>({config:r,queryClient:l}),[r,l]);return jsxRuntime.jsx(H.Provider,{value:k,children:jsxRuntime.jsx(reactQuery.QueryClientProvider,{client:l,children:e})})}var i={all:["tebex"],categories:()=>[...i.all,"categories"],categoriesList:e=>[...i.categories(),"list",{includePackages:e}],category:e=>[...i.categories(),"detail",e],packages:()=>[...i.all,"packages"],packagesList:e=>[...i.packages(),"list",{categoryId:e}],package:e=>[...i.packages(),"detail",e],baskets:()=>[...i.all,"baskets"],basket:e=>[...i.baskets(),e],webstore:()=>[...i.all,"webstore"]};function te(e){return e instanceof u?true:typeof e=="object"&&e!==null&&"name"in e&&"code"in e&&e.name==="TebexError"}function re(e){return e.success}function ne(e){return !e.success}function se(e){return e!=null}function oe(e){return typeof e=="string"&&e.length>0}function ae(e){return typeof e=="number"&&e>0&&Number.isFinite(e)}function R(e){return typeof e=="number"&&Number.isInteger(e)&&e>0}function N(e){return typeof e!="string"?false:/^[a-zA-Z0-9_]{3,16}$/.test(e)}var S=null;function _(){let e=B(),t=reactQuery.useQueryClient(),o=U(c=>c.basketIdent),r=U(c=>c.setBasketIdent),l=U(c=>c.clearBasketIdent),k=P(c=>c.username),f=react.useRef(o);f.current=o;let x=reactQuery.useQuery({queryKey:i.basket(o),queryFn:async()=>o===null?null:C().getBasket(o),enabled:o!==null,retry:(c,p)=>{let d=u.fromUnknown(p);return d.code==="BASKET_NOT_FOUND"||d.code==="BASKET_EXPIRED"?false:c<3}});react.useEffect(()=>{if(x.error!==null){let c=u.fromUnknown(x.error);(c.code==="BASKET_NOT_FOUND"||c.code==="BASKET_EXPIRED")&&l();}},[x.error,l]);let E=react.useCallback(async()=>{let c=U.getState().basketIdent;return c!==null?c:(S!==null||(S=(async()=>{if(k===null||k.length===0)throw new u("NOT_AUTHENTICATED","Username is required to create a basket");let T=await C().createMinecraftBasket(k,e.completeUrl,e.cancelUrl);return r(T.ident),T.ident})().finally(()=>{S=null;})),S)},[k,e.completeUrl,e.cancelUrl,r]),m=reactQuery.useMutation({scope:{id:"basket-mutations"},mutationFn:async c=>{let p=c.quantity??1;if(!R(p))throw new u("INVALID_QUANTITY","Quantity must be a positive integer");let d=await E(),T=C();return await T.addPackageToBasket(d,c.packageId,p,c.type,c.variableData),T.getBasket(d)},onMutate:async c=>{let p=f.current;if(p===null)return {previousBasket:void 0,ident:p};await t.cancelQueries({queryKey:i.basket(p)});let d=t.getQueryData(i.basket(p));if(d!=null){let T={id:c.packageId,name:"Loading...",description:"",image:null,in_basket:{quantity:c.quantity??1,price:0,gift_username_id:null,gift_username:null}},G=d.packages.findIndex(A=>A.id===c.packageId),Oe=G>=0?d.packages.map((A,Re)=>Re===G?{...A,in_basket:{...A.in_basket,quantity:A.in_basket.quantity+(c.quantity??1)}}:A):[...d.packages,T];t.setQueryData(i.basket(p),{...d,packages:Oe});}return {previousBasket:d,ident:p}},onError:(c,p,d)=>{d?.previousBasket!==void 0&&d.ident!==null&&t.setQueryData(i.basket(d.ident),d.previousBasket),e.onError?.(u.fromUnknown(c));},onSuccess:(c,p,d)=>{let T=d.ident??f.current;T!==null&&t.setQueryData(i.basket(T),c);}}),y=reactQuery.useMutation({scope:{id:"basket-mutations"},mutationFn:async c=>{if(o===null)throw new u("BASKET_NOT_FOUND");let p=C();return await p.removePackage(o,c),p.getBasket(o)},onMutate:async c=>{let p=f.current;if(p===null)return {previousBasket:void 0,ident:p};await t.cancelQueries({queryKey:i.basket(p)});let d=t.getQueryData(i.basket(p));return d!=null&&t.setQueryData(i.basket(p),{...d,packages:d.packages.filter(T=>T.id!==c)}),{previousBasket:d,ident:p}},onError:(c,p,d)=>{d?.previousBasket!==void 0&&d.ident!==null&&t.setQueryData(i.basket(d.ident),d.previousBasket),e.onError?.(u.fromUnknown(c));},onSuccess:(c,p,d)=>{let T=d.ident??f.current;T!==null&&t.setQueryData(i.basket(T),c);}}),n=reactQuery.useMutation({scope:{id:"basket-mutations"},mutationFn:async c=>{if(!R(c.quantity))throw new u("INVALID_QUANTITY","Quantity must be a positive integer");if(o===null)throw new u("BASKET_NOT_FOUND");let p=C();return await p.updateQuantity(o,c.packageId,c.quantity),p.getBasket(o)},onMutate:async c=>{let p=f.current;if(p===null)return {previousBasket:void 0,ident:p};await t.cancelQueries({queryKey:i.basket(p)});let d=t.getQueryData(i.basket(p));return d!=null&&t.setQueryData(i.basket(p),{...d,packages:d.packages.map(T=>T.id===c.packageId?{...T,in_basket:{...T.in_basket,quantity:c.quantity}}:T)}),{previousBasket:d,ident:p}},onError:(c,p,d)=>{d?.previousBasket!==void 0&&d.ident!==null&&t.setQueryData(i.basket(d.ident),d.previousBasket),e.onError?.(u.fromUnknown(c));},onSuccess:(c,p,d)=>{let T=d.ident??f.current;T!==null&&t.setQueryData(i.basket(T),c);}}),a=react.useCallback(()=>{l(),t.removeQueries({queryKey:i.baskets()});},[l,t]),s=x.data??null,b=react.useMemo(()=>s?.packages??[],[s?.packages]),M=react.useMemo(()=>b.reduce((c,p)=>c+p.in_basket.quantity,0),[b]),L=react.useMemo(()=>s?.total_price??0,[s?.total_price]),I=x.error??m.error??y.error??n.error,w=react.useMemo(()=>I!==null?u.fromUnknown(I):null,[I]),O=react.useCallback(async c=>{await m.mutateAsync(c);},[m]),q=react.useCallback(async c=>{await y.mutateAsync(c);},[y]),D=react.useCallback(async c=>{await n.mutateAsync(c);},[n]);return {basket:s,data:s,basketIdent:o,packages:b,isLoading:x.isLoading,isFetching:x.isFetching,isAddingPackage:m.isPending,isRemovingPackage:y.isPending,isUpdatingQuantity:n.isPending,error:w,errorCode:w?.code??null,addPackage:O,removePackage:q,updateQuantity:D,clearBasket:a,refetch:x.refetch,itemCount:M,total:L,isEmpty:b.length===0}}function ie(e={}){let{includePackages:t=true,enabled:o=true}=e,r=reactQuery.useQuery({queryKey:i.categoriesList(t),queryFn:async()=>C().getCategories(t),enabled:o,staleTime:300*1e3}),l=react.useMemo(()=>r.error!==null?u.fromUnknown(r.error):null,[r.error]),k=react.useRef(r.data);k.current=r.data;let f=react.useCallback(m=>k.current?.find(y=>y.name.toLowerCase()===m.toLowerCase()),[]),x=react.useCallback(m=>k.current?.find(y=>y.id===m),[]),E=react.useCallback(m=>k.current?.find(y=>y.slug===m),[]);return {categories:r.data??null,data:r.data??null,isLoading:r.isLoading,isFetching:r.isFetching,error:l,errorCode:l?.code??null,refetch:r.refetch,getByName:f,getById:x,getBySlug:E}}function ue(e){let{id:t,enabled:o=true}=e,r=reactQuery.useQuery({queryKey:i.category(t),queryFn:async()=>C().getCategory(t),enabled:o&&t>0&&Number.isInteger(t),staleTime:300*1e3}),l=react.useMemo(()=>r.error!==null?u.fromUnknown(r.error):null,[r.error]);return {category:r.data??null,data:r.data??null,isLoading:r.isLoading,isFetching:r.isFetching,error:l,errorCode:l?.code??null,refetch:r.refetch}}var tt=1800*1e3,F=0;function ce(e={}){let{basket:t,basketIdent:o,clearBasket:r,isEmpty:l}=_(),k=B(),f=reactQuery.useMutation({mutationFn:async()=>{if(o===null||t===null)throw new u("BASKET_NOT_FOUND");if(l)throw new u("BASKET_EMPTY","Basket is empty");if(typeof window>"u")throw new u("TEBEX_JS_NOT_LOADED","Cannot checkout on server side.");let m=window.Tebex;if(m===void 0)throw new u("TEBEX_JS_NOT_LOADED",'Tebex.js not loaded. Add <script src="https://js.tebex.io/v/1.9.0.js"></script> to your page.');return new Promise((y,n)=>{let a=m.checkout,s=false,b=++F,M=()=>{b!==F||s||(s=true,D(),r(),e.onSuccess?.(),y());},L=d=>{if(b!==F||s)return;s=true,D();let T=new u("CHECKOUT_FAILED",String(d));e.onError?.(T),k.onError?.(T),n(T);},I=()=>{b!==F||s||(s=true,D(),e.onClose?.(),y());},w=null,O=null,q=setTimeout(()=>{s||(s=true,D(),n(new u("TIMEOUT","Checkout session timed out")));},tt),D=()=>{clearTimeout(q),w!==null&&(w.disconnect(),w=null),O!==null&&(clearTimeout(O),O=null);},c=()=>document.querySelector('iframe[src*="tebex"]')??document.querySelector('[class*="tebex-js"]')??document.querySelector("tebex-checkout[open]"),p=()=>{let d=false,T=()=>{if(s)return;c()!==null?d=true:d&&I();};w=new MutationObserver(()=>{s||(O!==null&&clearTimeout(O),O=setTimeout(T,50));}),w.observe(document.body,{childList:true,subtree:true}),c()!==null&&(d=true);};a.init({ident:o}),a.on("payment:complete",M),a.on("payment:error",L),a.on("close",I),a.launch(),p();})}}),x=react.useCallback(async()=>{await f.mutateAsync();},[f]),E=react.useMemo(()=>f.error!==null?u.fromUnknown(f.error):null,[f.error]);return {launch:x,isLaunching:f.isPending,error:E,errorCode:E?.code??null,canCheckout:t!==null&&!l,checkoutUrl:t?.links.checkout??null}}function de(){let{basket:e}=_(),t=U(n=>n.basketIdent),o=react.useRef(t);o.current=t;let r=reactQuery.useQueryClient(),l=B(),k=reactQuery.useMutation({scope:{id:"basket-mutations"},mutationFn:async n=>{let a=o.current;if(a===null)throw new u("BASKET_NOT_FOUND");let s=C();return await s.apply(a,"coupons",{coupon_code:n}),s.getBasket(a)},onMutate:async n=>{let a=o.current;if(a===null)return;await r.cancelQueries({queryKey:i.basket(a)});let s=r.getQueryData(i.basket(a));return s!==void 0&&r.setQueryData(i.basket(a),{...s,coupons:[...s.coupons,{code:n}]}),{previousBasket:s,ident:a}},onError:(n,a,s)=>{s?.previousBasket!==void 0&&r.setQueryData(i.basket(s.ident),s.previousBasket),l.onError?.(u.fromUnknown(n));},onSuccess:(n,a,s)=>{let b=s?.ident??o.current;b!==null&&r.setQueryData(i.basket(b),n);}}),f=reactQuery.useMutation({scope:{id:"basket-mutations"},mutationFn:async n=>{let a=o.current;if(a===null)throw new u("BASKET_NOT_FOUND");let s=C();return await s.remove(a,"coupons",{coupon_code:n}),s.getBasket(a)},onMutate:async n=>{let a=o.current;if(a===null)return;await r.cancelQueries({queryKey:i.basket(a)});let s=r.getQueryData(i.basket(a));return s!==void 0&&r.setQueryData(i.basket(a),{...s,coupons:s.coupons.filter(b=>b.code!==n)}),{previousBasket:s,ident:a}},onError:(n,a,s)=>{s?.previousBasket!==void 0&&r.setQueryData(i.basket(s.ident),s.previousBasket),l.onError?.(u.fromUnknown(n));},onSuccess:(n,a,s)=>{let b=s?.ident??o.current;b!==null&&r.setQueryData(i.basket(b),n);}}),x=react.useCallback(async n=>{await k.mutateAsync(n);},[k]),E=react.useCallback(async n=>{await f.mutateAsync(n);},[f]),m=k.error??f.error,y=react.useMemo(()=>m!==null?u.fromUnknown(m):null,[m]);return {coupons:e?.coupons??[],apply:x,remove:E,isApplying:k.isPending,isRemoving:f.isPending,error:y,errorCode:y?.code??null}}function ke(){let{basket:e}=_(),t=U(n=>n.basketIdent),o=react.useRef(t);o.current=t;let r=reactQuery.useQueryClient(),l=B(),k=reactQuery.useMutation({scope:{id:"basket-mutations"},mutationFn:async n=>{let a=o.current;if(a===null)throw new u("BASKET_NOT_FOUND");let s=C();return await s.apply(a,"creator-codes",{creator_code:n}),s.getBasket(a)},onMutate:async n=>{let a=o.current;if(a===null)return;await r.cancelQueries({queryKey:i.basket(a)});let s=r.getQueryData(i.basket(a));return s!==void 0&&r.setQueryData(i.basket(a),{...s,creator_code:n}),{previousBasket:s,ident:a}},onError:(n,a,s)=>{s?.previousBasket!==void 0&&r.setQueryData(i.basket(s.ident),s.previousBasket),l.onError?.(u.fromUnknown(n));},onSuccess:(n,a,s)=>{let b=s?.ident??o.current;b!==null&&r.setQueryData(i.basket(b),n);}}),f=reactQuery.useMutation({scope:{id:"basket-mutations"},mutationFn:async()=>{let n=o.current;if(n===null)throw new u("BASKET_NOT_FOUND");let a=C();return await a.remove(n,"creator-codes",{creator_code:""}),a.getBasket(n)},onMutate:async()=>{let n=o.current;if(n===null)return;await r.cancelQueries({queryKey:i.basket(n)});let a=r.getQueryData(i.basket(n));return a!==void 0&&r.setQueryData(i.basket(n),{...a,creator_code:""}),{previousBasket:a,ident:n}},onError:(n,a,s)=>{s?.previousBasket!==void 0&&r.setQueryData(i.basket(s.ident),s.previousBasket),l.onError?.(u.fromUnknown(n));},onSuccess:(n,a,s)=>{let b=s?.ident??o.current;b!==null&&r.setQueryData(i.basket(b),n);}}),x=react.useCallback(async n=>{await k.mutateAsync(n);},[k]),E=react.useCallback(async()=>{await f.mutateAsync();},[f]),m=k.error??f.error,y=react.useMemo(()=>m!==null?u.fromUnknown(m):null,[m]);return {creatorCode:e?.creator_code??null,apply:x,remove:E,isApplying:k.isPending,isRemoving:f.isPending,error:y,errorCode:y?.code??null}}function be(){let{basket:e}=_(),t=U(n=>n.basketIdent),o=react.useRef(t);o.current=t;let r=reactQuery.useQueryClient(),l=B(),k=reactQuery.useMutation({scope:{id:"basket-mutations"},mutationFn:async n=>{let a=o.current;if(a===null)throw new u("BASKET_NOT_FOUND");let s=C();return await s.apply(a,"giftcards",{card_number:n}),s.getBasket(a)},onMutate:async n=>{let a=o.current;if(a===null)return;await r.cancelQueries({queryKey:i.basket(a)});let s=r.getQueryData(i.basket(a));return s!==void 0&&r.setQueryData(i.basket(a),{...s,giftcards:[...s.giftcards,{card_number:n}]}),{previousBasket:s,ident:a}},onError:(n,a,s)=>{s?.previousBasket!==void 0&&r.setQueryData(i.basket(s.ident),s.previousBasket),l.onError?.(u.fromUnknown(n));},onSuccess:(n,a,s)=>{let b=s?.ident??o.current;b!==null&&r.setQueryData(i.basket(b),n);}}),f=reactQuery.useMutation({scope:{id:"basket-mutations"},mutationFn:async n=>{let a=o.current;if(a===null)throw new u("BASKET_NOT_FOUND");let s=C();return await s.remove(a,"giftcards",{card_number:n}),s.getBasket(a)},onMutate:async n=>{let a=o.current;if(a===null)return;await r.cancelQueries({queryKey:i.basket(a)});let s=r.getQueryData(i.basket(a));return s!==void 0&&r.setQueryData(i.basket(a),{...s,giftcards:s.giftcards.filter(b=>b.card_number!==n)}),{previousBasket:s,ident:a}},onError:(n,a,s)=>{s?.previousBasket!==void 0&&r.setQueryData(i.basket(s.ident),s.previousBasket),l.onError?.(u.fromUnknown(n));},onSuccess:(n,a,s)=>{let b=s?.ident??o.current;b!==null&&r.setQueryData(i.basket(b),n);}}),x=react.useCallback(async n=>{await k.mutateAsync(n);},[k]),E=react.useCallback(async n=>{await f.mutateAsync(n);},[f]),m=k.error??f.error,y=react.useMemo(()=>m!==null?u.fromUnknown(m):null,[m]);return {giftCards:e?.giftcards??[],apply:x,remove:E,isApplying:k.isPending,isRemoving:f.isPending,error:y,errorCode:y?.code??null}}function Te(){let e=U(m=>m.basketIdent),t=react.useRef(e);t.current=e;let o=U(m=>m.setBasketIdent),r=P(m=>m.username),l=reactQuery.useQueryClient(),k=B(),f=reactQuery.useMutation({scope:{id:"basket-mutations"},mutationFn:async m=>{if(r===null||r.length===0)throw new u("NOT_AUTHENTICATED","Username is required to gift a package");if(!N(m.targetUsername))throw new u("INVALID_USERNAME","Target username must be 3-16 alphanumeric characters");let y=m.quantity??1;if(!R(y))throw new u("INVALID_QUANTITY","Quantity must be a positive integer");let n=C(),a=U.getState().basketIdent;return a===null&&(a=(await n.createMinecraftBasket(r,k.completeUrl,k.cancelUrl)).ident,o(a)),await n.addPackageToBasket(a,m.packageId,y,"single",{gift_username:m.targetUsername}),n.getBasket(a)},onMutate:async m=>{let y=t.current;if(y===null)return;await l.cancelQueries({queryKey:i.basket(y)});let n=l.getQueryData(i.basket(y));if(n!==void 0){let a={id:m.packageId,name:"Loading...",description:"",image:null,in_basket:{quantity:m.quantity??1,price:0,gift_username_id:null,gift_username:m.targetUsername}};l.setQueryData(i.basket(y),{...n,packages:[...n.packages,a]});}return {previousBasket:n,ident:y}},onError:(m,y,n)=>{n?.previousBasket!==void 0&&l.setQueryData(i.basket(n.ident),n.previousBasket),k.onError?.(u.fromUnknown(m));},onSuccess:(m,y,n)=>{let a=n?.ident??t.current;a!==null&&l.setQueryData(i.basket(a),m);}}),x=react.useCallback(async m=>{await f.mutateAsync(m);},[f]),E=react.useMemo(()=>f.error!==null?u.fromUnknown(f.error):null,[f.error]);return {gift:x,isGifting:f.isPending,error:E,errorCode:E?.code??null}}function Ce(e){let{id:t,enabled:o=true}=e,r=reactQuery.useQuery({queryKey:i.package(t),queryFn:async()=>C().getPackage(t),enabled:o&&t>0&&Number.isInteger(t),staleTime:300*1e3}),l=react.useMemo(()=>r.error!==null?u.fromUnknown(r.error):null,[r.error]);return {package:r.data??null,data:r.data??null,isLoading:r.isLoading,isFetching:r.isFetching,error:l,errorCode:l?.code??null,refetch:r.refetch}}function Ee(e={}){let{categoryId:t,enabled:o=true}=e,r=reactQuery.useQuery({queryKey:i.packagesList(t),queryFn:async()=>{let E=C();if(t!==void 0)return (await E.getCategory(t)).packages;let m=await E.getCategories(true),y=[];for(let n of m)y.push(...n.packages);return y},enabled:o,staleTime:300*1e3}),l=react.useMemo(()=>r.error!==null?u.fromUnknown(r.error):null,[r.error]),k=react.useRef(r.data);k.current=r.data;let f=react.useCallback(E=>k.current?.find(m=>m.id===E),[]),x=react.useCallback(E=>k.current?.find(m=>m.name.toLowerCase()===E.toLowerCase()),[]);return {packages:r.data??null,data:r.data??null,isLoading:r.isLoading,isFetching:r.isFetching,error:l,errorCode:l?.code??null,refetch:r.refetch,getById:f,getByName:x}}function Be(){let e=P(f=>f.username),t=P(f=>f.setUsername),o=P(f=>f.clearUsername),r=react.useCallback(f=>{let x=f.trim();return N(x)?(t(x),true):false},[t]),l=react.useCallback(()=>{o();},[o]),k=e!==null&&e.length>0;return {username:e,setUsername:r,clearUsername:l,isAuthenticated:k}}function Ut(e){return typeof e=="object"&&e!==null&&"iso_4217"in e&&typeof e.iso_4217=="string"}function Bt(e){let t=e.currency,o;return Ut(t)?o=t.iso_4217:typeof t=="string"?o=t:o="USD",{id:e.id,name:e.name,description:e.description,currency:o,domain:e.webstore_url,logo:e.logo.length>0?e.logo:null}}function Pe(){let e=reactQuery.useQuery({queryKey:i.webstore(),queryFn:async()=>{let r=await C().getWebstore();return Bt(r)},staleTime:3e5}),t=react.useMemo(()=>e.error!==null?u.fromUnknown(e.error):null,[e.error]);return {webstore:e.data??null,data:e.data??null,name:e.data?.name??null,currency:e.data?.currency??null,domain:e.data?.domain??null,isLoading:e.isLoading,isFetching:e.isFetching,error:t,errorCode:t?.code??null,refetch:e.refetch}}function _e(e){return {success:true,data:e}}function we(e){return {success:false,error:e}}
|
|
3
|
+
exports.TebexError=u;exports.TebexErrorCode=V;exports.TebexProvider=ee;exports.err=we;exports.getTebexClient=C;exports.isDefined=se;exports.isError=ne;exports.isNonEmptyString=oe;exports.isPositiveInteger=R;exports.isPositiveNumber=ae;exports.isSuccess=re;exports.isTebexClientInitialized=j;exports.isTebexError=te;exports.isValidMinecraftUsername=N;exports.ok=_e;exports.tebexKeys=i;exports.useBasket=_;exports.useBasketStore=U;exports.useCategories=ie;exports.useCategory=ue;exports.useCheckout=ce;exports.useCoupons=de;exports.useCreatorCodes=ke;exports.useGiftCards=be;exports.useGiftPackage=Te;exports.usePackage=Ce;exports.usePackages=Ee;exports.useTebexConfig=B;exports.useTebexContext=K;exports.useUser=Be;exports.useUserStore=P;exports.useWebstore=Pe;//# sourceMappingURL=index.cjs.map
|
|
4
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -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.cjs","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"]}
|