@mohasinac/appkit 4.12.3 → 4.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. package/dist/_internal/server/features/brands/actions.js +7 -2
  2. package/dist/_internal/server/jobs/core/jobRunners.js +5 -0
  3. package/dist/_internal/server/jobs/core/onOrderCreate.js +33 -3
  4. package/dist/_internal/server/jobs/core/whatsappCatalogImport.d.ts +27 -0
  5. package/dist/_internal/server/jobs/core/whatsappCatalogImport.js +172 -0
  6. package/dist/core/hooks/useSiteSettings.d.ts +1 -1
  7. package/dist/features/account/hooks/useAccount.d.ts +2 -2
  8. package/dist/features/account/hooks/useAddressSelector.d.ts +1 -1
  9. package/dist/features/account/hooks/useAddresses.d.ts +2 -2
  10. package/dist/features/account/hooks/useNotifications.d.ts +1 -1
  11. package/dist/features/account/hooks/useProfile.d.ts +1 -1
  12. package/dist/features/account/hooks/usePublicProfile.d.ts +2 -2
  13. package/dist/features/admin/hooks/useAdmin.d.ts +1 -1
  14. package/dist/features/admin/hooks/useAdminSectionsListing.d.ts +1 -1
  15. package/dist/features/admin/hooks/useChat.d.ts +1 -1
  16. package/dist/features/auctions/hooks/useAuctions.d.ts +8 -8
  17. package/dist/features/auth/hooks/useAuth.d.ts +2 -2
  18. package/dist/features/cart/hooks/useCart.d.ts +1 -1
  19. package/dist/features/cart/hooks/useCartQuery.d.ts +1 -1
  20. package/dist/features/cart/hooks/useCheckoutReadQueries.d.ts +2 -2
  21. package/dist/features/cart/hooks/useOrder.d.ts +2 -2
  22. package/dist/features/categories/hooks/useCategories.d.ts +3 -3
  23. package/dist/features/categories/hooks/useCategorySelector.d.ts +3 -3
  24. package/dist/features/categories/hooks/useCategoryTree.d.ts +1 -1
  25. package/dist/features/checkout/hooks/useCheckoutApi.d.ts +2 -2
  26. package/dist/features/collections/hooks/useCollections.d.ts +2 -2
  27. package/dist/features/events/hooks/useEvent.d.ts +3 -3
  28. package/dist/features/events/hooks/useEvents.d.ts +1 -1
  29. package/dist/features/faq/hooks/useFAQs.d.ts +1 -1
  30. package/dist/features/faq/hooks/useFaqList.d.ts +9 -15
  31. package/dist/features/homepage/hooks/useBlogArticles.d.ts +1 -1
  32. package/dist/features/homepage/hooks/useFeaturedAuctions.d.ts +1 -1
  33. package/dist/features/homepage/hooks/useFeaturedPreOrders.d.ts +1 -1
  34. package/dist/features/homepage/hooks/useFeaturedProducts.d.ts +1 -1
  35. package/dist/features/homepage/hooks/useFeaturedStores.d.ts +1 -1
  36. package/dist/features/homepage/hooks/useHeroCarousel.d.ts +1 -1
  37. package/dist/features/homepage/hooks/useHomepageEvents.d.ts +1 -1
  38. package/dist/features/homepage/hooks/useHomepageReviews.d.ts +1 -1
  39. package/dist/features/homepage/hooks/useHomepageSections.d.ts +1 -1
  40. package/dist/features/homepage/hooks/useTopBrands.d.ts +1 -1
  41. package/dist/features/homepage/hooks/useTopCategories.d.ts +1 -1
  42. package/dist/features/loyalty/hooks/useLoyaltyBalance.d.ts +1 -1
  43. package/dist/features/orders/hooks/useOrders.d.ts +2 -2
  44. package/dist/features/payments/hooks/usePayments.d.ts +1 -1
  45. package/dist/features/pre-orders/hooks/usePreOrders.d.ts +2 -2
  46. package/dist/features/products/hooks/useProductDetail.d.ts +1 -1
  47. package/dist/features/products/hooks/useRelatedProducts.d.ts +1 -1
  48. package/dist/features/promotions/hooks/usePromotions.d.ts +2 -2
  49. package/dist/features/reviews/hooks/useReviews.d.ts +2 -2
  50. package/dist/features/search/hooks/useSearch.d.ts +2 -2
  51. package/dist/features/seller/hooks/useSellerPayouts.d.ts +3 -3
  52. package/dist/features/seller/hooks/useSellerStore.d.ts +6 -6
  53. package/dist/features/seller/hooks/useSellerStorefront.d.ts +2 -2
  54. package/dist/features/shipments/hooks/useShipments.d.ts +7 -7
  55. package/dist/features/stores/hooks/useStoreAddressSelector.d.ts +1 -1
  56. package/dist/features/stores/hooks/useStores.d.ts +6 -6
  57. package/dist/features/tester/seed-data/tester-checklist-seed-data.js +128 -0
  58. package/dist/features/whatsapp-bot/components/SellerWhatsAppSettingsView.js +42 -14
  59. package/dist/features/wishlist/hooks/useUserWishlist.d.ts +9 -15
  60. package/dist/features/wishlist/hooks/useWishlist.d.ts +1 -1
  61. package/dist/features/wishlist/hooks/useWishlistWithGuest.d.ts +1 -1
  62. package/dist/seed/site-settings-seed-data.js +19 -1
  63. package/package.json +15 -12
