@neosianexus/super-tebex 3.4.2 → 3.4.3
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/dist/errors/TebexError.d.ts +1 -1
- package/dist/errors/TebexError.d.ts.map +1 -1
- package/dist/hooks/useBasket.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/index.cjs +2 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/provider/TebexProvider.d.ts +1 -1
- package/dist/provider/TebexProvider.d.ts.map +1 -1
- package/dist/provider/context.d.ts +6 -0
- package/dist/provider/context.d.ts.map +1 -1
- package/dist/provider/index.d.ts +1 -1
- package/dist/provider/index.d.ts.map +1 -1
- package/dist/services/api.d.ts.map +1 -1
- package/dist/stores/basketStore.d.ts +6 -2
- package/dist/stores/basketStore.d.ts.map +1 -1
- package/dist/stores/userStore.d.ts +6 -2
- package/dist/stores/userStore.d.ts.map +1 -1
- package/dist/testing/TebexMockProvider.d.ts.map +1 -1
- package/dist/testing/index.cjs +2 -2
- package/dist/testing/index.cjs.map +1 -1
- package/dist/testing/index.js +2 -2
- package/dist/testing/index.js.map +1 -1
- package/dist/types/guards.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -48,5 +48,5 @@ interface TebexProviderProps {
|
|
|
48
48
|
* ```
|
|
49
49
|
*/
|
|
50
50
|
export declare function TebexProvider({ children, config, queryClient: externalQueryClient, }: TebexProviderProps): ReactNode;
|
|
51
|
-
export { useTebexConfig, useTebexContext } from './context';
|
|
51
|
+
export { useTebexConfig, useTebexContext, useTebexHydrated } from './context';
|
|
52
52
|
//# sourceMappingURL=TebexProvider.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TebexProvider.d.ts","sourceRoot":"","sources":["../../src/provider/TebexProvider.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAA+C,MAAM,uBAAuB,CAAC;AACjG,OAAO,
|
|
1
|
+
{"version":3,"file":"TebexProvider.d.ts","sourceRoot":"","sources":["../../src/provider/TebexProvider.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAA+C,MAAM,uBAAuB,CAAC;AACjG,OAAO,EAA6C,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAOlF,OAAO,KAAK,EAAuB,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAqDxE;;GAEG;AACH,UAAU,kBAAkB;IAC1B,QAAQ,CAAC,QAAQ,EAAE,SAAS,CAAC;IAC7B,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;IAC7B,mFAAmF;IACnF,QAAQ,CAAC,WAAW,CAAC,EAAE,WAAW,GAAG,SAAS,CAAC;CAChD;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,wBAAgB,aAAa,CAAC,EAC5B,QAAQ,EACR,MAAM,EACN,WAAW,EAAE,mBAAmB,GACjC,EAAE,kBAAkB,GAAG,SAAS,CAiEhC;AAED,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC"}
|
|
@@ -6,6 +6,7 @@ import type { ResolvedTebexConfig } from '../types/config';
|
|
|
6
6
|
export interface TebexContextValue {
|
|
7
7
|
readonly config: ResolvedTebexConfig;
|
|
8
8
|
readonly queryClient: QueryClient;
|
|
9
|
+
readonly isHydrated: boolean;
|
|
9
10
|
}
|
|
10
11
|
/**
|
|
11
12
|
* Tebex context for sharing configuration and QueryClient.
|
|
@@ -24,4 +25,9 @@ export declare function useTebexContext(): TebexContextValue;
|
|
|
24
25
|
* Useful when you don't need the QueryClient.
|
|
25
26
|
*/
|
|
26
27
|
export declare function useTebexConfig(): ResolvedTebexConfig;
|
|
28
|
+
/**
|
|
29
|
+
* Hook to check if Zustand stores have finished hydrating from localStorage.
|
|
30
|
+
* Useful to prevent actions before persisted state is available.
|
|
31
|
+
*/
|
|
32
|
+
export declare function useTebexHydrated(): boolean;
|
|
27
33
|
//# sourceMappingURL=context.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/provider/context.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAKzD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAE3D;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,MAAM,EAAE,mBAAmB,CAAC;IACrC,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/provider/context.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAKzD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAE3D;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,MAAM,EAAE,mBAAmB,CAAC;IACrC,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAC;IAClC,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;CAC9B;AAED;;;GAGG;AACH,eAAO,MAAM,YAAY,mDAAgD,CAAC;AAE1E;;;;;GAKG;AACH,wBAAgB,eAAe,IAAI,iBAAiB,CAWnD;AAED;;;GAGG;AACH,wBAAgB,cAAc,IAAI,mBAAmB,CAGpD;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,IAAI,OAAO,CAG1C"}
|
package/dist/provider/index.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { TebexProvider, useTebexConfig, useTebexContext } from './TebexProvider';
|
|
1
|
+
export { TebexProvider, useTebexConfig, useTebexContext, useTebexHydrated } from './TebexProvider';
|
|
2
2
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/provider/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/provider/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../src/services/api.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAM/C;;;GAGG;AACH,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../src/services/api.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAM/C;;;GAGG;AACH,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CASvD;AAED;;;GAGG;AACH,wBAAgB,cAAc,IAAI,aAAa,CAK9C;AAED;;GAEG;AACH,wBAAgB,wBAAwB,IAAI,OAAO,CAElD;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,IAAI,CAEvC"}
|
|
@@ -31,13 +31,17 @@ export declare const useBasketStore: import("zustand").UseBoundStore<Omit<Omit<i
|
|
|
31
31
|
setState(partial: BasketStore | Partial<BasketStore> | ((state: BasketStore) => BasketStore | Partial<BasketStore>), replace?: false | undefined): unknown;
|
|
32
32
|
setState(state: BasketStore | ((state: BasketStore) => BasketStore), replace: true): unknown;
|
|
33
33
|
persist: {
|
|
34
|
-
setOptions: (options: Partial<import("zustand/middleware").PersistOptions<BasketStore,
|
|
34
|
+
setOptions: (options: Partial<import("zustand/middleware").PersistOptions<BasketStore, {
|
|
35
|
+
basketIdent: string | null;
|
|
36
|
+
}, unknown>>) => void;
|
|
35
37
|
clearStorage: () => void;
|
|
36
38
|
rehydrate: () => Promise<void> | void;
|
|
37
39
|
hasHydrated: () => boolean;
|
|
38
40
|
onHydrate: (fn: (state: BasketStore) => void) => () => void;
|
|
39
41
|
onFinishHydration: (fn: (state: BasketStore) => void) => () => void;
|
|
40
|
-
getOptions: () => Partial<import("zustand/middleware").PersistOptions<BasketStore,
|
|
42
|
+
getOptions: () => Partial<import("zustand/middleware").PersistOptions<BasketStore, {
|
|
43
|
+
basketIdent: string | null;
|
|
44
|
+
}, unknown>>;
|
|
41
45
|
};
|
|
42
46
|
}>;
|
|
43
47
|
export type { BasketStore, BasketStoreActions, BasketStoreState };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"basketStore.d.ts","sourceRoot":"","sources":["../../src/stores/basketStore.ts"],"names":[],"mappings":"AAKA;;GAEG;AACH,UAAU,gBAAgB;IACxB,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;CACrC;AAED;;GAEG;AACH,UAAU,kBAAkB;IAC1B,QAAQ,CAAC,cAAc,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACjD,QAAQ,CAAC,gBAAgB,EAAE,MAAM,IAAI,CAAC;CACvC;AAED;;GAEG;AACH,KAAK,WAAW,GAAG,gBAAgB,GAAG,kBAAkB,CAAC;AAEzD;;;GAGG;AACH,eAAO,MAAM,cAAc
|
|
1
|
+
{"version":3,"file":"basketStore.d.ts","sourceRoot":"","sources":["../../src/stores/basketStore.ts"],"names":[],"mappings":"AAKA;;GAEG;AACH,UAAU,gBAAgB;IACxB,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;CACrC;AAED;;GAEG;AACH,UAAU,kBAAkB;IAC1B,QAAQ,CAAC,cAAc,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACjD,QAAQ,CAAC,gBAAgB,EAAE,MAAM,IAAI,CAAC;CACvC;AAED;;GAEG;AACH,KAAK,WAAW,GAAG,gBAAgB,GAAG,kBAAkB,CAAC;AAEzD;;;GAGG;AACH,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;EA0C1B,CAAC;AAEF,YAAY,EAAE,WAAW,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,CAAC"}
|
|
@@ -31,13 +31,17 @@ export declare const useUserStore: import("zustand").UseBoundStore<Omit<Omit<imp
|
|
|
31
31
|
setState(partial: UserStore | Partial<UserStore> | ((state: UserStore) => UserStore | Partial<UserStore>), replace?: false | undefined): unknown;
|
|
32
32
|
setState(state: UserStore | ((state: UserStore) => UserStore), replace: true): unknown;
|
|
33
33
|
persist: {
|
|
34
|
-
setOptions: (options: Partial<import("zustand/middleware").PersistOptions<UserStore,
|
|
34
|
+
setOptions: (options: Partial<import("zustand/middleware").PersistOptions<UserStore, {
|
|
35
|
+
username: string | null;
|
|
36
|
+
}, unknown>>) => void;
|
|
35
37
|
clearStorage: () => void;
|
|
36
38
|
rehydrate: () => Promise<void> | void;
|
|
37
39
|
hasHydrated: () => boolean;
|
|
38
40
|
onHydrate: (fn: (state: UserStore) => void) => () => void;
|
|
39
41
|
onFinishHydration: (fn: (state: UserStore) => void) => () => void;
|
|
40
|
-
getOptions: () => Partial<import("zustand/middleware").PersistOptions<UserStore,
|
|
42
|
+
getOptions: () => Partial<import("zustand/middleware").PersistOptions<UserStore, {
|
|
43
|
+
username: string | null;
|
|
44
|
+
}, unknown>>;
|
|
41
45
|
};
|
|
42
46
|
}>;
|
|
43
47
|
export type { UserStore, UserStoreActions, UserStoreState };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"userStore.d.ts","sourceRoot":"","sources":["../../src/stores/userStore.ts"],"names":[],"mappings":"AAOA;;GAEG;AACH,UAAU,cAAc;IACtB,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CAClC;AAED;;GAEG;AACH,UAAU,gBAAgB;IACxB,QAAQ,CAAC,WAAW,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IACjD,QAAQ,CAAC,aAAa,EAAE,MAAM,IAAI,CAAC;CACpC;AAED;;GAEG;AACH,KAAK,SAAS,GAAG,cAAc,GAAG,gBAAgB,CAAC;AAEnD;;;GAGG;AACH,eAAO,MAAM,YAAY
|
|
1
|
+
{"version":3,"file":"userStore.d.ts","sourceRoot":"","sources":["../../src/stores/userStore.ts"],"names":[],"mappings":"AAOA;;GAEG;AACH,UAAU,cAAc;IACtB,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CAClC;AAED;;GAEG;AACH,UAAU,gBAAgB;IACxB,QAAQ,CAAC,WAAW,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IACjD,QAAQ,CAAC,aAAa,EAAE,MAAM,IAAI,CAAC;CACpC;AAED;;GAEG;AACH,KAAK,SAAS,GAAG,cAAc,GAAG,gBAAgB,CAAC;AAEnD;;;GAGG;AACH,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;EA2CxB,CAAC;AAEF,YAAY,EAAE,SAAS,EAAE,gBAAgB,EAAE,cAAc,EAAE,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TebexMockProvider.d.ts","sourceRoot":"","sources":["../../src/testing/TebexMockProvider.tsx"],"names":[],"mappings":"AAGA,OAAO,EAA4C,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAEjF,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAMlD,OAAO,EAOL,KAAK,cAAc,EAGpB,MAAM,YAAY,CAAC;AAEpB;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,QAAQ,EAAE,SAAS,CAAC;IAE7B;;OAEG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,cAAc,GAAG,SAAS,CAAC;IAE/C;;;OAGG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IAE9C;;;;;OAKG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAE1C;;;OAGG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAEtC;;OAEG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;CAC9D;AA4ID;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AACH,wBAAgB,iBAAiB,CAAC,EAChC,QAAQ,EACR,QAAQ,EAAE,cAAc,EACxB,QAAuB,EACvB,UAAiB,EACjB,OAAiC,EACjC,OAAO,GACR,EAAE,sBAAsB,GAAG,SAAS,
|
|
1
|
+
{"version":3,"file":"TebexMockProvider.d.ts","sourceRoot":"","sources":["../../src/testing/TebexMockProvider.tsx"],"names":[],"mappings":"AAGA,OAAO,EAA4C,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAEjF,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAMlD,OAAO,EAOL,KAAK,cAAc,EAGpB,MAAM,YAAY,CAAC;AAEpB;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,QAAQ,EAAE,SAAS,CAAC;IAE7B;;OAEG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,cAAc,GAAG,SAAS,CAAC;IAE/C;;;OAGG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IAE9C;;;;;OAKG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAE1C;;;OAGG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAEtC;;OAEG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;CAC9D;AA4ID;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AACH,wBAAgB,iBAAiB,CAAC,EAChC,QAAQ,EACR,QAAQ,EAAE,cAAc,EACxB,QAAuB,EACvB,UAAiB,EACjB,OAAiC,EACjC,OAAO,GACR,EAAE,sBAAsB,GAAG,SAAS,CA0DpC;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,IAAI,OAAO,CAG3C"}
|
package/dist/testing/index.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
'use strict';var reactQuery=require('@tanstack/react-query'),react=require('react'),zustand=require('zustand'),middleware=require('zustand/middleware'),jsxRuntime=require('react/jsx-runtime');var
|
|
3
|
-
exports.TebexMockProvider=
|
|
2
|
+
'use strict';var reactQuery=require('@tanstack/react-query'),react=require('react'),zustand=require('zustand'),middleware=require('zustand/middleware'),jsxRuntime=require('react/jsx-runtime');var b=react.createContext(null);var o={all:["tebex"],categories:()=>[...o.all,"categories"],categoriesList:e=>[...o.categories(),"list",{includePackages:e}],category:e=>[...o.categories(),"detail",e],packages:()=>[...o.all,"packages"],packagesList:e=>[...o.packages(),"list",{categoryId:e}],package:e=>[...o.packages(),"detail",e],baskets:()=>[...o.all,"baskets"],basket:e=>[...o.baskets(),e],webstore:()=>[...o.all,"webstore"]};var p=zustand.create()(middleware.subscribeWithSelector(middleware.persist(e=>({basketIdent:null,setBasketIdent:t=>{e({basketIdent:t});},clearBasketIdent:()=>{e({basketIdent:null});}}),{name:"tebex-basket-store",skipHydration:true,version:1,partialize:e=>({basketIdent:e.basketIdent}),migrate:e=>{if(typeof e=="object"&&e!==null&&"basketIdent"in e){let t=e;return {basketIdent:typeof t.basketIdent=="string"?t.basketIdent:null}}return {basketIdent:null}},onRehydrateStorage:()=>(e,t)=>{t!==void 0&&console.warn("[tebex] Failed to rehydrate basket store:",t);}})));var m=zustand.create()(middleware.subscribeWithSelector(middleware.persist(e=>({username:null,setUsername:t=>{e({username:t});},clearUsername:()=>{e({username:null}),p.getState().clearBasketIdent();}}),{name:"tebex-user-store",skipHydration:true,version:1,partialize:e=>({username:e.username}),migrate:e=>{if(typeof e=="object"&&e!==null&&"username"in e){let t=e;return {username:typeof t.username=="string"?t.username:null}}return {username:null}},onRehydrateStorage:()=>(e,t)=>{t!==void 0&&console.warn("[tebex] Failed to rehydrate user store:",t);}})));var g={id:1,name:"Test Store",description:"A test Tebex store for development",currency:"EUR",domain:"test.tebex.io",logo:null},s=[{id:101,name:"VIP Gold",description:"Gold VIP membership with exclusive perks",type:"single",disable_gifting:false,disable_quantity:false,expiration_date:null,base_price:9.99,sales_tax:0,total_price:9.99,currency:"EUR",image:null,category:{id:1,name:"VIP Ranks"},discount:0,created_at:"2024-01-01T00:00:00Z",updated_at:"2024-01-01T00:00:00Z",order:1},{id:102,name:"VIP Diamond",description:"Diamond VIP membership with all perks",type:"single",disable_gifting:false,disable_quantity:false,expiration_date:null,base_price:19.99,sales_tax:0,total_price:19.99,currency:"EUR",image:null,category:{id:1,name:"VIP Ranks"},discount:0,created_at:"2024-01-01T00:00:00Z",updated_at:"2024-01-01T00:00:00Z",order:2},{id:201,name:"Pet Pack",description:"Adorable pet companions",type:"single",disable_gifting:false,disable_quantity:false,expiration_date:null,base_price:4.99,sales_tax:0,total_price:4.99,currency:"EUR",image:null,category:{id:2,name:"Cosmetics"},discount:0,created_at:"2024-01-01T00:00:00Z",updated_at:"2024-01-01T00:00:00Z",order:1},{id:202,name:"Trail Effects",description:"Particle trail effects",type:"single",disable_gifting:false,disable_quantity:false,expiration_date:null,base_price:2.99,sales_tax:0,total_price:2.99,currency:"EUR",image:null,category:{id:2,name:"Cosmetics"},discount:0,created_at:"2024-01-01T00:00:00Z",updated_at:"2024-01-01T00:00:00Z",order:2},{id:301,name:"1000 Coins",description:"In-game currency pack",type:"single",disable_gifting:false,disable_quantity:false,expiration_date:null,base_price:1.99,sales_tax:0,total_price:1.99,currency:"EUR",image:null,category:{id:3,name:"Currency"},discount:0,created_at:"2024-01-01T00:00:00Z",updated_at:"2024-01-01T00:00:00Z",order:1}],y=[{id:1,name:"VIP Ranks",description:"Exclusive VIP memberships",parent:null,order:1,display_type:"grid",slug:"vip-ranks",packages:s.filter(e=>e.category.id===1)},{id:2,name:"Cosmetics",description:"Cosmetic items and effects",parent:null,order:2,display_type:"grid",slug:"cosmetics",packages:s.filter(e=>e.category.id===2)},{id:3,name:"Currency",description:"In-game currency packs",parent:null,order:3,display_type:"grid",slug:"currency",packages:s.filter(e=>e.category.id===3)}],d={ident:"mock-basket-001",complete:false,id:1,country:"US",ip:"127.0.0.1",username_id:null,username:null,cancel_url:"https://example.com/cancel",complete_url:"https://example.com/complete",complete_auto_redirect:false,base_price:0,sales_tax:0,total_price:0,email:"",currency:"EUR",packages:[],coupons:[],giftcards:[],creator_code:"",links:{checkout:"https://checkout.tebex.io/mock"},custom:{}};function M(e,t=1,r=null){return {id:e.id,name:e.name,description:e.description,image:e.image,in_basket:{quantity:t,price:e.base_price*t,gift_username_id:null,gift_username:r}}}function l(e,t){let r=e.map(n=>M(n.package,n.quantity??1,n.giftUsername??null)),a=r.reduce((n,i)=>n+i.in_basket.price,0);return {...d,packages:r,total_price:a,base_price:a,...t}}function f(e){return {code:e}}function x(e){return {card_number:e}}var V={webstore:g,categories:y,packages:s,emptyBasket:d,basketWithOneItem:l([{package:s[0],quantity:1}]),basketWithMultipleItems:l([{package:s[0],quantity:1},{package:s[2],quantity:2}]),basketWithCoupon:{...l([{package:s[0],quantity:1}]),coupons:[f("SAVE10")]},basketWithGiftCard:{...l([{package:s[0],quantity:1}]),giftcards:[x("GIFT-1234-5678")]},basketWithCreatorCode:{...l([{package:s[0],quantity:1}]),creator_code:"STREAMER123"},helpers:{createBasketPackage:M,createMockBasket:l,createMockCoupon:f,createMockGiftCard:x},getPackageById:e=>s.find(t=>t.id===e),getCategoryById:e=>y.find(t=>t.id===e)};function q(){return new reactQuery.QueryClient({defaultOptions:{queries:{staleTime:1/0,gcTime:1/0,retry:false,refetchOnMount:false,refetchOnWindowFocus:false,refetchOnReconnect:false},mutations:{retry:false}}})}function O(e,t){let r=e.replace(/\/$/,"");return {publicKey:"mock-public-key",baseUrl:r,completeUrl:`${r}/shop/complete`,cancelUrl:`${r}/shop/cancel`,onError:t}}function F(e,t){e.setQueryData(o.webstore(),{id:t.webstore.id,name:t.webstore.name,description:t.webstore.description,currency:t.webstore.currency,domain:t.webstore.domain,logo:t.webstore.logo}),e.setQueryData(o.categoriesList(true),t.categories),e.setQueryData(o.categoriesList(false),t.categories.map(a=>({...a,packages:[]})));for(let a of t.categories)e.setQueryData(o.category(a.id),a);e.setQueryData(o.packagesList(),t.packages);let r=new Map;for(let a of t.packages){let n=a.category.id,i=r.get(n)??[];r.set(n,[...i,a]);}for(let[a,n]of r)e.setQueryData(o.packagesList(a),n);for(let a of t.packages)e.setQueryData(o.package(a.id),a);t.basket!==null&&t.basketIdent!==null&&e.setQueryData(o.basket(t.basketIdent),t.basket);}function H({username:e,basketIdent:t}){let r=m(c=>c.setUsername),a=m(c=>c.clearUsername),n=p(c=>c.setBasketIdent),i=p(c=>c.clearBasketIdent);return react.useEffect(()=>{e!==null?r(e):a();},[e,r,a]),react.useEffect(()=>{t!==null?n(t):i();},[t,n,i]),null}function L({children:e,mockData:t,username:r="TestPlayer",withBasket:a=true,baseUrl:n="https://mock.tebex.io",onError:i}){let c=react.useMemo(()=>{let S={...g,...t?.webstore},v=t?.categories??y,U=t?.packages??s,k=null,T=null;return a&&(k=t?.basket?{...d,...t.basket}:d,T=k.ident,r!==null&&(k={...k,username:r})),{webstore:S,categories:v,packages:U,basket:k,basketIdent:T}},[t,a,r]),[u]=react.useState(()=>q()),P=react.useMemo(()=>O(n,i),[n,i]);react.useEffect(()=>{F(u,c);},[u,c]);let I=react.useMemo(()=>({config:P,queryClient:u,isHydrated:true}),[P,u]);return jsxRuntime.jsx(b.Provider,{value:I,children:jsxRuntime.jsxs(reactQuery.QueryClientProvider,{client:u,children:[jsxRuntime.jsx(H,{username:r,basketIdent:c.basketIdent}),e]})})}function N(){let e=react.useContext(b);return e!==null&&e.config.publicKey==="mock-public-key"}
|
|
3
|
+
exports.TebexMockProvider=L;exports.createBasketPackage=M;exports.createMockBasket=l;exports.createMockCoupon=f;exports.createMockGiftCard=x;exports.defaultMockBasket=d;exports.defaultMockCategories=y;exports.defaultMockPackages=s;exports.defaultMockWebstore=g;exports.mockData=V;exports.useIsMockProvider=N;//# sourceMappingURL=index.cjs.map
|
|
4
4
|
//# sourceMappingURL=index.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/provider/context.ts","../../src/queries/keys.ts","../../src/stores/basketStore.ts","../../src/stores/userStore.ts","../../src/testing/mockData.ts","../../src/testing/TebexMockProvider.tsx"],"names":["TebexContext","createContext","tebexKeys","includePackages","id","categoryId","ident","useBasketStore","create","subscribeWithSelector","persist","set","state","persistedState","_state","error","useUserStore","username","defaultMockWebstore","defaultMockPackages","defaultMockCategories","p","defaultMockBasket","createBasketPackage","pkg","quantity","giftUsername","createMockBasket","items","overrides","packages","item","totalPrice","sum","createMockCoupon","code","createMockGiftCard","cardNumber","mockData","c","createMockQueryClient","QueryClient","resolveMockConfig","baseUrl","onError","cleanBaseUrl","populateMockData","queryClient","config","cat","category","packagesByCategory","existing","MockStoreSync","basketIdent","setUsername","clearUsername","setBasketIdent","clearBasketIdent","useEffect","TebexMockProvider","children","mockDataConfig","withBasket","resolvedMockData","useMemo","webstore","categories","basket","useState","resolvedConfig","contextValue","jsx","jsxs","QueryClientProvider","useIsMockProvider","context","useContext"],"mappings":"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","file":"index.cjs","sourcesContent":["'use client';\n\nimport type { QueryClient } from '@tanstack/react-query';\nimport { createContext, useContext } from 'react';\n\nimport { TebexError } from '../errors/TebexError';\nimport { TebexErrorCode } from '../errors/codes';\nimport type { ResolvedTebexConfig } from '../types/config';\n\n/**\n * Context value provided by TebexProvider.\n */\nexport interface TebexContextValue {\n readonly config: ResolvedTebexConfig;\n readonly queryClient: QueryClient;\n}\n\n/**\n * Tebex context for sharing configuration and QueryClient.\n * Used by both TebexProvider and TebexMockProvider.\n */\nexport const TebexContext = createContext<TebexContextValue | null>(null);\n\n/**\n * Hook to access the Tebex context.\n * Must be used within a TebexProvider or TebexMockProvider.\n *\n * @throws TebexError if used outside of a provider\n */\nexport function useTebexContext(): TebexContextValue {\n const context = useContext(TebexContext);\n\n if (context === null) {\n throw new TebexError(\n TebexErrorCode.PROVIDER_NOT_FOUND,\n 'useTebexContext must be used within TebexProvider or TebexMockProvider',\n );\n }\n\n return context;\n}\n\n/**\n * Hook to access just the Tebex configuration.\n * Useful when you don't need the QueryClient.\n */\nexport function useTebexConfig(): ResolvedTebexConfig {\n const { config } = useTebexContext();\n return config;\n}\n","/**\n * Query keys factory for TanStack Query.\n * Follows the recommended pattern for granular cache invalidation.\n *\n * @see https://tkdodo.eu/blog/effective-react-query-keys\n */\nexport const tebexKeys = {\n /** Root key for all Tebex queries */\n all: ['tebex'] as const,\n\n // ============ Categories ============\n\n /** All category-related queries */\n categories: () => [...tebexKeys.all, 'categories'] as const,\n\n /** Categories list with include packages option */\n categoriesList: (includePackages: boolean) =>\n [...tebexKeys.categories(), 'list', { includePackages }] as const,\n\n /** Single category by ID */\n category: (id: number) => [...tebexKeys.categories(), 'detail', id] as const,\n\n // ============ Packages ============\n\n /** All package-related queries */\n packages: () => [...tebexKeys.all, 'packages'] as const,\n\n /** Packages list, optionally filtered by category */\n packagesList: (categoryId?: number) => [...tebexKeys.packages(), 'list', { categoryId }] as const,\n\n /** Single package by ID */\n package: (id: number) => [...tebexKeys.packages(), 'detail', id] as const,\n\n // ============ Basket ============\n\n /** All basket-related queries */\n baskets: () => [...tebexKeys.all, 'baskets'] as const,\n\n /** Specific basket by ident */\n basket: (ident: string | null) => [...tebexKeys.baskets(), ident] as const,\n\n // ============ Webstore ============\n\n /** Webstore info query */\n webstore: () => [...tebexKeys.all, 'webstore'] as const,\n} as const;\n\n/**\n * Type helper for extracting query key types.\n */\ntype KeyFunctions = Omit<typeof tebexKeys, 'all'>;\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype ExtractReturnType<T> = T extends (...args: any[]) => infer R ? R : never;\nexport type TebexQueryKey =\n | (typeof tebexKeys)['all']\n | ExtractReturnType<KeyFunctions[keyof KeyFunctions]>;\n","'use client';\n\nimport { create } from 'zustand';\nimport { persist, subscribeWithSelector } from 'zustand/middleware';\n\n/**\n * Basket store state interface.\n */\ninterface BasketStoreState {\n readonly basketIdent: string | null;\n}\n\n/**\n * Basket store actions interface.\n */\ninterface BasketStoreActions {\n readonly setBasketIdent: (ident: string) => void;\n readonly clearBasketIdent: () => void;\n}\n\n/**\n * Complete basket store type.\n */\ntype BasketStore = BasketStoreState & BasketStoreActions;\n\n/**\n * Zustand store for basket ident persistence.\n * Uses localStorage to persist the basket ident across sessions.\n */\nexport const useBasketStore = create<BasketStore>()(\n subscribeWithSelector(\n persist(\n set => ({\n basketIdent: null,\n setBasketIdent: (ident: string) => {\n set({ basketIdent: ident });\n },\n clearBasketIdent: () => {\n set({ basketIdent: null });\n },\n }),\n {\n name: 'tebex-basket-store',\n // Skip hydration — rehydrated manually in TebexProvider\n skipHydration: true,\n version: 1,\n partialize: (state: BasketStore) => ({ basketIdent: state.basketIdent }),\n migrate: (persistedState: unknown) => {\n return persistedState as Pick<BasketStoreState, 'basketIdent'>;\n },\n onRehydrateStorage: () => {\n return (_state: unknown, error?: unknown) => {\n if (error !== undefined) {\n // eslint-disable-next-line no-console\n console.warn('[tebex] Failed to rehydrate basket store:', error);\n }\n };\n },\n },\n ),\n ),\n);\n\nexport type { BasketStore, BasketStoreActions, BasketStoreState };\n","'use client';\n\nimport { create } from 'zustand';\nimport { persist, subscribeWithSelector } from 'zustand/middleware';\n\nimport { useBasketStore } from './basketStore';\n\n/**\n * User store state interface.\n */\ninterface UserStoreState {\n readonly username: string | null;\n}\n\n/**\n * User store actions interface.\n */\ninterface UserStoreActions {\n readonly setUsername: (username: string) => void;\n readonly clearUsername: () => void;\n}\n\n/**\n * Complete user store type.\n */\ntype UserStore = UserStoreState & UserStoreActions;\n\n/**\n * Zustand store for user data persistence.\n * Uses localStorage to persist the username (Minecraft username) across sessions.\n */\nexport const useUserStore = create<UserStore>()(\n subscribeWithSelector(\n persist(\n set => ({\n username: null,\n setUsername: (username: string) => {\n set({ username });\n },\n clearUsername: () => {\n set({ username: null });\n useBasketStore.getState().clearBasketIdent();\n },\n }),\n {\n name: 'tebex-user-store',\n // Skip hydration — rehydrated manually in TebexProvider\n skipHydration: true,\n version: 1,\n partialize: (state: UserStore) => ({ username: state.username }),\n migrate: (persistedState: unknown) => {\n return persistedState as Pick<UserStoreState, 'username'>;\n },\n onRehydrateStorage: () => {\n return (_state: unknown, error?: unknown) => {\n if (error !== undefined) {\n // eslint-disable-next-line no-console\n console.warn('[tebex] Failed to rehydrate user store:', error);\n }\n };\n },\n },\n ),\n ),\n);\n\nexport type { UserStore, UserStoreActions, UserStoreState };\n","import type { Basket, BasketPackage, Category, Code, GiftCardCode, Package } from 'tebex_headless';\n\nimport type { WebstoreData } from '../types/hooks';\n\n/**\n * Mock webstore data for testing.\n */\nexport interface MockWebstoreData extends WebstoreData {\n readonly id: number;\n readonly name: string;\n readonly description: string;\n readonly currency: string;\n readonly domain: string;\n readonly logo: string | null;\n}\n\n/**\n * Mock package data for testing.\n * Extends the base Package type with required fields.\n */\nexport type MockPackage = Package;\n\n/**\n * Mock category data for testing.\n */\nexport type MockCategory = Category;\n\n/**\n * Mock basket data for testing.\n */\nexport type MockBasket = Basket;\n\n/**\n * Configuration for mock data.\n */\nexport interface MockDataConfig {\n readonly webstore?: Partial<MockWebstoreData> | undefined;\n readonly categories?: MockCategory[] | undefined;\n readonly packages?: MockPackage[] | undefined;\n readonly basket?: Partial<MockBasket> | undefined;\n readonly username?: string | null | undefined;\n}\n\n/**\n * Default mock webstore data.\n */\nexport const defaultMockWebstore: MockWebstoreData = {\n id: 1,\n name: 'Test Store',\n description: 'A test Tebex store for development',\n currency: 'EUR',\n domain: 'test.tebex.io',\n logo: null,\n};\n\n/**\n * Default mock packages organized by category.\n */\nexport const defaultMockPackages: MockPackage[] = [\n {\n id: 101,\n name: 'VIP Gold',\n description: 'Gold VIP membership with exclusive perks',\n type: 'single',\n disable_gifting: false,\n disable_quantity: false,\n expiration_date: null,\n base_price: 9.99,\n sales_tax: 0,\n total_price: 9.99,\n currency: 'EUR',\n image: null,\n category: { id: 1, name: 'VIP Ranks' },\n discount: 0,\n created_at: '2024-01-01T00:00:00Z',\n updated_at: '2024-01-01T00:00:00Z',\n order: 1,\n },\n {\n id: 102,\n name: 'VIP Diamond',\n description: 'Diamond VIP membership with all perks',\n type: 'single',\n disable_gifting: false,\n disable_quantity: false,\n expiration_date: null,\n base_price: 19.99,\n sales_tax: 0,\n total_price: 19.99,\n currency: 'EUR',\n image: null,\n category: { id: 1, name: 'VIP Ranks' },\n discount: 0,\n created_at: '2024-01-01T00:00:00Z',\n updated_at: '2024-01-01T00:00:00Z',\n order: 2,\n },\n {\n id: 201,\n name: 'Pet Pack',\n description: 'Adorable pet companions',\n type: 'single',\n disable_gifting: false,\n disable_quantity: false,\n expiration_date: null,\n base_price: 4.99,\n sales_tax: 0,\n total_price: 4.99,\n currency: 'EUR',\n image: null,\n category: { id: 2, name: 'Cosmetics' },\n discount: 0,\n created_at: '2024-01-01T00:00:00Z',\n updated_at: '2024-01-01T00:00:00Z',\n order: 1,\n },\n {\n id: 202,\n name: 'Trail Effects',\n description: 'Particle trail effects',\n type: 'single',\n disable_gifting: false,\n disable_quantity: false,\n expiration_date: null,\n base_price: 2.99,\n sales_tax: 0,\n total_price: 2.99,\n currency: 'EUR',\n image: null,\n category: { id: 2, name: 'Cosmetics' },\n discount: 0,\n created_at: '2024-01-01T00:00:00Z',\n updated_at: '2024-01-01T00:00:00Z',\n order: 2,\n },\n {\n id: 301,\n name: '1000 Coins',\n description: 'In-game currency pack',\n type: 'single',\n disable_gifting: false,\n disable_quantity: false,\n expiration_date: null,\n base_price: 1.99,\n sales_tax: 0,\n total_price: 1.99,\n currency: 'EUR',\n image: null,\n category: { id: 3, name: 'Currency' },\n discount: 0,\n created_at: '2024-01-01T00:00:00Z',\n updated_at: '2024-01-01T00:00:00Z',\n order: 1,\n },\n];\n\n/**\n * Default mock categories with packages.\n */\nexport const defaultMockCategories: MockCategory[] = [\n {\n id: 1,\n name: 'VIP Ranks',\n description: 'Exclusive VIP memberships',\n parent: null,\n order: 1,\n display_type: 'grid',\n slug: 'vip-ranks',\n packages: defaultMockPackages.filter(p => p.category.id === 1),\n },\n {\n id: 2,\n name: 'Cosmetics',\n description: 'Cosmetic items and effects',\n parent: null,\n order: 2,\n display_type: 'grid',\n slug: 'cosmetics',\n packages: defaultMockPackages.filter(p => p.category.id === 2),\n },\n {\n id: 3,\n name: 'Currency',\n description: 'In-game currency packs',\n parent: null,\n order: 3,\n display_type: 'grid',\n slug: 'currency',\n packages: defaultMockPackages.filter(p => p.category.id === 3),\n },\n];\n\n/**\n * Default empty basket.\n */\nexport const defaultMockBasket: MockBasket = {\n ident: 'mock-basket-001',\n complete: false,\n id: 1,\n country: 'US',\n ip: '127.0.0.1',\n username_id: null,\n username: null,\n cancel_url: 'https://example.com/cancel',\n complete_url: 'https://example.com/complete',\n complete_auto_redirect: false,\n base_price: 0,\n sales_tax: 0,\n total_price: 0,\n email: '',\n currency: 'EUR',\n packages: [],\n coupons: [],\n giftcards: [],\n creator_code: '',\n links: {\n checkout: 'https://checkout.tebex.io/mock',\n },\n custom: {},\n};\n\n/**\n * Create a basket package from a mock package.\n */\nexport function createBasketPackage(\n pkg: MockPackage,\n quantity = 1,\n giftUsername: string | null = null,\n): BasketPackage {\n return {\n id: pkg.id,\n name: pkg.name,\n description: pkg.description,\n image: pkg.image,\n in_basket: {\n quantity,\n price: pkg.base_price * quantity,\n gift_username_id: null,\n gift_username: giftUsername,\n },\n };\n}\n\n/**\n * Create a mock basket with items.\n */\nexport function createMockBasket(\n items: { package: MockPackage; quantity?: number; giftUsername?: string | null }[],\n overrides?: Partial<MockBasket>,\n): MockBasket {\n const packages = items.map(item =>\n createBasketPackage(item.package, item.quantity ?? 1, item.giftUsername ?? null),\n );\n\n const totalPrice = packages.reduce((sum, pkg) => sum + pkg.in_basket.price, 0);\n\n return {\n ...defaultMockBasket,\n packages,\n total_price: totalPrice,\n base_price: totalPrice,\n ...overrides,\n };\n}\n\n/**\n * Create a mock coupon.\n */\nexport function createMockCoupon(code: string): Code {\n return {\n code,\n };\n}\n\n/**\n * Create a mock gift card.\n */\nexport function createMockGiftCard(cardNumber: string): GiftCardCode {\n return {\n card_number: cardNumber,\n };\n}\n\n/**\n * Pre-built mock data for common testing scenarios.\n */\nexport const mockData = {\n /** Default webstore */\n webstore: defaultMockWebstore,\n\n /** All categories with packages */\n categories: defaultMockCategories,\n\n /** All packages flat list */\n packages: defaultMockPackages,\n\n /** Empty basket */\n emptyBasket: defaultMockBasket,\n\n /** Basket with one VIP Gold item */\n basketWithOneItem: createMockBasket([{ package: defaultMockPackages[0]!, quantity: 1 }]),\n\n /** Basket with multiple items */\n basketWithMultipleItems: createMockBasket([\n { package: defaultMockPackages[0]!, quantity: 1 },\n { package: defaultMockPackages[2]!, quantity: 2 },\n ]),\n\n /** Basket with coupon applied */\n basketWithCoupon: {\n ...createMockBasket([{ package: defaultMockPackages[0]!, quantity: 1 }]),\n coupons: [createMockCoupon('SAVE10')],\n },\n\n /** Basket with gift card applied */\n basketWithGiftCard: {\n ...createMockBasket([{ package: defaultMockPackages[0]!, quantity: 1 }]),\n giftcards: [createMockGiftCard('GIFT-1234-5678')],\n },\n\n /** Basket with creator code */\n basketWithCreatorCode: {\n ...createMockBasket([{ package: defaultMockPackages[0]!, quantity: 1 }]),\n creator_code: 'STREAMER123',\n },\n\n /** Helper functions */\n helpers: {\n createBasketPackage,\n createMockBasket,\n createMockCoupon,\n createMockGiftCard,\n },\n\n /** Get package by ID */\n getPackageById: (id: number): MockPackage | undefined => {\n return defaultMockPackages.find(p => p.id === id);\n },\n\n /** Get category by ID */\n getCategoryById: (id: number): MockCategory | undefined => {\n return defaultMockCategories.find(c => c.id === id);\n },\n} as const;\n\nexport type { Basket, BasketPackage, Category, Code, GiftCardCode, Package };\n","'use client';\n\nimport { QueryClient, QueryClientProvider } from '@tanstack/react-query';\nimport { useContext, useEffect, useMemo, useState, type ReactNode } from 'react';\n\nimport { TebexError } from '../errors/TebexError';\nimport { TebexContext, type TebexContextValue } from '../provider/context';\nimport { tebexKeys } from '../queries/keys';\nimport { useBasketStore } from '../stores/basketStore';\nimport { useUserStore } from '../stores/userStore';\nimport type { ResolvedTebexConfig } from '../types/config';\nimport {\n defaultMockBasket,\n defaultMockCategories,\n defaultMockPackages,\n defaultMockWebstore,\n type MockBasket,\n type MockCategory,\n type MockDataConfig,\n type MockPackage,\n type MockWebstoreData,\n} from './mockData';\n\n/**\n * Props for TebexMockProvider component.\n */\nexport interface TebexMockProviderProps {\n readonly children: ReactNode;\n\n /**\n * Mock data to use. If not provided, defaults will be used.\n */\n readonly mockData?: MockDataConfig | undefined;\n\n /**\n * Mock username to set in the user store.\n * @default 'TestPlayer'\n */\n readonly username?: string | null | undefined;\n\n /**\n * Whether to initialize a basket.\n * If true and mockData.basket is provided, that basket will be used.\n * If true and no basket is provided, an empty basket will be created.\n * @default true\n */\n readonly withBasket?: boolean | undefined;\n\n /**\n * Base URL for the mock store.\n * @default 'https://mock.tebex.io'\n */\n readonly baseUrl?: string | undefined;\n\n /**\n * Callback when an error occurs.\n */\n readonly onError?: ((error: TebexError) => void) | undefined;\n}\n\n/**\n * Create a QueryClient configured for mocking.\n * - Infinite staleTime so queries never auto-refetch\n * - No retries\n * - Instant garbage collection time for testing\n */\nfunction createMockQueryClient(): QueryClient {\n return new QueryClient({\n defaultOptions: {\n queries: {\n staleTime: Infinity,\n gcTime: Infinity,\n retry: false,\n refetchOnMount: false,\n refetchOnWindowFocus: false,\n refetchOnReconnect: false,\n },\n mutations: {\n retry: false,\n },\n },\n });\n}\n\n/**\n * Resolve mock config with defaults.\n */\nfunction resolveMockConfig(\n baseUrl: string,\n onError?: (error: TebexError) => void,\n): ResolvedTebexConfig {\n const cleanBaseUrl = baseUrl.replace(/\\/$/, '');\n\n return {\n publicKey: 'mock-public-key',\n baseUrl: cleanBaseUrl,\n completeUrl: `${cleanBaseUrl}/shop/complete`,\n cancelUrl: `${cleanBaseUrl}/shop/cancel`,\n onError,\n };\n}\n\n/**\n * Populate the QueryClient with mock data.\n */\nfunction populateMockData(\n queryClient: QueryClient,\n config: {\n webstore: MockWebstoreData;\n categories: MockCategory[];\n packages: MockPackage[];\n basket: MockBasket | null;\n basketIdent: string | null;\n },\n): void {\n // Webstore data\n queryClient.setQueryData(tebexKeys.webstore(), {\n id: config.webstore.id,\n name: config.webstore.name,\n description: config.webstore.description,\n currency: config.webstore.currency,\n domain: config.webstore.domain,\n logo: config.webstore.logo,\n });\n\n // Categories with packages\n queryClient.setQueryData(tebexKeys.categoriesList(true), config.categories);\n\n // Categories without packages\n queryClient.setQueryData(\n tebexKeys.categoriesList(false),\n config.categories.map(cat => ({ ...cat, packages: [] })),\n );\n\n // Individual categories\n for (const category of config.categories) {\n queryClient.setQueryData(tebexKeys.category(category.id), category);\n }\n\n // All packages\n queryClient.setQueryData(tebexKeys.packagesList(), config.packages);\n\n // Packages by category\n const packagesByCategory = new Map<number, MockPackage[]>();\n for (const pkg of config.packages) {\n const categoryId = pkg.category.id;\n const existing = packagesByCategory.get(categoryId) ?? [];\n packagesByCategory.set(categoryId, [...existing, pkg]);\n }\n for (const [categoryId, packages] of packagesByCategory) {\n queryClient.setQueryData(tebexKeys.packagesList(categoryId), packages);\n }\n\n // Individual packages\n for (const pkg of config.packages) {\n queryClient.setQueryData(tebexKeys.package(pkg.id), pkg);\n }\n\n // Basket (if provided)\n if (config.basket !== null && config.basketIdent !== null) {\n queryClient.setQueryData(tebexKeys.basket(config.basketIdent), config.basket);\n }\n}\n\n/**\n * Component to sync mock data with stores.\n */\nfunction MockStoreSync({\n username,\n basketIdent,\n}: {\n username: string | null;\n basketIdent: string | null;\n}): null {\n const setUsername = useUserStore(state => state.setUsername);\n const clearUsername = useUserStore(state => state.clearUsername);\n const setBasketIdent = useBasketStore(state => state.setBasketIdent);\n const clearBasketIdent = useBasketStore(state => state.clearBasketIdent);\n\n useEffect(() => {\n if (username !== null) {\n setUsername(username);\n } else {\n clearUsername();\n }\n }, [username, setUsername, clearUsername]);\n\n useEffect(() => {\n if (basketIdent !== null) {\n setBasketIdent(basketIdent);\n } else {\n clearBasketIdent();\n }\n }, [basketIdent, setBasketIdent, clearBasketIdent]);\n\n return null;\n}\n\n/**\n * TebexMockProvider - A mock provider for testing and Storybook.\n *\n * This provider pre-populates TanStack Query with mock data, allowing\n * you to render components that use Tebex hooks without making real API calls.\n *\n * **Features:**\n * - Pre-populated categories, packages, and webstore data\n * - Optional basket state\n * - No network requests (queries have infinite staleTime)\n * - Same context interface as TebexProvider\n *\n * **Limitations:**\n * - Mutations (addPackage, removePackage, etc.) won't persist changes\n * - For full mutation support, use MSW with the provided handlers\n *\n * @example Basic usage\n * ```tsx\n * import { TebexMockProvider, mockData } from '@neosianexus/super-tebex/testing';\n *\n * <TebexMockProvider>\n * <ShopPage />\n * </TebexMockProvider>\n * ```\n *\n * @example Custom mock data\n * ```tsx\n * <TebexMockProvider\n * mockData={{\n * webstore: { name: 'My Custom Store', currency: 'USD' },\n * basket: mockData.basketWithMultipleItems,\n * }}\n * username=\"CustomPlayer\"\n * >\n * <CheckoutPage />\n * </TebexMockProvider>\n * ```\n *\n * @example Without basket (for category/package browsing)\n * ```tsx\n * <TebexMockProvider withBasket={false}>\n * <CatalogPage />\n * </TebexMockProvider>\n * ```\n */\nexport function TebexMockProvider({\n children,\n mockData: mockDataConfig,\n username = 'TestPlayer',\n withBasket = true,\n baseUrl = 'https://mock.tebex.io',\n onError,\n}: TebexMockProviderProps): ReactNode {\n // Resolve mock data with defaults\n const resolvedMockData = useMemo(() => {\n const webstore: MockWebstoreData = {\n ...defaultMockWebstore,\n ...mockDataConfig?.webstore,\n };\n\n const categories = mockDataConfig?.categories ?? defaultMockCategories;\n const packages = mockDataConfig?.packages ?? defaultMockPackages;\n\n let basket: MockBasket | null = null;\n let basketIdent: string | null = null;\n\n if (withBasket) {\n basket = mockDataConfig?.basket\n ? { ...defaultMockBasket, ...mockDataConfig.basket }\n : defaultMockBasket;\n basketIdent = basket.ident;\n\n // Set username on basket if provided\n if (username !== null) {\n basket = { ...basket, username };\n }\n }\n\n return { webstore, categories, packages, basket, basketIdent };\n }, [mockDataConfig, withBasket, username]);\n\n // Create QueryClient once\n const [queryClient] = useState(() => createMockQueryClient());\n\n // Resolve config\n const resolvedConfig = useMemo(() => resolveMockConfig(baseUrl, onError), [baseUrl, onError]);\n\n // Populate mock data on mount and when data changes\n useEffect(() => {\n populateMockData(queryClient, resolvedMockData);\n }, [queryClient, resolvedMockData]);\n\n // Context value\n const contextValue = useMemo<TebexContextValue>(\n () => ({\n config: resolvedConfig,\n queryClient,\n }),\n [resolvedConfig, queryClient],\n );\n\n return (\n <TebexContext.Provider value={contextValue}>\n <QueryClientProvider client={queryClient}>\n <MockStoreSync username={username} basketIdent={resolvedMockData.basketIdent} />\n {children}\n </QueryClientProvider>\n </TebexContext.Provider>\n );\n}\n\n/**\n * Hook to check if we're inside a mock provider.\n * Useful for conditional logic in components.\n *\n * Note: This hook checks for any Tebex provider (real or mock).\n * The mock provider is identified by its configuration.\n */\nexport function useIsMockProvider(): boolean {\n const context = useContext(TebexContext);\n return context !== null && context.config.publicKey === 'mock-public-key';\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../src/provider/context.ts","../../src/queries/keys.ts","../../src/stores/basketStore.ts","../../src/stores/userStore.ts","../../src/testing/mockData.ts","../../src/testing/TebexMockProvider.tsx"],"names":["TebexContext","createContext","tebexKeys","includePackages","id","categoryId","ident","useBasketStore","create","subscribeWithSelector","persist","set","state","persistedState","_state","error","useUserStore","username","defaultMockWebstore","defaultMockPackages","defaultMockCategories","p","defaultMockBasket","createBasketPackage","pkg","quantity","giftUsername","createMockBasket","items","overrides","packages","item","totalPrice","sum","createMockCoupon","code","createMockGiftCard","cardNumber","mockData","c","createMockQueryClient","QueryClient","resolveMockConfig","baseUrl","onError","cleanBaseUrl","populateMockData","queryClient","config","cat","category","packagesByCategory","existing","MockStoreSync","basketIdent","setUsername","clearUsername","setBasketIdent","clearBasketIdent","useEffect","TebexMockProvider","children","mockDataConfig","withBasket","resolvedMockData","useMemo","webstore","categories","basket","useState","resolvedConfig","contextValue","jsx","jsxs","QueryClientProvider","useIsMockProvider","context","useContext"],"mappings":"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","file":"index.cjs","sourcesContent":["'use client';\n\nimport type { QueryClient } from '@tanstack/react-query';\nimport { createContext, useContext } from 'react';\n\nimport { TebexError } from '../errors/TebexError';\nimport { TebexErrorCode } from '../errors/codes';\nimport type { ResolvedTebexConfig } from '../types/config';\n\n/**\n * Context value provided by TebexProvider.\n */\nexport interface TebexContextValue {\n readonly config: ResolvedTebexConfig;\n readonly queryClient: QueryClient;\n readonly isHydrated: boolean;\n}\n\n/**\n * Tebex context for sharing configuration and QueryClient.\n * Used by both TebexProvider and TebexMockProvider.\n */\nexport const TebexContext = createContext<TebexContextValue | null>(null);\n\n/**\n * Hook to access the Tebex context.\n * Must be used within a TebexProvider or TebexMockProvider.\n *\n * @throws TebexError if used outside of a provider\n */\nexport function useTebexContext(): TebexContextValue {\n const context = useContext(TebexContext);\n\n if (context === null) {\n throw new TebexError(\n TebexErrorCode.PROVIDER_NOT_FOUND,\n 'useTebexContext must be used within TebexProvider or TebexMockProvider',\n );\n }\n\n return context;\n}\n\n/**\n * Hook to access just the Tebex configuration.\n * Useful when you don't need the QueryClient.\n */\nexport function useTebexConfig(): ResolvedTebexConfig {\n const { config } = useTebexContext();\n return config;\n}\n\n/**\n * Hook to check if Zustand stores have finished hydrating from localStorage.\n * Useful to prevent actions before persisted state is available.\n */\nexport function useTebexHydrated(): boolean {\n const { isHydrated } = useTebexContext();\n return isHydrated;\n}\n","/**\n * Query keys factory for TanStack Query.\n * Follows the recommended pattern for granular cache invalidation.\n *\n * @see https://tkdodo.eu/blog/effective-react-query-keys\n */\nexport const tebexKeys = {\n /** Root key for all Tebex queries */\n all: ['tebex'] as const,\n\n // ============ Categories ============\n\n /** All category-related queries */\n categories: () => [...tebexKeys.all, 'categories'] as const,\n\n /** Categories list with include packages option */\n categoriesList: (includePackages: boolean) =>\n [...tebexKeys.categories(), 'list', { includePackages }] as const,\n\n /** Single category by ID */\n category: (id: number) => [...tebexKeys.categories(), 'detail', id] as const,\n\n // ============ Packages ============\n\n /** All package-related queries */\n packages: () => [...tebexKeys.all, 'packages'] as const,\n\n /** Packages list, optionally filtered by category */\n packagesList: (categoryId?: number) => [...tebexKeys.packages(), 'list', { categoryId }] as const,\n\n /** Single package by ID */\n package: (id: number) => [...tebexKeys.packages(), 'detail', id] as const,\n\n // ============ Basket ============\n\n /** All basket-related queries */\n baskets: () => [...tebexKeys.all, 'baskets'] as const,\n\n /** Specific basket by ident */\n basket: (ident: string | null) => [...tebexKeys.baskets(), ident] as const,\n\n // ============ Webstore ============\n\n /** Webstore info query */\n webstore: () => [...tebexKeys.all, 'webstore'] as const,\n} as const;\n\n/**\n * Type helper for extracting query key types.\n */\ntype KeyFunctions = Omit<typeof tebexKeys, 'all'>;\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype ExtractReturnType<T> = T extends (...args: any[]) => infer R ? R : never;\nexport type TebexQueryKey =\n | (typeof tebexKeys)['all']\n | ExtractReturnType<KeyFunctions[keyof KeyFunctions]>;\n","'use client';\n\nimport { create } from 'zustand';\nimport { persist, subscribeWithSelector } from 'zustand/middleware';\n\n/**\n * Basket store state interface.\n */\ninterface BasketStoreState {\n readonly basketIdent: string | null;\n}\n\n/**\n * Basket store actions interface.\n */\ninterface BasketStoreActions {\n readonly setBasketIdent: (ident: string) => void;\n readonly clearBasketIdent: () => void;\n}\n\n/**\n * Complete basket store type.\n */\ntype BasketStore = BasketStoreState & BasketStoreActions;\n\n/**\n * Zustand store for basket ident persistence.\n * Uses localStorage to persist the basket ident across sessions.\n */\nexport const useBasketStore = create<BasketStore>()(\n subscribeWithSelector(\n persist(\n set => ({\n basketIdent: null,\n setBasketIdent: (ident: string) => {\n set({ basketIdent: ident });\n },\n clearBasketIdent: () => {\n set({ basketIdent: null });\n },\n }),\n {\n name: 'tebex-basket-store',\n // Skip hydration — rehydrated manually in TebexProvider\n skipHydration: true,\n version: 1,\n partialize: (state: BasketStore) => ({ basketIdent: state.basketIdent }),\n migrate: (persistedState: unknown) => {\n if (\n typeof persistedState === 'object' &&\n persistedState !== null &&\n 'basketIdent' in persistedState\n ) {\n const state = persistedState as Record<string, unknown>;\n return {\n basketIdent: typeof state.basketIdent === 'string' ? state.basketIdent : null,\n };\n }\n return { basketIdent: null };\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 if (\n typeof persistedState === 'object' &&\n persistedState !== null &&\n 'username' in persistedState\n ) {\n const state = persistedState as Record<string, unknown>;\n return {\n username: typeof state.username === 'string' ? state.username : null,\n };\n }\n return { username: null };\n },\n onRehydrateStorage: () => {\n return (_state: unknown, error?: unknown) => {\n if (error !== undefined) {\n // eslint-disable-next-line no-console\n console.warn('[tebex] Failed to rehydrate user store:', error);\n }\n };\n },\n },\n ),\n ),\n);\n\nexport type { UserStore, UserStoreActions, UserStoreState };\n","import type { Basket, BasketPackage, Category, Code, GiftCardCode, Package } from 'tebex_headless';\n\nimport type { WebstoreData } from '../types/hooks';\n\n/**\n * Mock webstore data for testing.\n */\nexport interface MockWebstoreData extends WebstoreData {\n readonly id: number;\n readonly name: string;\n readonly description: string;\n readonly currency: string;\n readonly domain: string;\n readonly logo: string | null;\n}\n\n/**\n * Mock package data for testing.\n * Extends the base Package type with required fields.\n */\nexport type MockPackage = Package;\n\n/**\n * Mock category data for testing.\n */\nexport type MockCategory = Category;\n\n/**\n * Mock basket data for testing.\n */\nexport type MockBasket = Basket;\n\n/**\n * Configuration for mock data.\n */\nexport interface MockDataConfig {\n readonly webstore?: Partial<MockWebstoreData> | undefined;\n readonly categories?: MockCategory[] | undefined;\n readonly packages?: MockPackage[] | undefined;\n readonly basket?: Partial<MockBasket> | undefined;\n readonly username?: string | null | undefined;\n}\n\n/**\n * Default mock webstore data.\n */\nexport const defaultMockWebstore: MockWebstoreData = {\n id: 1,\n name: 'Test Store',\n description: 'A test Tebex store for development',\n currency: 'EUR',\n domain: 'test.tebex.io',\n logo: null,\n};\n\n/**\n * Default mock packages organized by category.\n */\nexport const defaultMockPackages: MockPackage[] = [\n {\n id: 101,\n name: 'VIP Gold',\n description: 'Gold VIP membership with exclusive perks',\n type: 'single',\n disable_gifting: false,\n disable_quantity: false,\n expiration_date: null,\n base_price: 9.99,\n sales_tax: 0,\n total_price: 9.99,\n currency: 'EUR',\n image: null,\n category: { id: 1, name: 'VIP Ranks' },\n discount: 0,\n created_at: '2024-01-01T00:00:00Z',\n updated_at: '2024-01-01T00:00:00Z',\n order: 1,\n },\n {\n id: 102,\n name: 'VIP Diamond',\n description: 'Diamond VIP membership with all perks',\n type: 'single',\n disable_gifting: false,\n disable_quantity: false,\n expiration_date: null,\n base_price: 19.99,\n sales_tax: 0,\n total_price: 19.99,\n currency: 'EUR',\n image: null,\n category: { id: 1, name: 'VIP Ranks' },\n discount: 0,\n created_at: '2024-01-01T00:00:00Z',\n updated_at: '2024-01-01T00:00:00Z',\n order: 2,\n },\n {\n id: 201,\n name: 'Pet Pack',\n description: 'Adorable pet companions',\n type: 'single',\n disable_gifting: false,\n disable_quantity: false,\n expiration_date: null,\n base_price: 4.99,\n sales_tax: 0,\n total_price: 4.99,\n currency: 'EUR',\n image: null,\n category: { id: 2, name: 'Cosmetics' },\n discount: 0,\n created_at: '2024-01-01T00:00:00Z',\n updated_at: '2024-01-01T00:00:00Z',\n order: 1,\n },\n {\n id: 202,\n name: 'Trail Effects',\n description: 'Particle trail effects',\n type: 'single',\n disable_gifting: false,\n disable_quantity: false,\n expiration_date: null,\n base_price: 2.99,\n sales_tax: 0,\n total_price: 2.99,\n currency: 'EUR',\n image: null,\n category: { id: 2, name: 'Cosmetics' },\n discount: 0,\n created_at: '2024-01-01T00:00:00Z',\n updated_at: '2024-01-01T00:00:00Z',\n order: 2,\n },\n {\n id: 301,\n name: '1000 Coins',\n description: 'In-game currency pack',\n type: 'single',\n disable_gifting: false,\n disable_quantity: false,\n expiration_date: null,\n base_price: 1.99,\n sales_tax: 0,\n total_price: 1.99,\n currency: 'EUR',\n image: null,\n category: { id: 3, name: 'Currency' },\n discount: 0,\n created_at: '2024-01-01T00:00:00Z',\n updated_at: '2024-01-01T00:00:00Z',\n order: 1,\n },\n];\n\n/**\n * Default mock categories with packages.\n */\nexport const defaultMockCategories: MockCategory[] = [\n {\n id: 1,\n name: 'VIP Ranks',\n description: 'Exclusive VIP memberships',\n parent: null,\n order: 1,\n display_type: 'grid',\n slug: 'vip-ranks',\n packages: defaultMockPackages.filter(p => p.category.id === 1),\n },\n {\n id: 2,\n name: 'Cosmetics',\n description: 'Cosmetic items and effects',\n parent: null,\n order: 2,\n display_type: 'grid',\n slug: 'cosmetics',\n packages: defaultMockPackages.filter(p => p.category.id === 2),\n },\n {\n id: 3,\n name: 'Currency',\n description: 'In-game currency packs',\n parent: null,\n order: 3,\n display_type: 'grid',\n slug: 'currency',\n packages: defaultMockPackages.filter(p => p.category.id === 3),\n },\n];\n\n/**\n * Default empty basket.\n */\nexport const defaultMockBasket: MockBasket = {\n ident: 'mock-basket-001',\n complete: false,\n id: 1,\n country: 'US',\n ip: '127.0.0.1',\n username_id: null,\n username: null,\n cancel_url: 'https://example.com/cancel',\n complete_url: 'https://example.com/complete',\n complete_auto_redirect: false,\n base_price: 0,\n sales_tax: 0,\n total_price: 0,\n email: '',\n currency: 'EUR',\n packages: [],\n coupons: [],\n giftcards: [],\n creator_code: '',\n links: {\n checkout: 'https://checkout.tebex.io/mock',\n },\n custom: {},\n};\n\n/**\n * Create a basket package from a mock package.\n */\nexport function createBasketPackage(\n pkg: MockPackage,\n quantity = 1,\n giftUsername: string | null = null,\n): BasketPackage {\n return {\n id: pkg.id,\n name: pkg.name,\n description: pkg.description,\n image: pkg.image,\n in_basket: {\n quantity,\n price: pkg.base_price * quantity,\n gift_username_id: null,\n gift_username: giftUsername,\n },\n };\n}\n\n/**\n * Create a mock basket with items.\n */\nexport function createMockBasket(\n items: { package: MockPackage; quantity?: number; giftUsername?: string | null }[],\n overrides?: Partial<MockBasket>,\n): MockBasket {\n const packages = items.map(item =>\n createBasketPackage(item.package, item.quantity ?? 1, item.giftUsername ?? null),\n );\n\n const totalPrice = packages.reduce((sum, pkg) => sum + pkg.in_basket.price, 0);\n\n return {\n ...defaultMockBasket,\n packages,\n total_price: totalPrice,\n base_price: totalPrice,\n ...overrides,\n };\n}\n\n/**\n * Create a mock coupon.\n */\nexport function createMockCoupon(code: string): Code {\n return {\n code,\n };\n}\n\n/**\n * Create a mock gift card.\n */\nexport function createMockGiftCard(cardNumber: string): GiftCardCode {\n return {\n card_number: cardNumber,\n };\n}\n\n/**\n * Pre-built mock data for common testing scenarios.\n */\nexport const mockData = {\n /** Default webstore */\n webstore: defaultMockWebstore,\n\n /** All categories with packages */\n categories: defaultMockCategories,\n\n /** All packages flat list */\n packages: defaultMockPackages,\n\n /** Empty basket */\n emptyBasket: defaultMockBasket,\n\n /** Basket with one VIP Gold item */\n basketWithOneItem: createMockBasket([{ package: defaultMockPackages[0]!, quantity: 1 }]),\n\n /** Basket with multiple items */\n basketWithMultipleItems: createMockBasket([\n { package: defaultMockPackages[0]!, quantity: 1 },\n { package: defaultMockPackages[2]!, quantity: 2 },\n ]),\n\n /** Basket with coupon applied */\n basketWithCoupon: {\n ...createMockBasket([{ package: defaultMockPackages[0]!, quantity: 1 }]),\n coupons: [createMockCoupon('SAVE10')],\n },\n\n /** Basket with gift card applied */\n basketWithGiftCard: {\n ...createMockBasket([{ package: defaultMockPackages[0]!, quantity: 1 }]),\n giftcards: [createMockGiftCard('GIFT-1234-5678')],\n },\n\n /** Basket with creator code */\n basketWithCreatorCode: {\n ...createMockBasket([{ package: defaultMockPackages[0]!, quantity: 1 }]),\n creator_code: 'STREAMER123',\n },\n\n /** Helper functions */\n helpers: {\n createBasketPackage,\n createMockBasket,\n createMockCoupon,\n createMockGiftCard,\n },\n\n /** Get package by ID */\n getPackageById: (id: number): MockPackage | undefined => {\n return defaultMockPackages.find(p => p.id === id);\n },\n\n /** Get category by ID */\n getCategoryById: (id: number): MockCategory | undefined => {\n return defaultMockCategories.find(c => c.id === id);\n },\n} as const;\n\nexport type { Basket, BasketPackage, Category, Code, GiftCardCode, Package };\n","'use client';\n\nimport { QueryClient, QueryClientProvider } from '@tanstack/react-query';\nimport { useContext, useEffect, useMemo, useState, type ReactNode } from 'react';\n\nimport { TebexError } from '../errors/TebexError';\nimport { TebexContext, type TebexContextValue } from '../provider/context';\nimport { tebexKeys } from '../queries/keys';\nimport { useBasketStore } from '../stores/basketStore';\nimport { useUserStore } from '../stores/userStore';\nimport type { ResolvedTebexConfig } from '../types/config';\nimport {\n defaultMockBasket,\n defaultMockCategories,\n defaultMockPackages,\n defaultMockWebstore,\n type MockBasket,\n type MockCategory,\n type MockDataConfig,\n type MockPackage,\n type MockWebstoreData,\n} from './mockData';\n\n/**\n * Props for TebexMockProvider component.\n */\nexport interface TebexMockProviderProps {\n readonly children: ReactNode;\n\n /**\n * Mock data to use. If not provided, defaults will be used.\n */\n readonly mockData?: MockDataConfig | undefined;\n\n /**\n * Mock username to set in the user store.\n * @default 'TestPlayer'\n */\n readonly username?: string | null | undefined;\n\n /**\n * Whether to initialize a basket.\n * If true and mockData.basket is provided, that basket will be used.\n * If true and no basket is provided, an empty basket will be created.\n * @default true\n */\n readonly withBasket?: boolean | undefined;\n\n /**\n * Base URL for the mock store.\n * @default 'https://mock.tebex.io'\n */\n readonly baseUrl?: string | undefined;\n\n /**\n * Callback when an error occurs.\n */\n readonly onError?: ((error: TebexError) => void) | undefined;\n}\n\n/**\n * Create a QueryClient configured for mocking.\n * - Infinite staleTime so queries never auto-refetch\n * - No retries\n * - Instant garbage collection time for testing\n */\nfunction createMockQueryClient(): QueryClient {\n return new QueryClient({\n defaultOptions: {\n queries: {\n staleTime: Infinity,\n gcTime: Infinity,\n retry: false,\n refetchOnMount: false,\n refetchOnWindowFocus: false,\n refetchOnReconnect: false,\n },\n mutations: {\n retry: false,\n },\n },\n });\n}\n\n/**\n * Resolve mock config with defaults.\n */\nfunction resolveMockConfig(\n baseUrl: string,\n onError?: (error: TebexError) => void,\n): ResolvedTebexConfig {\n const cleanBaseUrl = baseUrl.replace(/\\/$/, '');\n\n return {\n publicKey: 'mock-public-key',\n baseUrl: cleanBaseUrl,\n completeUrl: `${cleanBaseUrl}/shop/complete`,\n cancelUrl: `${cleanBaseUrl}/shop/cancel`,\n onError,\n };\n}\n\n/**\n * Populate the QueryClient with mock data.\n */\nfunction populateMockData(\n queryClient: QueryClient,\n config: {\n webstore: MockWebstoreData;\n categories: MockCategory[];\n packages: MockPackage[];\n basket: MockBasket | null;\n basketIdent: string | null;\n },\n): void {\n // Webstore data\n queryClient.setQueryData(tebexKeys.webstore(), {\n id: config.webstore.id,\n name: config.webstore.name,\n description: config.webstore.description,\n currency: config.webstore.currency,\n domain: config.webstore.domain,\n logo: config.webstore.logo,\n });\n\n // Categories with packages\n queryClient.setQueryData(tebexKeys.categoriesList(true), config.categories);\n\n // Categories without packages\n queryClient.setQueryData(\n tebexKeys.categoriesList(false),\n config.categories.map(cat => ({ ...cat, packages: [] })),\n );\n\n // Individual categories\n for (const category of config.categories) {\n queryClient.setQueryData(tebexKeys.category(category.id), category);\n }\n\n // All packages\n queryClient.setQueryData(tebexKeys.packagesList(), config.packages);\n\n // Packages by category\n const packagesByCategory = new Map<number, MockPackage[]>();\n for (const pkg of config.packages) {\n const categoryId = pkg.category.id;\n const existing = packagesByCategory.get(categoryId) ?? [];\n packagesByCategory.set(categoryId, [...existing, pkg]);\n }\n for (const [categoryId, packages] of packagesByCategory) {\n queryClient.setQueryData(tebexKeys.packagesList(categoryId), packages);\n }\n\n // Individual packages\n for (const pkg of config.packages) {\n queryClient.setQueryData(tebexKeys.package(pkg.id), pkg);\n }\n\n // Basket (if provided)\n if (config.basket !== null && config.basketIdent !== null) {\n queryClient.setQueryData(tebexKeys.basket(config.basketIdent), config.basket);\n }\n}\n\n/**\n * Component to sync mock data with stores.\n */\nfunction MockStoreSync({\n username,\n basketIdent,\n}: {\n username: string | null;\n basketIdent: string | null;\n}): null {\n const setUsername = useUserStore(state => state.setUsername);\n const clearUsername = useUserStore(state => state.clearUsername);\n const setBasketIdent = useBasketStore(state => state.setBasketIdent);\n const clearBasketIdent = useBasketStore(state => state.clearBasketIdent);\n\n useEffect(() => {\n if (username !== null) {\n setUsername(username);\n } else {\n clearUsername();\n }\n }, [username, setUsername, clearUsername]);\n\n useEffect(() => {\n if (basketIdent !== null) {\n setBasketIdent(basketIdent);\n } else {\n clearBasketIdent();\n }\n }, [basketIdent, setBasketIdent, clearBasketIdent]);\n\n return null;\n}\n\n/**\n * TebexMockProvider - A mock provider for testing and Storybook.\n *\n * This provider pre-populates TanStack Query with mock data, allowing\n * you to render components that use Tebex hooks without making real API calls.\n *\n * **Features:**\n * - Pre-populated categories, packages, and webstore data\n * - Optional basket state\n * - No network requests (queries have infinite staleTime)\n * - Same context interface as TebexProvider\n *\n * **Limitations:**\n * - Mutations (addPackage, removePackage, etc.) won't persist changes\n * - For full mutation support, use MSW with the provided handlers\n *\n * @example Basic usage\n * ```tsx\n * import { TebexMockProvider, mockData } from '@neosianexus/super-tebex/testing';\n *\n * <TebexMockProvider>\n * <ShopPage />\n * </TebexMockProvider>\n * ```\n *\n * @example Custom mock data\n * ```tsx\n * <TebexMockProvider\n * mockData={{\n * webstore: { name: 'My Custom Store', currency: 'USD' },\n * basket: mockData.basketWithMultipleItems,\n * }}\n * username=\"CustomPlayer\"\n * >\n * <CheckoutPage />\n * </TebexMockProvider>\n * ```\n *\n * @example Without basket (for category/package browsing)\n * ```tsx\n * <TebexMockProvider withBasket={false}>\n * <CatalogPage />\n * </TebexMockProvider>\n * ```\n */\nexport function TebexMockProvider({\n children,\n mockData: mockDataConfig,\n username = 'TestPlayer',\n withBasket = true,\n baseUrl = 'https://mock.tebex.io',\n onError,\n}: TebexMockProviderProps): ReactNode {\n // Resolve mock data with defaults\n const resolvedMockData = useMemo(() => {\n const webstore: MockWebstoreData = {\n ...defaultMockWebstore,\n ...mockDataConfig?.webstore,\n };\n\n const categories = mockDataConfig?.categories ?? defaultMockCategories;\n const packages = mockDataConfig?.packages ?? defaultMockPackages;\n\n let basket: MockBasket | null = null;\n let basketIdent: string | null = null;\n\n if (withBasket) {\n basket = mockDataConfig?.basket\n ? { ...defaultMockBasket, ...mockDataConfig.basket }\n : defaultMockBasket;\n basketIdent = basket.ident;\n\n // Set username on basket if provided\n if (username !== null) {\n basket = { ...basket, username };\n }\n }\n\n return { webstore, categories, packages, basket, basketIdent };\n }, [mockDataConfig, withBasket, username]);\n\n // Create QueryClient once\n const [queryClient] = useState(() => createMockQueryClient());\n\n // Resolve config\n const resolvedConfig = useMemo(() => resolveMockConfig(baseUrl, onError), [baseUrl, onError]);\n\n // Populate mock data on mount and when data changes\n useEffect(() => {\n populateMockData(queryClient, resolvedMockData);\n }, [queryClient, resolvedMockData]);\n\n // Context value — mock provider is always considered hydrated\n const contextValue = useMemo<TebexContextValue>(\n () => ({\n config: resolvedConfig,\n queryClient,\n isHydrated: true,\n }),\n [resolvedConfig, queryClient],\n );\n\n return (\n <TebexContext.Provider value={contextValue}>\n <QueryClientProvider client={queryClient}>\n <MockStoreSync username={username} basketIdent={resolvedMockData.basketIdent} />\n {children}\n </QueryClientProvider>\n </TebexContext.Provider>\n );\n}\n\n/**\n * Hook to check if we're inside a mock provider.\n * Useful for conditional logic in components.\n *\n * Note: This hook checks for any Tebex provider (real or mock).\n * The mock provider is identified by its configuration.\n */\nexport function useIsMockProvider(): boolean {\n const context = useContext(TebexContext);\n return context !== null && context.config.publicKey === 'mock-public-key';\n}\n"]}
|
package/dist/testing/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
import {QueryClientProvider,QueryClient}from'@tanstack/react-query';import {createContext,useMemo,useState,useEffect,useContext}from'react';import {create}from'zustand';import {subscribeWithSelector,persist}from'zustand/middleware';import {jsx,jsxs}from'react/jsx-runtime';var
|
|
3
|
-
export{
|
|
2
|
+
import {QueryClientProvider,QueryClient}from'@tanstack/react-query';import {createContext,useMemo,useState,useEffect,useContext}from'react';import {create}from'zustand';import {subscribeWithSelector,persist}from'zustand/middleware';import {jsx,jsxs}from'react/jsx-runtime';var b=createContext(null);var o={all:["tebex"],categories:()=>[...o.all,"categories"],categoriesList:e=>[...o.categories(),"list",{includePackages:e}],category:e=>[...o.categories(),"detail",e],packages:()=>[...o.all,"packages"],packagesList:e=>[...o.packages(),"list",{categoryId:e}],package:e=>[...o.packages(),"detail",e],baskets:()=>[...o.all,"baskets"],basket:e=>[...o.baskets(),e],webstore:()=>[...o.all,"webstore"]};var p=create()(subscribeWithSelector(persist(e=>({basketIdent:null,setBasketIdent:t=>{e({basketIdent:t});},clearBasketIdent:()=>{e({basketIdent:null});}}),{name:"tebex-basket-store",skipHydration:true,version:1,partialize:e=>({basketIdent:e.basketIdent}),migrate:e=>{if(typeof e=="object"&&e!==null&&"basketIdent"in e){let t=e;return {basketIdent:typeof t.basketIdent=="string"?t.basketIdent:null}}return {basketIdent:null}},onRehydrateStorage:()=>(e,t)=>{t!==void 0&&console.warn("[tebex] Failed to rehydrate basket store:",t);}})));var m=create()(subscribeWithSelector(persist(e=>({username:null,setUsername:t=>{e({username:t});},clearUsername:()=>{e({username:null}),p.getState().clearBasketIdent();}}),{name:"tebex-user-store",skipHydration:true,version:1,partialize:e=>({username:e.username}),migrate:e=>{if(typeof e=="object"&&e!==null&&"username"in e){let t=e;return {username:typeof t.username=="string"?t.username:null}}return {username:null}},onRehydrateStorage:()=>(e,t)=>{t!==void 0&&console.warn("[tebex] Failed to rehydrate user store:",t);}})));var g={id:1,name:"Test Store",description:"A test Tebex store for development",currency:"EUR",domain:"test.tebex.io",logo:null},s=[{id:101,name:"VIP Gold",description:"Gold VIP membership with exclusive perks",type:"single",disable_gifting:false,disable_quantity:false,expiration_date:null,base_price:9.99,sales_tax:0,total_price:9.99,currency:"EUR",image:null,category:{id:1,name:"VIP Ranks"},discount:0,created_at:"2024-01-01T00:00:00Z",updated_at:"2024-01-01T00:00:00Z",order:1},{id:102,name:"VIP Diamond",description:"Diamond VIP membership with all perks",type:"single",disable_gifting:false,disable_quantity:false,expiration_date:null,base_price:19.99,sales_tax:0,total_price:19.99,currency:"EUR",image:null,category:{id:1,name:"VIP Ranks"},discount:0,created_at:"2024-01-01T00:00:00Z",updated_at:"2024-01-01T00:00:00Z",order:2},{id:201,name:"Pet Pack",description:"Adorable pet companions",type:"single",disable_gifting:false,disable_quantity:false,expiration_date:null,base_price:4.99,sales_tax:0,total_price:4.99,currency:"EUR",image:null,category:{id:2,name:"Cosmetics"},discount:0,created_at:"2024-01-01T00:00:00Z",updated_at:"2024-01-01T00:00:00Z",order:1},{id:202,name:"Trail Effects",description:"Particle trail effects",type:"single",disable_gifting:false,disable_quantity:false,expiration_date:null,base_price:2.99,sales_tax:0,total_price:2.99,currency:"EUR",image:null,category:{id:2,name:"Cosmetics"},discount:0,created_at:"2024-01-01T00:00:00Z",updated_at:"2024-01-01T00:00:00Z",order:2},{id:301,name:"1000 Coins",description:"In-game currency pack",type:"single",disable_gifting:false,disable_quantity:false,expiration_date:null,base_price:1.99,sales_tax:0,total_price:1.99,currency:"EUR",image:null,category:{id:3,name:"Currency"},discount:0,created_at:"2024-01-01T00:00:00Z",updated_at:"2024-01-01T00:00:00Z",order:1}],y=[{id:1,name:"VIP Ranks",description:"Exclusive VIP memberships",parent:null,order:1,display_type:"grid",slug:"vip-ranks",packages:s.filter(e=>e.category.id===1)},{id:2,name:"Cosmetics",description:"Cosmetic items and effects",parent:null,order:2,display_type:"grid",slug:"cosmetics",packages:s.filter(e=>e.category.id===2)},{id:3,name:"Currency",description:"In-game currency packs",parent:null,order:3,display_type:"grid",slug:"currency",packages:s.filter(e=>e.category.id===3)}],d={ident:"mock-basket-001",complete:false,id:1,country:"US",ip:"127.0.0.1",username_id:null,username:null,cancel_url:"https://example.com/cancel",complete_url:"https://example.com/complete",complete_auto_redirect:false,base_price:0,sales_tax:0,total_price:0,email:"",currency:"EUR",packages:[],coupons:[],giftcards:[],creator_code:"",links:{checkout:"https://checkout.tebex.io/mock"},custom:{}};function M(e,t=1,r=null){return {id:e.id,name:e.name,description:e.description,image:e.image,in_basket:{quantity:t,price:e.base_price*t,gift_username_id:null,gift_username:r}}}function l(e,t){let r=e.map(n=>M(n.package,n.quantity??1,n.giftUsername??null)),a=r.reduce((n,i)=>n+i.in_basket.price,0);return {...d,packages:r,total_price:a,base_price:a,...t}}function f(e){return {code:e}}function x(e){return {card_number:e}}var V={webstore:g,categories:y,packages:s,emptyBasket:d,basketWithOneItem:l([{package:s[0],quantity:1}]),basketWithMultipleItems:l([{package:s[0],quantity:1},{package:s[2],quantity:2}]),basketWithCoupon:{...l([{package:s[0],quantity:1}]),coupons:[f("SAVE10")]},basketWithGiftCard:{...l([{package:s[0],quantity:1}]),giftcards:[x("GIFT-1234-5678")]},basketWithCreatorCode:{...l([{package:s[0],quantity:1}]),creator_code:"STREAMER123"},helpers:{createBasketPackage:M,createMockBasket:l,createMockCoupon:f,createMockGiftCard:x},getPackageById:e=>s.find(t=>t.id===e),getCategoryById:e=>y.find(t=>t.id===e)};function q(){return new QueryClient({defaultOptions:{queries:{staleTime:1/0,gcTime:1/0,retry:false,refetchOnMount:false,refetchOnWindowFocus:false,refetchOnReconnect:false},mutations:{retry:false}}})}function O(e,t){let r=e.replace(/\/$/,"");return {publicKey:"mock-public-key",baseUrl:r,completeUrl:`${r}/shop/complete`,cancelUrl:`${r}/shop/cancel`,onError:t}}function F(e,t){e.setQueryData(o.webstore(),{id:t.webstore.id,name:t.webstore.name,description:t.webstore.description,currency:t.webstore.currency,domain:t.webstore.domain,logo:t.webstore.logo}),e.setQueryData(o.categoriesList(true),t.categories),e.setQueryData(o.categoriesList(false),t.categories.map(a=>({...a,packages:[]})));for(let a of t.categories)e.setQueryData(o.category(a.id),a);e.setQueryData(o.packagesList(),t.packages);let r=new Map;for(let a of t.packages){let n=a.category.id,i=r.get(n)??[];r.set(n,[...i,a]);}for(let[a,n]of r)e.setQueryData(o.packagesList(a),n);for(let a of t.packages)e.setQueryData(o.package(a.id),a);t.basket!==null&&t.basketIdent!==null&&e.setQueryData(o.basket(t.basketIdent),t.basket);}function H({username:e,basketIdent:t}){let r=m(c=>c.setUsername),a=m(c=>c.clearUsername),n=p(c=>c.setBasketIdent),i=p(c=>c.clearBasketIdent);return useEffect(()=>{e!==null?r(e):a();},[e,r,a]),useEffect(()=>{t!==null?n(t):i();},[t,n,i]),null}function L({children:e,mockData:t,username:r="TestPlayer",withBasket:a=true,baseUrl:n="https://mock.tebex.io",onError:i}){let c=useMemo(()=>{let S={...g,...t?.webstore},v=t?.categories??y,U=t?.packages??s,k=null,T=null;return a&&(k=t?.basket?{...d,...t.basket}:d,T=k.ident,r!==null&&(k={...k,username:r})),{webstore:S,categories:v,packages:U,basket:k,basketIdent:T}},[t,a,r]),[u]=useState(()=>q()),P=useMemo(()=>O(n,i),[n,i]);useEffect(()=>{F(u,c);},[u,c]);let I=useMemo(()=>({config:P,queryClient:u,isHydrated:true}),[P,u]);return jsx(b.Provider,{value:I,children:jsxs(QueryClientProvider,{client:u,children:[jsx(H,{username:r,basketIdent:c.basketIdent}),e]})})}function N(){let e=useContext(b);return e!==null&&e.config.publicKey==="mock-public-key"}
|
|
3
|
+
export{L as TebexMockProvider,M as createBasketPackage,l as createMockBasket,f as createMockCoupon,x as createMockGiftCard,d as defaultMockBasket,y as defaultMockCategories,s as defaultMockPackages,g as defaultMockWebstore,V as mockData,N as useIsMockProvider};//# sourceMappingURL=index.js.map
|
|
4
4
|
//# sourceMappingURL=index.js.map
|