@@ -37,7 +37,12 @@ function brandInputToCategoryFields(input) {
37
37
  }
38
38
  export async function createBrandAction(input) {
39
39
  return wrapAction(async () => {
40
- await requireRoleUser("admin");
40
+ // Sellers create brands inline from the product form's brand picker
41
+ // (BrandInlineSelect -> BrandQuickCreateForm); there is no /store/brands
42
+ // page. Mirrors ROLES_STORE_WRITE on the only caller,
43
+ // src/app/api/admin/brands/route.ts. Kept as a gate rather than dropped:
44
+ // this is a "use server" export and is independently callable.
45
+ const actor = await requireRoleUser(["admin", "seller"]);
41
46
  const parsed = brandInputSchema.safeParse(input);
42
47
  if (!parsed.success)
43
48
  throw new ValidationError(parsed.error.issues[0]?.message ?? "Invalid brand input");
@@ -73,7 +78,7 @@ export async function createBrandAction(input) {
73
78
  },
74
79
  seo: { title: parsed.data.name, description: parsed.data.description ?? "", keywords: [parsed.data.name] },
75
80
  ancestors: [],
76
- createdBy: "admin",
81
+ createdBy: actor.uid,
77
82
  createdAt: new Date(),
78
83
  updatedAt: new Date(),
79
84
  ...fields,
@@ -13,6 +13,7 @@ import { runHardBanCascade } from "./hardBanCascade";
13
13
  import { runResetOtpVerification } from "./resetOtpVerification";
14
14
  import { runWhatsAppNotify } from "./whatsappNotify";
15
15
  import { runNewsletterExport } from "./newsletterExport";
16
+ import { runWhatsAppCatalogImport } from "./whatsappCatalogImport";
16
17
  async function runPayoutsWeeklyJob(_payload, ctx) {
17
18
  const { payoutsCreated, ordersProcessed, payoutIds } = await runWeeklyPayoutEligibility(ctx);
18
19
  return {
@@ -45,10 +46,14 @@ async function runWhatsAppNotifyJob(payload, ctx) {
45
46
  async function runNewsletterExportJob(_payload, ctx) {
46
47
  return runNewsletterExport(ctx);
47
48
  }
49
+ async function runWhatsAppCatalogImportJob(payload, ctx) {
50
+ return runWhatsAppCatalogImport({ storeSlug: String(payload.storeSlug ?? "") }, ctx);
51
+ }
48
52
  export const JOB_RUNNERS = {
49
53
  payoutsWeekly: runPayoutsWeeklyJob,
50
54
  hardBanCascade: runHardBanCascadeJob,
51
55
  resetOtpVerification: runResetOtpVerificationJob,
52
56
  whatsappNotify: runWhatsAppNotifyJob,
53
57
  newsletterExport: runNewsletterExportJob,
58
+ whatsappCatalogImport: runWhatsAppCatalogImportJob,
54
59
  };
@@ -2,6 +2,7 @@ import { normalizeError } from "../../../../errors/normalize";
2
2
  import { storeRepository, userRepository } from "../../../../repositories";
3
3
  import { decryptPii } from "../../../../security/index";
4
4
  import { sendWhatsAppBusinessMessage, buildPurchaseAnnouncementMessage, } from "../../../../features/whatsapp-bot/server";
5
+ import { resolveKeys } from "../../../../core/integration-keys";
5
6
  async function sendAnnouncement(ctx, toPhone, message, phoneNumberId, accessToken, label, orderId) {
6
7
  try {
7
8
  const sent = await sendWhatsAppBusinessMessage({
@@ -44,10 +45,40 @@ async function notifyStoreOwner(ctx, storeId, message, phoneNumberId, accessToke
44
45
  ctx.logger.error("Store owner lookup failed (non-fatal)", err, { orderId, storeId });
45
46
  }
46
47
  }
48
+ /**
49
+ * Seeded credentials are `*_PLACEHOLDER` strings rather than empty, so an
50
+ * emptiness test alone would happily send with a fake token. Mirrors the guard
51
+ * in checkout-value-otp-actions.ts.
52
+ */
53
+ function usable(value) {
54
+ const v = value?.trim() ?? "";
55
+ return v && !v.includes("PLACEHOLDER") ? v : "";
56
+ }
57
+ async function resolveWhatsAppCredentials(ctx, orderId) {
58
+ let db = {};
59
+ try {
60
+ db = await resolveKeys();
61
+ }
62
+ catch (err) {
63
+ void normalizeError(err);
64
+ // Firestore unreachable from the Functions runtime — env-only is still a
65
+ // valid configuration, so this is a warning, not a failure.
66
+ ctx.logger.warn("Credential lookup failed — falling back to env", { orderId });
67
+ }
68
+ return {
69
+ phoneNumberId: usable(db.whatsappPhoneNumberId) || usable(ctx.env("WHATSAPP_PHONE_NUMBER_ID")),
70
+ accessToken: usable(db.whatsappCloudApiToken) || usable(ctx.env("WHATSAPP_CLOUD_API_TOKEN")),
71
+ adminNumbersRaw: usable(db.whatsappAdminNotifyNumbers) || usable(ctx.env("WHATSAPP_ADMIN_NOTIFY_NUMBERS")),
72
+ };
73
+ }
47
74
  export async function handleOrderCreate(input, ctx) {
48
75
  const { orderId, order } = input;
49
- const phoneNumberId = ctx.env("WHATSAPP_PHONE_NUMBER_ID") ?? "";
50
- const accessToken = ctx.env("WHATSAPP_CLOUD_API_TOKEN") ?? "";
76
+ // Credentials resolve DB-first (Admin → Site Settings → WhatsApp) with an env
77
+ // fallback, matching resolveKeys() and every other WhatsApp send path. This
78
+ // read ctx.env() ONLY until 2026-08-22, so credentials saved in Site Settings
79
+ // never reached the order-placed announcement — it silently no-op'd unless the
80
+ // Functions runtime also carried the env vars.
81
+ const { phoneNumberId, accessToken, adminNumbersRaw } = await resolveWhatsAppCredentials(ctx, orderId);
51
82
  if (!phoneNumberId || !accessToken) {
52
83
  ctx.logger.info("WhatsApp Cloud API not configured — skipping announcement", { orderId });
53
84
  return;
@@ -64,7 +95,6 @@ export async function handleOrderCreate(input, ctx) {
64
95
  totalAmount: order.totalPrice ?? 0,
65
96
  orderId,
66
97
  });
67
- const adminNumbersRaw = ctx.env("WHATSAPP_ADMIN_NOTIFY_NUMBERS") ?? "";
68
98
  const adminNumbers = adminNumbersRaw
69
99
  .split(",")
70
100
  .map((n) => n.trim().replace(/\D/g, ""))
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Core: async WhatsApp Business Catalog import (`whatsappCatalogImport` job).
3
+ *
4
+ * `POST /api/store/whatsapp-settings/catalog-import` used to do this inline:
5
+ * one Meta fetch capped at `limit=250`, then a sequential per-item loop doing
6
+ * up to 2 `findBySlug` reads plus 1 `create` write EACH — a real 10s-timeout
7
+ * risk on Vercel Hobby (CLAUDE.md Rule #6) well before the cap was reached.
8
+ * It also declared `paging.next` in its response type and never followed it,
9
+ * so a catalog larger than 250 items silently imported only the first page.
10
+ *
11
+ * Running here instead buys the Function's 300s budget, which is what makes
12
+ * following `paging.next` safe rather than making the timeout worse.
13
+ *
14
+ * Two efficiency changes vs. the old route:
15
+ * - Existing-slug detection is ONE `findByStore` read into a Set, not 2 reads
16
+ * per item. A seller's WA catalog is populated by pushing their own store's
17
+ * products, so store-scoped lookup is equivalent to the old global
18
+ * `findBySlug` here while costing a single query.
19
+ * - That Set is updated as we create, so duplicate rows within one Meta
20
+ * response can't produce two products.
21
+ */
22
+ import type { JobContext } from "../runtime/types";
23
+ import type { JobRunResult } from "./jobRunners";
24
+ export interface WhatsAppCatalogImportPayload {
25
+ storeSlug: string;
26
+ }
27
+ export declare function runWhatsAppCatalogImport(payload: WhatsAppCatalogImportPayload, ctx: JobContext): Promise<JobRunResult>;
@@ -0,0 +1,172 @@
1
+ /**
2
+ * Core: async WhatsApp Business Catalog import (`whatsappCatalogImport` job).
3
+ *
4
+ * `POST /api/store/whatsapp-settings/catalog-import` used to do this inline:
5
+ * one Meta fetch capped at `limit=250`, then a sequential per-item loop doing
6
+ * up to 2 `findBySlug` reads plus 1 `create` write EACH — a real 10s-timeout
7
+ * risk on Vercel Hobby (CLAUDE.md Rule #6) well before the cap was reached.
8
+ * It also declared `paging.next` in its response type and never followed it,
9
+ * so a catalog larger than 250 items silently imported only the first page.
10
+ *
11
+ * Running here instead buys the Function's 300s budget, which is what makes
12
+ * following `paging.next` safe rather than making the timeout worse.
13
+ *
14
+ * Two efficiency changes vs. the old route:
15
+ * - Existing-slug detection is ONE `findByStore` read into a Set, not 2 reads
16
+ * per item. A seller's WA catalog is populated by pushing their own store's
17
+ * products, so store-scoped lookup is equivalent to the old global
18
+ * `findBySlug` here while costing a single query.
19
+ * - That Set is updated as we create, so duplicate rows within one Meta
20
+ * response can't produce two products.
21
+ */
22
+ import { normalizeError } from "../../../../errors/normalize";
23
+ import { storeRepository, productRepository } from "../../../../repositories";
24
+ import { decryptPii } from "../../../../security/index";
25
+ const META_GRAPH_BASE = "https://graph.facebook.com/v20.0";
26
+ const SLUG_PREFIX = "product-";
27
+ const PAGE_SIZE = 250;
28
+ /**
29
+ * Defensive stop. 40 pages x 250 = 10,000 items, far beyond any realistic
30
+ * seller catalog — this exists so a malformed/looping `paging.next` from Meta
31
+ * can't spin until the Function's 300s ceiling kills the job mid-write.
32
+ */
33
+ const MAX_PAGES = 40;
34
+ /** Meta returns "<amount> <currency>", e.g. "450.00 INR". */
35
+ function parseMetaPrice(raw) {
36
+ if (!raw)
37
+ return 0;
38
+ const digits = raw.replace(/[^0-9.]/g, "");
39
+ return Math.round((parseFloat(digits) || 0) * 100) / 100;
40
+ }
41
+ /**
42
+ * The LetItRip slug a Meta item claims to correspond to, if any. Items we
43
+ * pushed carry it in `description` (see catalog-sync's field mapping) and/or
44
+ * `retailer_id`; items authored natively in Meta carry neither.
45
+ */
46
+ function claimedSlug(item) {
47
+ const description = (item.description ?? "").trim();
48
+ if (description.startsWith(SLUG_PREFIX))
49
+ return description;
50
+ const retailerId = (item.retailer_id ?? "").trim();
51
+ if (retailerId.startsWith(SLUG_PREFIX))
52
+ return retailerId;
53
+ return null;
54
+ }
55
+ export async function runWhatsAppCatalogImport(payload, ctx) {
56
+ const { storeSlug } = payload;
57
+ const empty = { total: 0, succeeded: 0, skipped: 0, failed: 0 };
58
+ const store = await storeRepository.findBySlug(storeSlug);
59
+ if (!store) {
60
+ return {
61
+ summary: empty,
62
+ succeeded: [],
63
+ skipped: [],
64
+ failed: [{ id: storeSlug, reason: "Store not found" }],
65
+ };
66
+ }
67
+ const cfg = store.whatsappConfig;
68
+ const token = cfg?.accessToken ? decryptPii(cfg.accessToken) : null;
69
+ // Re-checked here even though the route gates on the same conditions — the
70
+ // job doc outlives the request, and the seller could disconnect in between.
71
+ if (!cfg?.connected || !cfg.catalogId || !token) {
72
+ return {
73
+ summary: empty,
74
+ succeeded: [],
75
+ skipped: [],
76
+ failed: [{ id: storeSlug, reason: "WhatsApp is not connected for this store" }],
77
+ };
78
+ }
79
+ const existing = await productRepository.findByStore(store.storeSlug);
80
+ const knownSlugs = new Set(existing.map((p) => p.slug).filter((s) => Boolean(s)));
81
+ const imported = [];
82
+ const skipped = [];
83
+ const failed = [];
84
+ let url = `${META_GRAPH_BASE}/${cfg.catalogId}/products` +
85
+ `?fields=name,price,currency,image_url,description,retailer_id&limit=${PAGE_SIZE}`;
86
+ let page = 0;
87
+ let truncated = false;
88
+ while (url) {
89
+ if (page >= MAX_PAGES) {
90
+ truncated = true;
91
+ ctx.logger.warn("whatsappCatalogImport: page cap reached — catalog truncated", {
92
+ storeSlug,
93
+ maxPages: MAX_PAGES,
94
+ importedSoFar: imported.length,
95
+ });
96
+ break;
97
+ }
98
+ page++;
99
+ const res = await fetch(url, { headers: { Authorization: `Bearer ${token}` } });
100
+ if (!res.ok) {
101
+ const body = (await res.json().catch(() => ({})));
102
+ const reason = body.error?.message ?? res.statusText;
103
+ ctx.logger.error("whatsappCatalogImport: Meta fetch failed", null, { storeSlug, page, reason });
104
+ failed.push({ id: `page-${page}`, reason: `Meta fetch failed: ${reason}` });
105
+ break;
106
+ }
107
+ const body = (await res.json());
108
+ const items = body.data ?? [];
109
+ for (const item of items) {
110
+ const slug = claimedSlug(item);
111
+ if (slug && knownSlugs.has(slug)) {
112
+ skipped.push(item.id);
113
+ continue;
114
+ }
115
+ const input = {
116
+ title: item.name ?? `WhatsApp Import ${item.id}`,
117
+ description: "",
118
+ slug: "",
119
+ listingType: "standard",
120
+ status: "draft",
121
+ price: parseMetaPrice(item.price),
122
+ currency: "INR",
123
+ mainImage: item.image_url ?? "",
124
+ images: [],
125
+ stockQuantity: 1,
126
+ condition: "new",
127
+ storeId: store.id,
128
+ storeName: store.storeName,
129
+ tags: ["whatsapp-import"],
130
+ categorySlugs: [],
131
+ featured: false,
132
+ };
133
+ try {
134
+ const created = await productRepository.create(input);
135
+ // Guard against the same item appearing twice in one Meta response.
136
+ if (slug)
137
+ knownSlugs.add(slug);
138
+ if (created.slug)
139
+ knownSlugs.add(created.slug);
140
+ imported.push(created.id);
141
+ }
142
+ catch (err) {
143
+ void normalizeError(err);
144
+ failed.push({
145
+ id: item.id,
146
+ reason: err instanceof Error ? err.message : "Product create failed",
147
+ });
148
+ }
149
+ }
150
+ url = body.paging?.next;
151
+ }
152
+ ctx.logger.info("whatsappCatalogImport: complete", {
153
+ storeSlug,
154
+ pages: page,
155
+ imported: imported.length,
156
+ skipped: skipped.length,
157
+ failed: failed.length,
158
+ truncated,
159
+ });
160
+ return {
161
+ summary: {
162
+ total: imported.length + skipped.length + failed.length,
163
+ succeeded: imported.length,
164
+ skipped: skipped.length,
165
+ failed: failed.length,
166
+ },
167
+ succeeded: imported,
168
+ skipped,
169
+ failed,
170
+ data: { imported: imported.length, skipped: skipped.length, pages: page, truncated },
171
+ };
172
+ }
@@ -1 +1 @@
1
- export declare function useSiteSettings<T = unknown>(endpoint?: "/api/site-settings", staleTime?: number): import("@tanstack/react-query").UseQueryResult<NoInfer<T>, Error>;
1
+ export declare function useSiteSettings<T = unknown>(endpoint?: "/api/site-settings", staleTime?: number): import("@tanstack/react-query").UseQueryResult<T, Error>;
@@ -5,9 +5,9 @@ interface UseProfileOptions {
5
5
  endpoint?: string;
6
6
  }
7
7
  export declare function useProfile(userId: string, opts?: UseProfileOptions): {
8
- profile: NoInfer<UserProfile> | undefined;
8
+ profile: UserProfile | undefined;
9
9
  isLoading: boolean;
10
10
  error: Error | null;
11
- refetch: (options?: import("@tanstack/query-core").RefetchOptions) => Promise<import("@tanstack/query-core").QueryObserverResult<NoInfer<UserProfile>, Error>>;
11
+ refetch: (options?: import("@tanstack/query-core").RefetchOptions) => Promise<import("@tanstack/query-core").QueryObserverResult<UserProfile, Error>>;
12
12
  };
13
13
  export {};
@@ -18,7 +18,7 @@ export declare function useAddressSelector(options?: {
18
18
  }): {
19
19
  addresses: SavedAddress[];
20
20
  isLoading: boolean;
21
- refetch: (options?: import("@tanstack/query-core").RefetchOptions) => Promise<import("@tanstack/query-core").QueryObserverResult<NoInfer<SavedAddress[]>, Error>>;
21
+ refetch: (options?: import("@tanstack/query-core").RefetchOptions) => Promise<import("@tanstack/query-core").QueryObserverResult<SavedAddress[], Error>>;
22
22
  createAddress: import("@tanstack/react-query").UseMutateFunction<CreateAddressApiResponse, Error, AddressFormData, unknown>;
23
23
  isSaving: boolean;
24
24
  };
@@ -36,11 +36,11 @@ export declare function useAddresses(options?: {
36
36
  enabled?: boolean;
37
37
  listEndpoint?: string;
38
38
  filters?: AddressFilterParams;
39
- }): import("@tanstack/react-query").UseQueryResult<NoInfer<Address[]>, Error>;
39
+ }): import("@tanstack/react-query").UseQueryResult<Address[], Error>;
40
40
  export declare function useAddress(id: string, options?: {
41
41
  enabled?: boolean;
42
42
  byIdEndpoint?: (id: string) => string;
43
- }): import("@tanstack/react-query").UseQueryResult<NoInfer<Address>, Error>;
43
+ }): import("@tanstack/react-query").UseQueryResult<Address, Error>;
44
44
  export declare function useCreateAddress(options?: {
45
45
  listEndpoint?: string;
46
46
  onSuccess?: (data: Address) => void;
@@ -17,7 +17,7 @@ export declare function useNotifications<TNotification = any>(limit?: number, op
17
17
  notifications: TNotification[];
18
18
  unreadCount: number;
19
19
  isLoading: boolean;
20
- refetch: (options?: import("@tanstack/query-core").RefetchOptions) => Promise<import("@tanstack/query-core").QueryObserverResult<NoInfer<NotificationsResponse<TNotification>>, Error>>;
20
+ refetch: (options?: import("@tanstack/query-core").RefetchOptions) => Promise<import("@tanstack/query-core").QueryObserverResult<NotificationsResponse<TNotification>, Error>>;
21
21
  markRead: import("@tanstack/react-query").UseMutateFunction<unknown, Error, string, unknown>;
22
22
  markAllRead: import("@tanstack/react-query").UseMutateFunction<unknown, Error, void, unknown>;
23
23
  isMarkingAll: boolean;
@@ -40,7 +40,7 @@ export interface UpdateCurrentProfileInput {
40
40
  export declare function useCurrentProfile(options?: {
41
41
  enabled?: boolean;
42
42
  endpoint?: string;
43
- }): import("@tanstack/react-query").UseQueryResult<NoInfer<UserProfile>, Error>;
43
+ }): import("@tanstack/react-query").UseQueryResult<UserProfile, Error>;
44
44
  export declare function useUpdateCurrentProfile(options?: {
45
45
  onSuccess?: (data: JsonValue) => void;
46
46
  onError?: (error: Error) => void;
@@ -71,8 +71,8 @@ export declare function usePublicProfile(userId: string, options?: PublicProfile
71
71
  loading: boolean;
72
72
  profileError: string;
73
73
  isSeller: boolean;
74
- productsData: NoInfer<ProductsApiResponse> | undefined;
74
+ productsData: ProductsApiResponse | undefined;
75
75
  productsLoading: boolean;
76
- reviewsData: NoInfer<SellerReviewsData> | undefined;
76
+ reviewsData: SellerReviewsData | undefined;
77
77
  reviewsLoading: boolean;
78
78
  };
@@ -3,7 +3,7 @@ export declare function useDashboardStats(opts?: {
3
3
  initialData?: DashboardStats;
4
4
  enabled?: boolean;
5
5
  }): {
6
- stats: NoInfer<DashboardStats> | undefined;
6
+ stats: DashboardStats | undefined;
7
7
  isLoading: boolean;
8
8
  error: Error | null;
9
9
  };
@@ -23,6 +23,6 @@ export declare function useAdminSectionsListing({ page, pageSize, sorts, filters
23
23
  hasMore: boolean;
24
24
  isLoading: boolean;
25
25
  errorMessage: string | undefined;
26
- refetch: (options?: import("@tanstack/query-core").RefetchOptions) => Promise<import("@tanstack/query-core").QueryObserverResult<NoInfer<AdminSectionsListingResponse>, ApiClientError>>;
26
+ refetch: (options?: import("@tanstack/query-core").RefetchOptions) => Promise<import("@tanstack/query-core").QueryObserverResult<AdminSectionsListingResponse, ApiClientError>>;
27
27
  };
28
28
  export {};
@@ -16,7 +16,7 @@ export interface UseChatReturn {
16
16
  export declare function useChat(chatId: string | null, options?: {
17
17
  realtimeProvider?: IClientRealtimeProvider;
18
18
  }): UseChatReturn;
19
- export declare function useChatRooms(): import("@tanstack/react-query").UseQueryResult<NoInfer<unknown[]>, Error>;
19
+ export declare function useChatRooms(): import("@tanstack/react-query").UseQueryResult<unknown[], Error>;
20
20
  export declare function useCreateChatRoom(): import("@tanstack/react-query").UseMutationResult<unknown, import("@mohasinac/appkit/client").ApiError, {
21
21
  orderId: string;
22
22
  ownerId: string;
@@ -17,22 +17,22 @@ interface UseAuctionDetailOptions {
17
17
  bidsQueryKeyPrefix?: string;
18
18
  }
19
19
  export declare function useAuctions(params?: AuctionListQuery, opts?: UseAuctionsOptions): {
20
- data: NoInfer<AuctionListResponse> | undefined;
20
+ data: AuctionListResponse | undefined;
21
21
  auctions: AuctionItem[];
22
22
  total: number;
23
23
  totalPages: number;
24
24
  hasMore: boolean;
25
25
  isLoading: boolean;
26
26
  error: string | null;
27
- refetch: (options?: import("@tanstack/query-core").RefetchOptions) => Promise<import("@tanstack/query-core").QueryObserverResult<NoInfer<AuctionListResponse>, Error>>;
27
+ refetch: (options?: import("@tanstack/query-core").RefetchOptions) => Promise<import("@tanstack/query-core").QueryObserverResult<AuctionListResponse, Error>>;
28
28
  };
29
29
  export declare function useAuction(slug: string, opts?: {
30
30
  enabled?: boolean;
31
31
  }): {
32
- auction: NonNullable<NoInfer<AuctionItem | null>> | null;
32
+ auction: AuctionItem | null;
33
33
  isLoading: boolean;
34
34
  error: string | null;
35
- refetch: (options?: import("@tanstack/query-core").RefetchOptions) => Promise<import("@tanstack/query-core").QueryObserverResult<NoInfer<AuctionItem | null>, Error>>;
35
+ refetch: (options?: import("@tanstack/query-core").RefetchOptions) => Promise<import("@tanstack/query-core").QueryObserverResult<AuctionItem | null, Error>>;
36
36
  };
37
37
  export declare function useAuctionBids(auctionSlug: string, limit?: number, opts?: {
38
38
  enabled?: boolean;
@@ -43,9 +43,9 @@ export declare function useAuctionBids(auctionSlug: string, limit?: number, opts
43
43
  error: string | null;
44
44
  };
45
45
  export declare function useAuctionDetail(id: string, opts?: UseAuctionDetailOptions): {
46
- productQuery: import("@tanstack/react-query").UseQueryResult<NoInfer<ProductItem | null>, Error>;
47
- product: NonNullable<NoInfer<ProductItem | null>> | null;
48
- bidsQuery: import("@tanstack/react-query").UseQueryResult<NoInfer<PublicBid[]>, Error>;
49
- bids: NoInfer<PublicBid[]>;
46
+ productQuery: import("@tanstack/react-query").UseQueryResult<ProductItem | null, Error>;
47
+ product: ProductItem | null;
48
+ bidsQuery: import("@tanstack/react-query").UseQueryResult<PublicBid[], Error>;
49
+ bids: PublicBid[];
50
50
  };
51
51
  export {};
@@ -5,11 +5,11 @@ interface UseCurrentUserOptions {
5
5
  enabled?: boolean;
6
6
  }
7
7
  export declare function useCurrentUser(opts?: UseCurrentUserOptions): {
8
- user: NonNullable<NoInfer<AuthUser | null>> | null;
8
+ user: AuthUser | null;
9
9
  isLoading: boolean;
10
10
  isAuthenticated: boolean;
11
11
  error: Error | null;
12
- refetch: (options?: import("@tanstack/query-core").RefetchOptions) => Promise<import("@tanstack/query-core").QueryObserverResult<NoInfer<AuthUser | null>, Error>>;
12
+ refetch: (options?: import("@tanstack/query-core").RefetchOptions) => Promise<import("@tanstack/query-core").QueryObserverResult<AuthUser | null, Error>>;
13
13
  };
14
14
  export interface LoginCredentials {
15
15
  email: string;
@@ -12,6 +12,6 @@ export declare function useCart(userIdOrSession: string, opts?: UseCartOptions):
12
12
  itemCount: number;
13
13
  isLoading: boolean;
14
14
  error: Error | null;
15
- refetch: (options?: import("@tanstack/query-core").RefetchOptions) => Promise<import("@tanstack/query-core").QueryObserverResult<NoInfer<CartData>, Error>>;
15
+ refetch: (options?: import("@tanstack/query-core").RefetchOptions) => Promise<import("@tanstack/query-core").QueryObserverResult<CartData, Error>>;
16
16
  };
17
17
  export {};
@@ -5,5 +5,5 @@ interface UseCartQueryOptions<TData> {
5
5
  enabled?: boolean;
6
6
  initialData?: TData;
7
7
  }
8
- export declare function useCartQuery<TData = unknown>(options: UseCartQueryOptions<TData>): import("@tanstack/react-query").UseQueryResult<NoInfer<TData>, Error>;
8
+ export declare function useCartQuery<TData = unknown>(options: UseCartQueryOptions<TData>): import("@tanstack/react-query").UseQueryResult<TData, Error>;
9
9
  export {};
@@ -9,7 +9,7 @@ interface UseCheckoutReadQueriesOptions<TAddress, TCart> {
9
9
  initialCart?: TCart;
10
10
  }
11
11
  export declare function useCheckoutReadQueries<TAddress = unknown, TCart = unknown>(options: UseCheckoutReadQueriesOptions<TAddress, TCart>): {
12
- addressQuery: import("@tanstack/react-query").UseQueryResult<NoInfer<TAddress[]>, Error>;
13
- cartQuery: import("@tanstack/react-query").UseQueryResult<NoInfer<TCart>, Error>;
12
+ addressQuery: import("@tanstack/react-query").UseQueryResult<TAddress[], Error>;
13
+ cartQuery: import("@tanstack/react-query").UseQueryResult<TCart, Error>;
14
14
  };
15
15
  export {};
@@ -5,9 +5,9 @@ interface UseOrderOptions<TOrder> {
5
5
  initialData?: TOrder | null;
6
6
  }
7
7
  export declare function useOrder<TOrder = unknown>(orderId: string | null, options?: UseOrderOptions<TOrder>): {
8
- order: NonNullable<NoInfer<TOrder | null>> | null;
8
+ order: NonNullable<TOrder> | null;
9
9
  isLoading: boolean;
10
10
  error: Error | null;
11
- refetch: (options?: import("@tanstack/query-core").RefetchOptions) => Promise<import("@tanstack/query-core").QueryObserverResult<NoInfer<TOrder | null>, Error>>;
11
+ refetch: (options?: import("@tanstack/query-core").RefetchOptions) => Promise<import("@tanstack/query-core").QueryObserverResult<TOrder | null, Error>>;
12
12
  };
13
13
  export {};
@@ -4,7 +4,7 @@ interface UseCategoriesListOptions {
4
4
  enabled?: boolean;
5
5
  }
6
6
  export declare function useCategoriesList(opts?: UseCategoriesListOptions): {
7
- categories: NoInfer<CategoryItem[]>;
7
+ categories: CategoryItem[];
8
8
  total: number;
9
9
  isLoading: boolean;
10
10
  error: Error | null;
@@ -37,8 +37,8 @@ interface UseCategoryDetailOptions {
37
37
  childrenEndpoint?: string;
38
38
  }
39
39
  export declare function useCategoryDetail(slug: string, opts?: UseCategoryDetailOptions): {
40
- category: NonNullable<NoInfer<CategoryItem | null>> | null;
41
- children: NoInfer<CategoryItem[]>;
40
+ category: CategoryItem | null;
41
+ children: CategoryItem[];
42
42
  isLoading: boolean;
43
43
  childrenLoading: boolean;
44
44
  error: Error | null;
@@ -9,16 +9,16 @@ export interface UseCategorySelectorOptions {
9
9
  export declare function useCategorySelector(options?: UseCategorySelectorOptions): {
10
10
  categories: CategoryItem[];
11
11
  isLoading: boolean;
12
- refetch: (options?: import("@tanstack/query-core").RefetchOptions) => Promise<import("@tanstack/query-core").QueryObserverResult<NoInfer<CategoryItem[]>, Error>>;
12
+ refetch: (options?: import("@tanstack/query-core").RefetchOptions) => Promise<import("@tanstack/query-core").QueryObserverResult<CategoryItem[], Error>>;
13
13
  createCategory: import("@tanstack/react-query").UseMutateFunction<CategoryItem, Error, Record<string, JsonValue>, unknown>;
14
14
  isCreating: boolean;
15
15
  };
16
16
  export declare function useCategories(options?: {
17
17
  endpoint?: string;
18
18
  }): {
19
- categories: NoInfer<CategoryItem[]>;
19
+ categories: CategoryItem[];
20
20
  isLoading: boolean;
21
- refetch: (options?: import("@tanstack/query-core").RefetchOptions) => Promise<import("@tanstack/query-core").QueryObserverResult<NoInfer<CategoryItem[]>, Error>>;
21
+ refetch: (options?: import("@tanstack/query-core").RefetchOptions) => Promise<import("@tanstack/query-core").QueryObserverResult<CategoryItem[], Error>>;
22
22
  };
23
23
  export declare function useCreateCategory(options?: {
24
24
  endpoint?: string;
@@ -7,7 +7,7 @@ import type { CategoryItem } from "../types";
7
7
  export declare function useCategoryTree(opts?: {
8
8
  enabled?: boolean;
9
9
  }): {
10
- categories: NoInfer<CategoryItem[]>;
10
+ categories: CategoryItem[];
11
11
  isLoading: boolean;
12
12
  };
13
13
  /** Convert category tree to FacetOption[] with indentation prefix for tier > 0. */
@@ -62,8 +62,8 @@ interface UseCheckoutOptions<TAddress = any, TCart = any> {
62
62
  initialCart?: CartApiResponse<TCart>;
63
63
  }
64
64
  export declare function useCheckout<TAddress = any, TCart = any>(options?: UseCheckoutOptions<TAddress, TCart>): {
65
- addressQuery: import("@tanstack/react-query").UseQueryResult<NoInfer<TAddress[]>, Error>;
66
- cartQuery: import("@tanstack/react-query").UseQueryResult<NoInfer<CartApiResponse<TCart>>, Error>;
65
+ addressQuery: import("@tanstack/react-query").UseQueryResult<TAddress[], Error>;
66
+ cartQuery: import("@tanstack/react-query").UseQueryResult<CartApiResponse<TCart>, Error>;
67
67
  preflightMutation: import("@tanstack/react-query").UseMutationResult<PreflightResponse, Error, string, unknown>;
68
68
  placeCodOrderMutation: import("@tanstack/react-query").UseMutationResult<PlaceOrderResponse, Error, PlaceOrderPayload, unknown>;
69
69
  createPaymentOrderMutation: import("@tanstack/react-query").UseMutationResult<CreatePaymentOrderResponse, Error, CreatePaymentOrderPayload, unknown>;
@@ -1,7 +1,7 @@
1
1
  import type { CollectionItem, CollectionListItem } from "../types";
2
2
  export declare function useCollections(opts?: {
3
3
  endpoint?: string;
4
- }): import("@tanstack/react-query").UseQueryResult<NoInfer<CollectionListItem[]>, Error>;
4
+ }): import("@tanstack/react-query").UseQueryResult<CollectionListItem[], Error>;
5
5
  export declare function useCollection(slug: string | undefined, opts?: {
6
6
  endpoint?: string;
7
- }): import("@tanstack/react-query").UseQueryResult<NoInfer<CollectionItem | null>, Error>;
7
+ }): import("@tanstack/react-query").UseQueryResult<CollectionItem | null, Error>;
@@ -16,7 +16,7 @@ export declare function useEvent<T extends EventItem = EventItem>(id: string, op
16
16
  event: T | null;
17
17
  isLoading: boolean;
18
18
  error: string | null;
19
- refetch: (options?: import("@tanstack/query-core").RefetchOptions) => Promise<import("@tanstack/query-core").QueryObserverResult<NoInfer<EventItem | null>, Error>>;
19
+ refetch: (options?: import("@tanstack/query-core").RefetchOptions) => Promise<import("@tanstack/query-core").QueryObserverResult<EventItem | null, Error>>;
20
20
  };
21
21
  export declare function useEventEntries(eventId: string, params?: {
22
22
  page?: number;
@@ -30,13 +30,13 @@ export declare function useEventEntries(eventId: string, params?: {
30
30
  total: number;
31
31
  isLoading: boolean;
32
32
  error: string | null;
33
- refetch: (options?: import("@tanstack/query-core").RefetchOptions) => Promise<import("@tanstack/query-core").QueryObserverResult<NoInfer<EventEntryListResponse>, Error>>;
33
+ refetch: (options?: import("@tanstack/query-core").RefetchOptions) => Promise<import("@tanstack/query-core").QueryObserverResult<EventEntryListResponse, Error>>;
34
34
  };
35
35
  export declare function useEventLeaderboard(eventId: string, limit?: number, opts?: {
36
36
  enabled?: boolean;
37
37
  endpoint?: string;
38
38
  }): {
39
- leaderboard: NoInfer<LeaderboardEntry[]>;
39
+ leaderboard: LeaderboardEntry[];
40
40
  isLoading: boolean;
41
41
  error: string | null;
42
42
  };
@@ -23,6 +23,6 @@ export declare function useEvents<T extends EventItem = EventItem>(params?: Even
23
23
  hasMore: boolean;
24
24
  isLoading: boolean;
25
25
  error: string | null;
26
- refetch: (options?: import("@tanstack/query-core").RefetchOptions) => Promise<import("@tanstack/query-core").QueryObserverResult<NoInfer<EventListResponse>, Error>>;
26
+ refetch: (options?: import("@tanstack/query-core").RefetchOptions) => Promise<import("@tanstack/query-core").QueryObserverResult<EventListResponse, Error>>;
27
27
  };
28
28
  export {};
@@ -15,7 +15,7 @@ export declare function useFAQ(id: string, opts?: {
15
15
  enabled?: boolean;
16
16
  endpoint?: string;
17
17
  }): {
18
- faq: NoInfer<FAQ> | undefined;
18
+ faq: FAQ | undefined;
19
19
  isLoading: boolean;
20
20
  error: Error | null;
21
21
  };