@classytic/commerce-sdk 0.1.1

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 (133) hide show
  1. package/LICENSE +14 -0
  2. package/README.md +164 -0
  3. package/dist/adjustment-MNH3AT6S.js +5 -0
  4. package/dist/adjustment-MNH3AT6S.js.map +1 -0
  5. package/dist/analytics/index.d.ts +27 -0
  6. package/dist/analytics/index.js +6 -0
  7. package/dist/analytics/index.js.map +1 -0
  8. package/dist/analytics-DMcD-o8w.d.ts +76 -0
  9. package/dist/api-factory-B_h4RKBm.d.ts +280 -0
  10. package/dist/auth/index.d.ts +39 -0
  11. package/dist/auth/index.js +5 -0
  12. package/dist/auth/index.js.map +1 -0
  13. package/dist/catalog/index.d.ts +571 -0
  14. package/dist/catalog/index.js +9 -0
  15. package/dist/catalog/index.js.map +1 -0
  16. package/dist/chunk-24FDD6UR.js +75 -0
  17. package/dist/chunk-24FDD6UR.js.map +1 -0
  18. package/dist/chunk-2TF7QNYV.js +159 -0
  19. package/dist/chunk-2TF7QNYV.js.map +1 -0
  20. package/dist/chunk-2YAZ5WG6.js +479 -0
  21. package/dist/chunk-2YAZ5WG6.js.map +1 -0
  22. package/dist/chunk-36NLLAVH.js +177 -0
  23. package/dist/chunk-36NLLAVH.js.map +1 -0
  24. package/dist/chunk-3OYSJB3P.js +126 -0
  25. package/dist/chunk-3OYSJB3P.js.map +1 -0
  26. package/dist/chunk-5E57JODA.js +135 -0
  27. package/dist/chunk-5E57JODA.js.map +1 -0
  28. package/dist/chunk-7LZCW4VF.js +13 -0
  29. package/dist/chunk-7LZCW4VF.js.map +1 -0
  30. package/dist/chunk-ANYGZ6O5.js +830 -0
  31. package/dist/chunk-ANYGZ6O5.js.map +1 -0
  32. package/dist/chunk-AQAISI4F.js +183 -0
  33. package/dist/chunk-AQAISI4F.js.map +1 -0
  34. package/dist/chunk-B6MPVOV7.js +328 -0
  35. package/dist/chunk-B6MPVOV7.js.map +1 -0
  36. package/dist/chunk-CILP56G2.js +94 -0
  37. package/dist/chunk-CILP56G2.js.map +1 -0
  38. package/dist/chunk-ERQ52WHY.js +534 -0
  39. package/dist/chunk-ERQ52WHY.js.map +1 -0
  40. package/dist/chunk-FOTUJPM4.js +640 -0
  41. package/dist/chunk-FOTUJPM4.js.map +1 -0
  42. package/dist/chunk-IHCBBLLW.js +198 -0
  43. package/dist/chunk-IHCBBLLW.js.map +1 -0
  44. package/dist/chunk-J4JBQET2.js +76 -0
  45. package/dist/chunk-J4JBQET2.js.map +1 -0
  46. package/dist/chunk-L4OEI4VZ.js +123 -0
  47. package/dist/chunk-L4OEI4VZ.js.map +1 -0
  48. package/dist/chunk-LRV7MWWX.js +616 -0
  49. package/dist/chunk-LRV7MWWX.js.map +1 -0
  50. package/dist/chunk-N43VE355.js +126 -0
  51. package/dist/chunk-N43VE355.js.map +1 -0
  52. package/dist/chunk-PYYLHUV6.js +3 -0
  53. package/dist/chunk-PYYLHUV6.js.map +1 -0
  54. package/dist/chunk-QCTXAMLA.js +261 -0
  55. package/dist/chunk-QCTXAMLA.js.map +1 -0
  56. package/dist/chunk-RIKAPJNG.js +40 -0
  57. package/dist/chunk-RIKAPJNG.js.map +1 -0
  58. package/dist/chunk-U3XT35GZ.js +202 -0
  59. package/dist/chunk-U3XT35GZ.js.map +1 -0
  60. package/dist/chunk-W22WB3WZ.js +148 -0
  61. package/dist/chunk-W22WB3WZ.js.map +1 -0
  62. package/dist/chunk-WTIJMKML.js +27 -0
  63. package/dist/chunk-WTIJMKML.js.map +1 -0
  64. package/dist/chunk-X2CQFJPR.js +75 -0
  65. package/dist/chunk-X2CQFJPR.js.map +1 -0
  66. package/dist/chunk-YYFKLOKO.js +769 -0
  67. package/dist/chunk-YYFKLOKO.js.map +1 -0
  68. package/dist/client-Cs7E_usr.d.ts +113 -0
  69. package/dist/content/index.d.ts +309 -0
  70. package/dist/content/index.js +6 -0
  71. package/dist/content/index.js.map +1 -0
  72. package/dist/core/index.d.ts +166 -0
  73. package/dist/core/index.js +5 -0
  74. package/dist/core/index.js.map +1 -0
  75. package/dist/core/react.d.ts +107 -0
  76. package/dist/core/react.js +5 -0
  77. package/dist/core/react.js.map +1 -0
  78. package/dist/coupon-BZSZ0y3n.d.ts +129 -0
  79. package/dist/coupon-CDzL4bJG.d.ts +655 -0
  80. package/dist/crud.factory-DyKaPHcU.d.ts +181 -0
  81. package/dist/finance/index.d.ts +81 -0
  82. package/dist/finance/index.js +5 -0
  83. package/dist/finance/index.js.map +1 -0
  84. package/dist/finance-BJdfKRw0.d.ts +135 -0
  85. package/dist/index.d.ts +32 -0
  86. package/dist/index.js +29 -0
  87. package/dist/index.js.map +1 -0
  88. package/dist/inventory/index.d.ts +512 -0
  89. package/dist/inventory/index.js +16 -0
  90. package/dist/inventory/index.js.map +1 -0
  91. package/dist/inventory-B5pssqRx.d.ts +748 -0
  92. package/dist/logistics/index.d.ts +248 -0
  93. package/dist/logistics/index.js +7 -0
  94. package/dist/logistics/index.js.map +1 -0
  95. package/dist/logistics-CrpKadKE.d.ts +410 -0
  96. package/dist/media-CNLJK93J.d.ts +721 -0
  97. package/dist/movement-R3CERFAM.js +5 -0
  98. package/dist/movement-R3CERFAM.js.map +1 -0
  99. package/dist/order-B3dCvHgK.d.ts +360 -0
  100. package/dist/payment-BRboLqvU.d.ts +127 -0
  101. package/dist/payments/index.d.ts +55 -0
  102. package/dist/payments/index.js +6 -0
  103. package/dist/payments/index.js.map +1 -0
  104. package/dist/platform/index.d.ts +645 -0
  105. package/dist/platform/index.js +8 -0
  106. package/dist/platform/index.js.map +1 -0
  107. package/dist/pos-BCqkx2-K.d.ts +527 -0
  108. package/dist/product-p09zXkXB.d.ts +260 -0
  109. package/dist/purchase-54PER2PY.js +5 -0
  110. package/dist/purchase-54PER2PY.js.map +1 -0
  111. package/dist/request-MP6NV5ZE.js +5 -0
  112. package/dist/request-MP6NV5ZE.js.map +1 -0
  113. package/dist/sales/index.d.ts +587 -0
  114. package/dist/sales/index.js +9 -0
  115. package/dist/sales/index.js.map +1 -0
  116. package/dist/server.d.ts +23 -0
  117. package/dist/server.js +37 -0
  118. package/dist/server.js.map +1 -0
  119. package/dist/size-guide-DgjzjM5P.d.ts +554 -0
  120. package/dist/stock-2LP4HJSB.js +5 -0
  121. package/dist/stock-2LP4HJSB.js.map +1 -0
  122. package/dist/stock-CfrU5_Wr.d.ts +632 -0
  123. package/dist/supplier-BWJTRZ5Z.js +5 -0
  124. package/dist/supplier-BWJTRZ5Z.js.map +1 -0
  125. package/dist/transaction/index.d.ts +104 -0
  126. package/dist/transaction/index.js +8 -0
  127. package/dist/transaction/index.js.map +1 -0
  128. package/dist/transaction-Bf6WjYCh.d.ts +84 -0
  129. package/dist/transaction-dL3WW-er.d.ts +442 -0
  130. package/dist/transfer-4XSS6HWT.js +5 -0
  131. package/dist/transfer-4XSS6HWT.js.map +1 -0
  132. package/dist/user-data-DdLjAGwO.d.ts +132 -0
  133. package/package.json +147 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/catalog/api/product.ts","../src/catalog/api/category.ts","../src/catalog/api/size-guide.ts","../src/catalog/api/review.ts","../src/catalog/hooks/product.ts","../src/catalog/hooks/category.ts","../src/catalog/hooks/size-guide.ts","../src/catalog/hooks/review.ts"],"names":["useQuery","useQueryClient","useMutation"],"mappings":"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","file":"chunk-FOTUJPM4.js","sourcesContent":["/**\r\n * Product API Client\r\n *\r\n * **Authentication:**\r\n * - Public: List, Get, GetBySlug, GetRecommendations\r\n * - Admin: Create, Update, Delete, GetDeleted, Restore, HardDelete, SyncStock\r\n *\r\n * **Base URL:** `/api/v1/products`\r\n */\r\n\r\nimport { BaseApi, type ApiResponse, type PaginatedResponse } from '../../core';\r\nimport type {\r\n Product,\r\n CreateProductPayload,\r\n UpdateProductPayload,\r\n ProductSyncStockResponse,\r\n} from '../types';\r\n\r\ntype FetchOptions = {\r\n cache?: RequestCache;\r\n revalidate?: number;\r\n tags?: string[];\r\n};\r\n\r\n/**\r\n * Product API Client\r\n * Extends BaseApi with product-specific endpoints\r\n */\r\nclass ProductApi extends BaseApi<Product, CreateProductPayload, UpdateProductPayload> {\r\n constructor(config = {}) {\r\n super('products', config);\r\n }\r\n\r\n /**\r\n * Get product by slug\r\n * GET /products/slug/:slug\r\n * (Public endpoint)\r\n *\r\n * @param token - Auth token (optional, public endpoint)\r\n * @param slug - Product slug\r\n * @param options - Additional fetch options\r\n * @returns Product object\r\n */\r\n async getBySlug({\r\n token = null,\r\n slug,\r\n options = {},\r\n }: {\r\n token?: string | null;\r\n slug: string;\r\n options?: FetchOptions;\r\n }): Promise<ApiResponse<Product>> {\r\n if (!slug) {\r\n throw new Error('Product slug is required');\r\n }\r\n\r\n return this.request<ApiResponse<Product>>('GET', `${this.baseUrl}/slug/${slug}`, {\r\n token: token || undefined,\r\n options: {\r\n cache: this.config.cache,\r\n ...options,\r\n },\r\n });\r\n }\r\n\r\n /**\r\n * Get product recommendations\r\n * GET /products/:id/recommendations\r\n * (Public endpoint)\r\n *\r\n * @param token - Auth token (optional)\r\n * @param productId - Product ID to get recommendations for\r\n * @param options - Additional fetch options\r\n * @returns List of recommended products\r\n */\r\n async getRecommendations({\r\n token = null,\r\n productId,\r\n options = {},\r\n }: {\r\n token?: string | null;\r\n productId: string;\r\n options?: FetchOptions;\r\n }): Promise<ApiResponse<Product[]>> {\r\n if (!productId) {\r\n throw new Error('Product ID is required');\r\n }\r\n\r\n return this.request<ApiResponse<Product[]>>('GET', `${this.baseUrl}/${productId}/recommendations`, {\r\n token: token || undefined,\r\n options: {\r\n cache: this.config.cache,\r\n ...options,\r\n },\r\n });\r\n }\r\n\r\n /**\r\n * Get soft-deleted products (Recycle Bin)\r\n * GET /products/deleted\r\n * (Admin only)\r\n *\r\n * @param token - Auth token (required)\r\n * @param params - Query parameters for pagination/filtering\r\n * @param options - Additional fetch options\r\n * @returns Paginated list of deleted products\r\n */\r\n async getDeleted({\r\n token,\r\n params = {},\r\n options = {},\r\n }: {\r\n token: string;\r\n params?: Record<string, unknown>;\r\n options?: FetchOptions;\r\n }): Promise<PaginatedResponse<Product>> {\r\n return this.request<PaginatedResponse<Product>>('GET', `${this.baseUrl}/deleted`, {\r\n token,\r\n params,\r\n options: {\r\n cache: this.config.cache,\r\n ...options,\r\n },\r\n });\r\n }\r\n\r\n /**\r\n * Restore a soft-deleted product\r\n * POST /products/:id/restore\r\n * (Admin only)\r\n *\r\n * @param token - Auth token (required)\r\n * @param id - Product ID to restore\r\n * @param options - Additional fetch options\r\n * @returns Restored product\r\n */\r\n async restore({\r\n token,\r\n id,\r\n options = {},\r\n }: {\r\n token: string;\r\n id: string;\r\n options?: FetchOptions;\r\n }): Promise<ApiResponse<Product>> {\r\n if (!id) {\r\n throw new Error('Product ID is required');\r\n }\r\n\r\n return this.request<ApiResponse<Product>>('POST', `${this.baseUrl}/${id}/restore`, {\r\n token,\r\n options,\r\n });\r\n }\r\n\r\n /**\r\n * Permanently delete a product (Hard delete)\r\n * DELETE /products/:id?hard=true\r\n * (Admin only - use with caution)\r\n *\r\n * @param token - Auth token (required)\r\n * @param id - Product ID to permanently delete\r\n * @param options - Additional fetch options\r\n * @returns Delete confirmation\r\n */\r\n async hardDelete({\r\n token,\r\n id,\r\n options = {},\r\n }: {\r\n token: string;\r\n id: string;\r\n options?: FetchOptions;\r\n }): Promise<ApiResponse<{ deleted: boolean }>> {\r\n if (!id) {\r\n throw new Error('Product ID is required');\r\n }\r\n\r\n return this.delete({\r\n token,\r\n id,\r\n options: {\r\n ...options,\r\n // @ts-ignore - params is handled internally\r\n params: { hard: 'true' },\r\n },\r\n });\r\n }\r\n\r\n /**\r\n * Sync product stock quantity\r\n * POST /products/:id/sync-stock\r\n *\r\n * Recomputes product.quantity by summing all StockEntry quantities across branches.\r\n * (Requires: admin, warehouse-admin, warehouse-staff, or store-manager role)\r\n *\r\n * @param token - Auth token (required)\r\n * @param id - Product ID to sync stock for\r\n * @param options - Additional fetch options\r\n * @returns Sync result with new quantity\r\n */\r\n async syncStock({\r\n token,\r\n id,\r\n options = {},\r\n }: {\r\n token: string;\r\n id: string;\r\n options?: FetchOptions;\r\n }): Promise<ProductSyncStockResponse> {\r\n if (!id) {\r\n throw new Error('Product ID is required');\r\n }\r\n\r\n return this.request<ProductSyncStockResponse>('POST', `${this.baseUrl}/${id}/sync-stock`, {\r\n token,\r\n options,\r\n });\r\n }\r\n}\r\n\r\n// Create and export a singleton instance\r\nexport const productApi = new ProductApi();\r\nexport { ProductApi };\r\n","/**\r\n * Category API Client\r\n *\r\n * **Authentication:**\r\n * - Public: List, Get, Tree, GetBySlug\r\n * - Admin: Create, Update, Delete\r\n *\r\n * **Base URL:** `/api/v1/categories`\r\n *\r\n * **Slug-Based Design:**\r\n * - Categories use slugs as identifiers (not ObjectIds)\r\n * - Products store category as slug string for fast queries\r\n * - Example: `db.products.find({ category: \"electronics\" })`\r\n */\r\n\r\nimport { BaseApi, type ApiResponse } from '../../core';\r\nimport type {\r\n Category,\r\n CategoryTreeNode,\r\n CreateCategoryPayload,\r\n UpdateCategoryPayload,\r\n CategoryTreeResponse,\r\n} from '../types';\r\n\r\ntype FetchOptions = {\r\n cache?: RequestCache;\r\n revalidate?: number;\r\n tags?: string[];\r\n};\r\n\r\n/**\r\n * Category API Client\r\n * Extends BaseApi with category-specific endpoints\r\n */\r\nclass CategoryApi extends BaseApi<Category, CreateCategoryPayload, UpdateCategoryPayload> {\r\n constructor(config = {}) {\r\n super('categories', config);\r\n }\r\n\r\n /**\r\n * Get category tree (nested structure)\r\n * GET /categories/tree\r\n *\r\n * **This is the main endpoint - FE should cache this and derive everything else from it.**\r\n *\r\n * Returns nested tree structure with children. Use helper functions to flatten, search, or extract children.\r\n *\r\n * @param token - Auth token (optional, public endpoint)\r\n * @param options - Additional fetch options\r\n * @returns Nested category tree\r\n *\r\n * @example\r\n * ```typescript\r\n * const { data } = await categoryApi.getTree({ token: null });\r\n * // data = [{ slug: \"clothing\", name: \"Clothing\", children: [...] }]\r\n * ```\r\n */\r\n async getTree({\r\n token = null,\r\n options = {},\r\n }: {\r\n token?: string | null;\r\n options?: FetchOptions;\r\n } = {}): Promise<CategoryTreeResponse> {\r\n return this.request<CategoryTreeResponse>('GET', `${this.baseUrl}/tree`, {\r\n token: token || undefined,\r\n options: {\r\n cache: this.config.cache,\r\n ...options,\r\n },\r\n });\r\n }\r\n\r\n /**\r\n * Get category by slug\r\n * GET /categories/slug/:slug\r\n *\r\n * For URL resolution when you need full category details.\r\n *\r\n * @param token - Auth token (optional, public endpoint)\r\n * @param slug - Category slug (e.g., \"electronics\", \"t-shirts\")\r\n * @param options - Additional fetch options\r\n * @returns Category object\r\n *\r\n * @example\r\n * ```typescript\r\n * const { data } = await categoryApi.getBySlug({\r\n * token: null,\r\n * slug: 'electronics'\r\n * });\r\n * ```\r\n */\r\n async getBySlug({\r\n token = null,\r\n slug,\r\n options = {},\r\n }: {\r\n token?: string | null;\r\n slug: string;\r\n options?: FetchOptions;\r\n }): Promise<ApiResponse<Category>> {\r\n if (!slug) {\r\n throw new Error('Category slug is required');\r\n }\r\n\r\n return this.request<ApiResponse<Category>>('GET', `${this.baseUrl}/slug/${slug}`, {\r\n token: token || undefined,\r\n options: {\r\n cache: this.config.cache,\r\n ...options,\r\n },\r\n });\r\n }\r\n\r\n /**\r\n * Sync product counts for all categories\r\n * POST /categories/sync-product-count\r\n *\r\n * Recalculates `productCount` for all categories based on current products.\r\n * Use when manual data fixes or migrations may have desynced counts.\r\n *\r\n * @param token - Auth token (admin or inventory staff required)\r\n * @param options - Additional fetch options\r\n * @returns Number of categories updated\r\n *\r\n * @example\r\n * ```typescript\r\n * const { data } = await categoryApi.syncProductCount({ token });\r\n * // data = { updated: 42 }\r\n * ```\r\n */\r\n async syncProductCount({\r\n token,\r\n options = {},\r\n }: {\r\n token: string;\r\n options?: FetchOptions;\r\n }): Promise<ApiResponse<{ updated: number }>> {\r\n return this.request<ApiResponse<{ updated: number }>>('POST', `${this.baseUrl}/sync-product-count`, {\r\n token,\r\n options,\r\n });\r\n }\r\n}\r\n\r\n// Create and export a singleton instance\r\nexport const categoryApi = new CategoryApi();\r\nexport { CategoryApi };\r\n","/**\r\n * Size Guide API Client\r\n *\r\n * **Authentication:**\r\n * - Public: List, Get, GetBySlug\r\n * - Admin: Create, Update, Delete\r\n *\r\n * **Base URL:** `/api/v1/size-guides`\r\n *\r\n * **Slug-Based Design:**\r\n * - Size guides use slugs as identifiers\r\n * - Products store `sizeGuideSlug` to reference a size guide\r\n */\r\n\r\nimport { BaseApi, type ApiResponse } from '../../core';\r\nimport type {\r\n SizeGuide,\r\n CreateSizeGuidePayload,\r\n UpdateSizeGuidePayload,\r\n} from '../types';\r\n\r\ntype FetchOptions = {\r\n cache?: RequestCache;\r\n revalidate?: number;\r\n tags?: string[];\r\n};\r\n\r\n/**\r\n * Size Guide API Client\r\n * Extends BaseApi with size-guide-specific endpoints\r\n */\r\nclass SizeGuideApi extends BaseApi<SizeGuide, CreateSizeGuidePayload, UpdateSizeGuidePayload> {\r\n constructor(config = {}) {\r\n super('size-guides', config);\r\n }\r\n\r\n /**\r\n * Get size guide by slug\r\n * GET /size-guides/slug/:slug\r\n *\r\n * For product detail pages to fetch the appropriate size guide.\r\n *\r\n * @param token - Auth token (optional, public endpoint)\r\n * @param slug - Size guide slug (e.g., \"t-shirts-tops\")\r\n * @param options - Additional fetch options\r\n * @returns Size guide object\r\n *\r\n * @example\r\n * ```typescript\r\n * const { data } = await sizeGuideApi.getBySlug({\r\n * token: null,\r\n * slug: 't-shirts-tops'\r\n * });\r\n * ```\r\n */\r\n async getBySlug({\r\n token = null,\r\n slug,\r\n options = {},\r\n }: {\r\n token?: string | null;\r\n slug: string;\r\n options?: FetchOptions;\r\n }): Promise<ApiResponse<SizeGuide>> {\r\n if (!slug) {\r\n throw new Error('Size guide slug is required');\r\n }\r\n\r\n return this.request<ApiResponse<SizeGuide>>('GET', `${this.baseUrl}/slug/${slug}`, {\r\n token: token || undefined,\r\n options: {\r\n cache: this.config.cache,\r\n ...options,\r\n },\r\n });\r\n }\r\n}\r\n\r\n// Create and export a singleton instance\r\nexport const sizeGuideApi = new SizeGuideApi();\r\nexport { SizeGuideApi };\r\n","/**\n * Review API Client\n *\n * **Authentication:**\n * - Public: List, Get\n * - User/Admin: Create, Update, Get My Review\n * - Admin: Delete\n *\n * **Base URL:** `/api/v1/reviews`\n */\n\nimport { BaseApi, type ApiResponse } from \"../../core\";\nimport type {\n Review,\n CreateReviewPayload,\n UpdateReviewPayload,\n} from \"../types\";\n\ntype FetchOptions = {\n cache?: RequestCache;\n revalidate?: number;\n tags?: string[];\n};\n\nclass ReviewApi extends BaseApi<Review, CreateReviewPayload, UpdateReviewPayload> {\n constructor(config = {}) {\n super(\"reviews\", config);\n }\n\n /**\n * Get current user's review for a product\n * GET /reviews/my/:productId\n *\n * @param token - Auth token (required)\n * @param productId - Product ID\n * @param options - Additional fetch options\n * @returns Review or null\n */\n async getMyReview({\n token,\n productId,\n options = {},\n }: {\n token: string;\n productId: string;\n options?: FetchOptions;\n }): Promise<ApiResponse<Review | null>> {\n if (!productId) {\n throw new Error(\"Product ID is required\");\n }\n\n return this.request<ApiResponse<Review | null>>(\"GET\", `${this.baseUrl}/my/${productId}`, {\n token,\n options: {\n cache: this.config.cache,\n ...options,\n },\n });\n }\n}\n\nexport const reviewApi = new ReviewApi();\nexport { ReviewApi };\n","\"use client\";\n\n/**\n * Product Hooks\n *\n * Pre-built hooks for product CRUD operations with:\n * - Optimistic updates\n * - Smart caching\n * - Type safety\n */\n\nimport { useQuery, useMutation, useQueryClient, type UseQueryOptions } from \"@tanstack/react-query\";\nimport { createCrudHooks, type CrudApi, getToastHandler } from \"../../core/react\";\nimport { productApi } from \"../api\";\nimport type {\n Product,\n CreateProductPayload,\n UpdateProductPayload,\n ProductSyncStockResponse,\n} from \"../types\";\nimport type { ApiResponse, PaginatedResponse } from \"../../core\";\n\n// Type helper for API compatibility\ntype AnyApi = CrudApi<any, any, any>;\n\n// ============================================\n// CRUD Hooks (Factory-generated)\n// ============================================\n\n/**\n * Product CRUD hooks with optimistic updates\n */\nexport const productHooks = createCrudHooks<Product, CreateProductPayload, UpdateProductPayload>({\n api: productApi as AnyApi,\n entityKey: \"products\",\n singular: \"Product\",\n plural: \"Products\",\n defaults: {\n staleTime: 5 * 60 * 1000, // 5 minutes\n },\n});\n\nexport const {\n KEYS: PRODUCT_KEYS,\n useList: useProducts,\n useDetail: useProductDetail,\n useActions: useProductActions,\n useNavigation: useProductNavigation,\n} = productHooks;\n\n// ============================================\n// Custom Product Hooks\n// ============================================\n\n/**\n * Hook to get product by slug\n *\n * @param token - Auth token (optional for public access)\n * @param slug - Product slug\n * @param options - React Query options\n * @returns Query result with product data\n *\n * @example\n * ```tsx\n * function ProductPage({ slug }) {\n * const { data, isLoading } = useProductBySlug(null, slug);\n *\n * if (isLoading) return <Spinner />;\n *\n * return <h1>{data?.data?.name}</h1>;\n * }\n * ```\n */\nexport function useProductBySlug(\n token: string | null | undefined,\n slug: string,\n options: Omit<UseQueryOptions<ApiResponse<Product>>, \"queryKey\" | \"queryFn\"> = {}\n) {\n return useQuery<ApiResponse<Product>>({\n queryKey: [...PRODUCT_KEYS.all, \"slug\", slug],\n queryFn: () => productApi.getBySlug({ token, slug }),\n enabled: !!slug,\n staleTime: 5 * 60 * 1000, // 5 minutes\n ...options,\n });\n}\n\nexport interface UseProductRecommendationsReturn {\n recommendations: Product[];\n isLoading: boolean;\n error: Error | null;\n}\n\n/**\n * Hook to get product recommendations\n *\n * @param productId - Product ID to get recommendations for\n * @param options - React Query options\n * @returns Object with recommendations array, isLoading, and error\n *\n * @example\n * ```tsx\n * function ProductRecommendations({ productId }) {\n * const { recommendations, isLoading } = useProductRecommendations(productId);\n *\n * if (isLoading) return <Spinner />;\n *\n * return (\n * <div>\n * {recommendations.map(product => (\n * <ProductCard key={product._id} product={product} />\n * ))}\n * </div>\n * );\n * }\n * ```\n */\nexport function useProductRecommendations(\n productId: string,\n options: Omit<UseQueryOptions<ApiResponse<Product[]>>, \"queryKey\" | \"queryFn\"> = {}\n): UseProductRecommendationsReturn {\n const { data, isLoading, error } = useQuery<ApiResponse<Product[]>>({\n queryKey: [...PRODUCT_KEYS.all, \"recommendations\", productId],\n queryFn: () => productApi.getRecommendations({ token: null, productId }),\n enabled: !!productId,\n staleTime: 10 * 60 * 1000, // 10 minutes\n ...options,\n });\n\n return {\n recommendations: data?.data ?? [],\n isLoading,\n error: error as Error | null,\n };\n}\n\n/**\n * Hook to get soft-deleted products (Recycle Bin)\n *\n * @param token - Auth token (required, admin only)\n * @param params - Query parameters for pagination/filtering\n * @param options - React Query options\n * @returns Query result with deleted products\n *\n * @example\n * ```tsx\n * function RecycleBin() {\n * const { data, isLoading } = useDeletedProducts(token, { page: 1, limit: 20 });\n *\n * if (isLoading) return <Spinner />;\n *\n * return (\n * <div>\n * {data?.docs?.map(product => (\n * <DeletedProductRow key={product._id} product={product} />\n * ))}\n * </div>\n * );\n * }\n * ```\n */\nexport function useDeletedProducts(\n token: string,\n params: Record<string, unknown> = {},\n options: Omit<UseQueryOptions<PaginatedResponse<Product>>, \"queryKey\" | \"queryFn\"> = {}\n) {\n return useQuery<PaginatedResponse<Product>>({\n queryKey: [...PRODUCT_KEYS.all, \"deleted\", params],\n queryFn: () => productApi.getDeleted({ token, params }),\n enabled: !!token,\n staleTime: 2 * 60 * 1000, // 2 minutes\n ...options,\n });\n}\n\n/**\n * Hook to restore a soft-deleted product\n *\n * @param token - Auth token (required, admin only)\n * @returns Mutation result with restore function\n *\n * @example\n * ```tsx\n * function RestoreButton({ productId }) {\n * const { mutate: restore, isPending } = useRestoreProduct(token);\n *\n * return (\n * <Button onClick={() => restore(productId)} disabled={isPending}>\n * Restore Product\n * </Button>\n * );\n * }\n * ```\n */\nexport function useRestoreProduct(token: string) {\n const queryClient = useQueryClient();\n const toast = getToastHandler();\n\n return useMutation({\n mutationFn: (id: string) => productApi.restore({ token, id }),\n onSuccess: () => {\n toast.success(\"Product restored successfully\");\n // Invalidate both deleted and main product lists\n queryClient.invalidateQueries({ queryKey: [...PRODUCT_KEYS.all, \"deleted\"] });\n queryClient.invalidateQueries({ queryKey: PRODUCT_KEYS.lists() });\n },\n onError: (error: Error) => {\n toast.error(error.message || \"Failed to restore product\");\n },\n });\n}\n\n/**\n * Hook to permanently delete a product (Hard delete)\n *\n * @param token - Auth token (required, admin only)\n * @returns Mutation result with hard delete function\n *\n * @example\n * ```tsx\n * function PermanentDeleteButton({ productId }) {\n * const { mutate: hardDelete, isPending } = useHardDeleteProduct(token);\n *\n * return (\n * <Button\n * variant=\"destructive\"\n * onClick={() => hardDelete(productId)}\n * disabled={isPending}\n * >\n * Permanently Delete\n * </Button>\n * );\n * }\n * ```\n */\nexport function useHardDeleteProduct(token: string) {\n const queryClient = useQueryClient();\n const toast = getToastHandler();\n\n return useMutation({\n mutationFn: (id: string) => productApi.hardDelete({ token, id }),\n onSuccess: () => {\n toast.success(\"Product permanently deleted\");\n // Invalidate deleted products list\n queryClient.invalidateQueries({ queryKey: [...PRODUCT_KEYS.all, \"deleted\"] });\n },\n onError: (error: Error) => {\n toast.error(error.message || \"Failed to permanently delete product\");\n },\n });\n}\n\n/**\n * Hook to sync product stock quantity\n *\n * Recomputes product.quantity by summing all StockEntry quantities across branches.\n *\n * @param token - Auth token (requires: admin, warehouse-admin, warehouse-staff, or store-manager role)\n * @returns Mutation result with sync function\n *\n * @example\n * ```tsx\n * function SyncStockButton({ productId }) {\n * const { mutate: syncStock, isPending } = useSyncProductStock(token);\n *\n * return (\n * <Button onClick={() => syncStock(productId)} disabled={isPending}>\n * Sync Stock\n * </Button>\n * );\n * }\n * ```\n */\nexport function useSyncProductStock(token: string) {\n const queryClient = useQueryClient();\n const toast = getToastHandler();\n\n return useMutation<ProductSyncStockResponse, Error, string>({\n mutationFn: (id: string) => productApi.syncStock({ token, id }),\n onSuccess: (result, id) => {\n toast.success(`Stock synced: ${result.totalQuantity} units`);\n // Invalidate product detail to refresh quantity\n queryClient.invalidateQueries({ queryKey: PRODUCT_KEYS.detail(id) });\n queryClient.invalidateQueries({ queryKey: PRODUCT_KEYS.lists() });\n },\n onError: (error: Error) => {\n toast.error(error.message || \"Failed to sync stock\");\n },\n });\n}\n","\"use client\";\n\n/**\n * Category Hooks\n *\n * Pre-built hooks for category CRUD operations with:\n * - Category tree support\n * - Optimistic updates\n * - Smart caching\n * - Type safety\n */\n\nimport { useQuery, useMutation, useQueryClient, type UseQueryOptions } from \"@tanstack/react-query\";\nimport { createCrudHooks, type CrudApi, getToastHandler } from \"../../core/react\";\nimport { categoryApi } from \"../api\";\nimport type {\n Category,\n CategoryTreeNode,\n CreateCategoryPayload,\n UpdateCategoryPayload,\n CategoryTreeResponse,\n} from \"../types\";\nimport type { ApiResponse } from \"../../core\";\n\n// Type helper for API compatibility\ntype AnyApi = CrudApi<any, any, any>;\n\n// ============================================\n// Types\n// ============================================\n\ninterface FlattenedNode extends CategoryTreeNode {\n depth: number;\n displayName: string;\n}\n\ninterface SelectOption {\n value: string;\n label: string;\n}\n\n// ============================================\n// CRUD Hooks (Factory-generated)\n// ============================================\n\n/**\n * Category CRUD hooks\n */\nexport const categoryHooks = createCrudHooks<Category, CreateCategoryPayload, UpdateCategoryPayload>({\n api: categoryApi as AnyApi,\n entityKey: \"categories\",\n singular: \"Category\",\n plural: \"Categories\",\n defaults: {\n staleTime: 10 * 60 * 1000, // 10 minutes\n },\n});\n\nexport const {\n KEYS: CATEGORY_KEYS,\n useList: useCategories,\n useDetail: useCategoryDetail,\n useActions: useCategoryActions,\n useNavigation: useCategoryNavigation,\n} = categoryHooks;\n\n// ============================================\n// Custom Category Hooks\n// ============================================\n\n/**\n * Hook to get category tree (nested structure)\n * FE should cache this and derive everything else from it\n *\n * @param token - Auth token (optional for public access)\n * @param options - React Query options\n * @returns Query result with tree data\n *\n * @example\n * ```tsx\n * function CategoryNav() {\n * const { data, isLoading } = useCategoryTree(token);\n *\n * if (isLoading) return <Spinner />;\n *\n * return (\n * <nav>\n * {data?.data?.map(category => (\n * <CategoryItem key={category.slug} category={category} />\n * ))}\n * </nav>\n * );\n * }\n * ```\n */\nexport function useCategoryTree(\n token?: string | null,\n options: Omit<UseQueryOptions<CategoryTreeResponse>, \"queryKey\" | \"queryFn\"> = {}\n) {\n return useQuery<CategoryTreeResponse>({\n queryKey: [...CATEGORY_KEYS.all, \"tree\"],\n queryFn: () => categoryApi.getTree({ token }),\n staleTime: 30 * 60 * 1000, // 30 minutes (categories rarely change)\n gcTime: 60 * 60 * 1000, // 60 minutes\n ...options,\n });\n}\n\n/**\n * Hook to get category by slug\n *\n * @param token - Auth token (optional for public access)\n * @param slug - Category slug\n * @param options - React Query options\n * @returns Query result with category data\n *\n * @example\n * ```tsx\n * function CategoryPage({ slug }) {\n * const { data, isLoading } = useCategoryBySlug(token, slug);\n *\n * if (isLoading) return <Spinner />;\n *\n * return <h1>{data?.data?.name}</h1>;\n * }\n * ```\n */\nexport function useCategoryBySlug(\n token: string | null | undefined,\n slug: string,\n options: Omit<UseQueryOptions<ApiResponse<Category>>, \"queryKey\" | \"queryFn\"> = {}\n) {\n return useQuery<ApiResponse<Category>>({\n queryKey: [...CATEGORY_KEYS.all, \"slug\", slug],\n queryFn: () => categoryApi.getBySlug({ token, slug }),\n enabled: !!slug,\n staleTime: 30 * 60 * 1000, // 30 minutes\n ...options,\n });\n}\n\n/**\n * Hook to sync product counts for all categories\n * POST /categories/sync-product-count\n *\n * Use when manual data fixes or migrations may have desynced counts.\n *\n * @param token - Auth token (admin or inventory staff required)\n * @returns Mutation result with sync function\n *\n * @example\n * ```tsx\n * function AdminPanel() {\n * const { mutate: sync, isPending } = useCategorySyncProductCount(token);\n *\n * return (\n * <Button onClick={() => sync()} disabled={isPending}>\n * Sync Product Counts\n * </Button>\n * );\n * }\n * ```\n */\nexport function useCategorySyncProductCount(token: string) {\n const queryClient = useQueryClient();\n const toast = getToastHandler();\n\n return useMutation({\n mutationFn: () => categoryApi.syncProductCount({ token }),\n onSuccess: (result) => {\n const count = result?.data?.updated ?? 0;\n toast.success(`Synced product counts for ${count} categories`);\n // Invalidate category queries to refresh counts\n queryClient.invalidateQueries({ queryKey: CATEGORY_KEYS.all });\n },\n onError: (error: Error) => {\n toast.error(error.message || \"Failed to sync product counts\");\n },\n });\n}\n\n// ============================================\n// Helper Functions\n// ============================================\n\n/**\n * Flatten category tree with depth indicator\n * Useful for building hierarchical selects\n *\n * @param nodes - Category tree nodes\n * @param depth - Current depth (used recursively)\n * @param result - Accumulator array (used recursively)\n * @returns Flattened array with depth and displayName\n *\n * @example\n * ```typescript\n * const { data } = useCategoryTree(token);\n * const flat = flattenCategoryTree(data?.data);\n * // flat = [\n * // { slug: 'clothing', displayName: 'Clothing', depth: 0, ... },\n * // { slug: 't-shirts', displayName: ' T-Shirts', depth: 1, ... },\n * // ]\n * ```\n */\nexport function flattenCategoryTree(\n nodes: CategoryTreeNode[] | undefined,\n depth = 0,\n result: FlattenedNode[] = []\n): FlattenedNode[] {\n for (const node of nodes || []) {\n result.push({\n ...node,\n depth,\n displayName: \"\\u00A0\\u00A0\".repeat(depth) + node.name,\n });\n if (node.children?.length) {\n flattenCategoryTree(node.children, depth + 1, result);\n }\n }\n return result;\n}\n\n/**\n * Build parent category options for select (root categories only)\n *\n * @param tree - Category tree from useCategoryTree\n * @returns Options array with value/label for select inputs\n *\n * @example\n * ```tsx\n * function ParentSelect() {\n * const { data } = useCategoryTree(token);\n * const options = getParentCategoryOptions(data?.data);\n *\n * return (\n * <Select>\n * {options.map(opt => (\n * <SelectItem key={opt.value} value={opt.value}>\n * {opt.label}\n * </SelectItem>\n * ))}\n * </Select>\n * );\n * }\n * ```\n */\nexport function getParentCategoryOptions(tree: CategoryTreeNode[] | undefined): SelectOption[] {\n return (tree || []).map((node) => ({\n value: node.slug,\n label: node.name,\n }));\n}\n\n/**\n * Build all category options for select (flattened with hierarchy)\n *\n * @param tree - Category tree from useCategoryTree\n * @returns Options array with value/label showing hierarchy\n *\n * @example\n * ```tsx\n * function CategorySelect() {\n * const { data } = useCategoryTree(token);\n * const options = getAllCategoryOptions(data?.data);\n *\n * return (\n * <Select>\n * {options.map(opt => (\n * <SelectItem key={opt.value} value={opt.value}>\n * {opt.label}\n * </SelectItem>\n * ))}\n * </Select>\n * );\n * }\n * ```\n */\nexport function getAllCategoryOptions(tree: CategoryTreeNode[] | undefined): SelectOption[] {\n return flattenCategoryTree(tree).map((node) => ({\n value: node.slug,\n label: node.displayName,\n }));\n}\n\n/**\n * Find a category in the tree by slug\n *\n * @param tree - Category tree nodes\n * @param slug - Category slug to find\n * @returns Category node or undefined\n */\nexport function findCategoryBySlug(\n tree: CategoryTreeNode[] | undefined,\n slug: string\n): CategoryTreeNode | undefined {\n if (!tree || !slug) return undefined;\n\n for (const node of tree) {\n if (node.slug === slug) return node;\n if (node.children?.length) {\n const found = findCategoryBySlug(node.children, slug);\n if (found) return found;\n }\n }\n return undefined;\n}\n\n/**\n * Get breadcrumb path for a category\n *\n * @param tree - Category tree nodes\n * @param slug - Category slug\n * @returns Array of categories from root to target\n */\nexport function getCategoryBreadcrumb(\n tree: CategoryTreeNode[] | undefined,\n slug: string\n): CategoryTreeNode[] {\n if (!tree || !slug) return [];\n\n function findPath(\n nodes: CategoryTreeNode[],\n target: string,\n path: CategoryTreeNode[] = []\n ): CategoryTreeNode[] | null {\n for (const node of nodes) {\n const currentPath = [...path, node];\n if (node.slug === target) return currentPath;\n if (node.children?.length) {\n const found = findPath(node.children, target, currentPath);\n if (found) return found;\n }\n }\n return null;\n }\n\n return findPath(tree, slug) || [];\n}\n\n/**\n * Get all children slugs for a category (recursive)\n *\n * @param tree - Category tree nodes\n * @param parentSlug - Parent category slug\n * @returns Array of child category slugs\n */\nexport function getChildCategorySlugs(\n tree: CategoryTreeNode[] | undefined,\n parentSlug: string\n): string[] {\n const parent = findCategoryBySlug(tree, parentSlug);\n if (!parent?.children?.length) return [];\n\n const slugs: string[] = [];\n\n function collectSlugs(nodes: CategoryTreeNode[]) {\n for (const node of nodes) {\n slugs.push(node.slug);\n if (node.children?.length) {\n collectSlugs(node.children);\n }\n }\n }\n\n collectSlugs(parent.children);\n return slugs;\n}\n\n/**\n * Get root categories only\n *\n * @param tree - Category tree nodes\n * @returns Array of root category nodes\n */\nexport function getRootCategories(tree: CategoryTreeNode[] | undefined): CategoryTreeNode[] {\n return tree || [];\n}\n","\"use client\";\n\n/**\n * Size Guide Hooks\n *\n * Pre-built hooks for size guide CRUD operations with:\n * - Optimistic updates\n * - Smart caching\n * - Type safety\n */\n\nimport { useQuery, type UseQueryOptions } from \"@tanstack/react-query\";\nimport { createCrudHooks, type CrudApi } from \"../../core/react\";\nimport { sizeGuideApi } from \"../api\";\nimport type {\n SizeGuide,\n CreateSizeGuidePayload,\n UpdateSizeGuidePayload,\n} from \"../types\";\nimport type { ApiResponse } from \"../../core\";\n\n// Type helper for API compatibility\ntype AnyApi = CrudApi<any, any, any>;\n\n// ============================================\n// CRUD Hooks (Factory-generated)\n// ============================================\n\n/**\n * Size Guide CRUD hooks\n */\nexport const sizeGuideHooks = createCrudHooks<SizeGuide, CreateSizeGuidePayload, UpdateSizeGuidePayload>({\n api: sizeGuideApi as AnyApi,\n entityKey: \"size-guides\",\n singular: \"Size Guide\",\n plural: \"Size Guides\",\n defaults: {\n staleTime: 30 * 60 * 1000, // 30 minutes (size guides change rarely)\n },\n});\n\nexport const {\n KEYS: SIZE_GUIDE_KEYS,\n useList: useSizeGuides,\n useDetail: useSizeGuideDetail,\n useActions: useSizeGuideActions,\n useNavigation: useSizeGuideNavigation,\n} = sizeGuideHooks;\n\n// ============================================\n// Custom Size Guide Hooks\n// ============================================\n\n/**\n * Hook to get size guide by slug\n *\n * @param token - Auth token (optional for public access)\n * @param slug - Size guide slug\n * @param options - React Query options\n * @returns Query result with size guide data\n *\n * @example\n * ```tsx\n * function SizeGuideDisplay({ slug }) {\n * const { data, isLoading } = useSizeGuideBySlug(null, slug);\n *\n * if (isLoading) return <Spinner />;\n *\n * return (\n * <div>\n * <h2>{data?.data?.name}</h2>\n * <SizeTable guide={data?.data} />\n * </div>\n * );\n * }\n * ```\n */\nexport function useSizeGuideBySlug(\n token: string | null | undefined,\n slug: string,\n options: Omit<UseQueryOptions<ApiResponse<SizeGuide>>, \"queryKey\" | \"queryFn\"> = {}\n) {\n return useQuery<ApiResponse<SizeGuide>>({\n queryKey: [...SIZE_GUIDE_KEYS.all, \"slug\", slug],\n queryFn: () => sizeGuideApi.getBySlug({ token, slug }),\n enabled: !!slug,\n staleTime: 30 * 60 * 1000, // 30 minutes\n ...options,\n });\n}\n\n// ============================================\n// Helper Functions\n// ============================================\n\n/**\n * Format size guide as select options\n *\n * @param sizeGuides - Array of size guides\n * @returns Options array with value/label for select inputs\n *\n * @example\n * ```tsx\n * function SizeGuideSelect() {\n * const { data } = useSizeGuides(token);\n * const options = getSizeGuideOptions(data?.docs);\n *\n * return (\n * <Select>\n * {options.map(opt => (\n * <SelectItem key={opt.value} value={opt.value}>\n * {opt.label}\n * </SelectItem>\n * ))}\n * </Select>\n * );\n * }\n * ```\n */\nexport function getSizeGuideOptions(sizeGuides: SizeGuide[] | undefined): { value: string; label: string }[] {\n return (sizeGuides || []).map((guide) => ({\n value: guide._id,\n label: guide.name,\n }));\n}\n\n/**\n * Get size guide by ID from a list\n *\n * @param sizeGuides - Array of size guides\n * @param id - Size guide ID\n * @returns Size guide or undefined\n */\nexport function findSizeGuideById(\n sizeGuides: SizeGuide[] | undefined,\n id: string\n): SizeGuide | undefined {\n return sizeGuides?.find((guide) => guide._id === id);\n}\n\n/**\n * Get size guide by slug from a list\n *\n * @param sizeGuides - Array of size guides\n * @param slug - Size guide slug\n * @returns Size guide or undefined\n */\nexport function findSizeGuideBySlug(\n sizeGuides: SizeGuide[] | undefined,\n slug: string\n): SizeGuide | undefined {\n return sizeGuides?.find((guide) => guide.slug === slug);\n}\n\n/**\n * Format measurement value with unit\n *\n * @param value - Measurement value\n * @param unit - Measurement unit ('inches' or 'cm')\n * @returns Formatted measurement string\n *\n * @example\n * ```typescript\n * formatMeasurement(\"34-36\", \"inches\") // \"34-36 in\"\n * formatMeasurement(\"88\", \"cm\") // \"88 cm\"\n * ```\n */\nexport function formatMeasurement(value: string, unit: 'inches' | 'cm'): string {\n const unitLabel = unit === 'inches' ? 'in' : 'cm';\n return `${value} ${unitLabel}`;\n}\n\n/**\n * Get measurement labels as table headers\n *\n * @param guide - Size guide object\n * @returns Array of header labels including \"Size\" as first column\n *\n * @example\n * ```typescript\n * const headers = getSizeTableHeaders(sizeGuide);\n * // [\"Size\", \"Chest\", \"Length\", \"Shoulder\"]\n * ```\n */\nexport function getSizeTableHeaders(guide: SizeGuide | undefined): string[] {\n if (!guide?.measurementLabels) return [\"Size\"];\n return [\"Size\", ...guide.measurementLabels];\n}\n\n/**\n * Get size table rows\n *\n * @param guide - Size guide object\n * @returns Array of row data with size name and measurements\n *\n * @example\n * ```typescript\n * const rows = getSizeTableRows(sizeGuide);\n * // [\n * // { name: \"S\", measurements: { chest: \"34-36\", length: \"28\" } },\n * // { name: \"M\", measurements: { chest: \"38-40\", length: \"29\" } },\n * // ]\n * ```\n */\nexport function getSizeTableRows(guide: SizeGuide | undefined): Array<{\n name: string;\n measurements: Record<string, string>;\n}> {\n if (!guide?.sizes) return [];\n return guide.sizes.map((size) => ({\n name: size.name,\n measurements: size.measurements,\n }));\n}\n","\"use client\";\n\n/**\n * Review Hooks\n *\n * CRUD hooks + current user's review helper.\n */\n\nimport { useQuery, type UseQueryOptions } from \"@tanstack/react-query\";\nimport { createCrudHooks, type CrudApi } from \"../../core/react\";\nimport { reviewApi } from \"../api\";\nimport type {\n Review,\n CreateReviewPayload,\n UpdateReviewPayload,\n ReviewResponse,\n} from \"../types\";\n\n// Type helper for API compatibility\ntype AnyApi = CrudApi<any, any, any>;\n\n// ============================================\n// CRUD Hooks (Factory-generated)\n// ============================================\n\nexport const reviewHooks = createCrudHooks<Review, CreateReviewPayload, UpdateReviewPayload>({\n api: reviewApi as AnyApi,\n entityKey: \"reviews\",\n singular: \"Review\",\n plural: \"Reviews\",\n defaults: {\n staleTime: 5 * 60 * 1000, // 5 minutes\n },\n});\n\nexport const {\n KEYS: REVIEW_KEYS,\n useList: useReviews,\n useDetail: useReviewDetail,\n useActions: useReviewActions,\n useNavigation: useReviewNavigation,\n} = reviewHooks;\n\n// ============================================\n// Custom Hooks\n// ============================================\n\nexport function useMyReview(\n token: string | null | undefined,\n productId: string | null | undefined,\n options: Omit<UseQueryOptions<ReviewResponse>, \"queryKey\" | \"queryFn\"> = {}\n) {\n return useQuery<ReviewResponse>({\n queryKey: [...REVIEW_KEYS.all, \"my\", productId],\n queryFn: () => reviewApi.getMyReview({ token: token as string, productId: productId as string }),\n enabled: Boolean(token && productId),\n ...options,\n });\n}\n"]}
@@ -0,0 +1,198 @@
1
+ // src/core/api-handler.ts
2
+ var ApiError = class _ApiError extends Error {
3
+ constructor(options) {
4
+ super(options.message);
5
+ this.name = "ApiError";
6
+ this.status = options.status;
7
+ this.statusText = options.statusText;
8
+ this.body = options.body;
9
+ this.endpoint = options.endpoint;
10
+ this.method = options.method;
11
+ if (Error.captureStackTrace) {
12
+ Error.captureStackTrace(this, _ApiError);
13
+ }
14
+ }
15
+ /** Check if error is a client error (4xx) */
16
+ isClientError() {
17
+ return this.status >= 400 && this.status < 500;
18
+ }
19
+ /** Check if error is a server error (5xx) */
20
+ isServerError() {
21
+ return this.status >= 500;
22
+ }
23
+ /** Returns detailed string for logging */
24
+ toDetailedString() {
25
+ const bodyStr = typeof this.body === "object" ? JSON.stringify(this.body, null, 2) : String(this.body ?? "");
26
+ return [
27
+ `ApiError: ${this.message}`,
28
+ ` Status: ${this.status} ${this.statusText}`,
29
+ ` Endpoint: ${this.method} ${this.endpoint}`,
30
+ bodyStr ? ` Body: ${bodyStr}` : null
31
+ ].filter(Boolean).join("\n");
32
+ }
33
+ };
34
+ var sdkConfig = null;
35
+ var sdkConfigProvider = null;
36
+ function getActiveSDKConfig() {
37
+ return sdkConfigProvider?.() ?? sdkConfig;
38
+ }
39
+ function setSDKConfigProvider(provider) {
40
+ sdkConfigProvider = provider;
41
+ }
42
+ function configureSDK(config) {
43
+ sdkConfig = config;
44
+ }
45
+ function getSDKConfig() {
46
+ return getActiveSDKConfig();
47
+ }
48
+ function getBaseUrl() {
49
+ const config = getActiveSDKConfig();
50
+ if (!config?.baseUrl) {
51
+ throw new Error(
52
+ "SDK not configured. Call configureSDK({ baseUrl: '...' }) before making API requests."
53
+ );
54
+ }
55
+ return config.baseUrl;
56
+ }
57
+ async function handleApiRequest(method, endpoint, options = {}, debug = false) {
58
+ const BASE_URL = getBaseUrl();
59
+ const activeConfig = getActiveSDKConfig();
60
+ const {
61
+ body,
62
+ token: optionToken,
63
+ organizationId: optionOrgId,
64
+ revalidate,
65
+ headerOptions,
66
+ tags,
67
+ cache,
68
+ credentials: optionCredentials
69
+ } = options;
70
+ const token = optionToken ?? await activeConfig?.getToken?.() ?? null;
71
+ const organizationId = optionOrgId ?? activeConfig?.organizationId ?? null;
72
+ try {
73
+ let headers = {
74
+ ...activeConfig?.headers || {},
75
+ ...token && { Authorization: `Bearer ${token}` },
76
+ ...organizationId && { "x-organization-id": organizationId }
77
+ };
78
+ if (!(body instanceof FormData)) {
79
+ headers["Content-Type"] = "application/json";
80
+ }
81
+ if (headerOptions) {
82
+ headers = { ...headers, ...headerOptions };
83
+ }
84
+ const credentials = optionCredentials ?? activeConfig?.credentials ?? "include";
85
+ const fetchOptions = {
86
+ method,
87
+ headers,
88
+ credentials
89
+ };
90
+ if (body !== void 0 && body !== null) {
91
+ fetchOptions.body = body instanceof FormData ? body : JSON.stringify(body);
92
+ }
93
+ if (cache || activeConfig?.cache) {
94
+ fetchOptions.cache = cache ?? activeConfig?.cache;
95
+ }
96
+ if (revalidate !== void 0) {
97
+ fetchOptions.next = {
98
+ ...fetchOptions.next,
99
+ revalidate
100
+ };
101
+ }
102
+ if (tags) {
103
+ fetchOptions.next = {
104
+ ...fetchOptions.next,
105
+ tags
106
+ };
107
+ }
108
+ const response = await fetch(`${BASE_URL}${endpoint}`, fetchOptions);
109
+ if (!response.ok) {
110
+ let errorBody = null;
111
+ let errorMessage = response.statusText;
112
+ const contentType2 = response.headers.get("Content-Type");
113
+ try {
114
+ if (contentType2?.includes("application/json")) {
115
+ errorBody = await response.json();
116
+ errorMessage = errorBody?.message || errorBody?.error || response.statusText;
117
+ } else {
118
+ errorBody = await response.text();
119
+ if (!response.statusText && typeof errorBody === "string") {
120
+ errorMessage = errorBody.slice(0, 200);
121
+ }
122
+ }
123
+ } catch {
124
+ errorBody = null;
125
+ }
126
+ throw new ApiError({
127
+ message: errorMessage,
128
+ status: response.status,
129
+ statusText: response.statusText,
130
+ body: errorBody,
131
+ endpoint,
132
+ method
133
+ });
134
+ }
135
+ const contentType = response.headers.get("Content-Type");
136
+ let data;
137
+ if (contentType?.includes("application/json")) {
138
+ data = await response.json();
139
+ } else if (contentType?.includes("application/pdf") || contentType?.includes("image/")) {
140
+ const blobData = await response.blob();
141
+ data = { data: blobData, response };
142
+ } else if (contentType?.includes("text/csv")) {
143
+ const csvData = await response.blob();
144
+ data = { data: csvData, response };
145
+ } else if (contentType?.includes("text/")) {
146
+ const text = await response.text();
147
+ data = { data: text, response };
148
+ } else {
149
+ try {
150
+ const blob = await response.clone().blob();
151
+ data = { data: blob, response };
152
+ } catch {
153
+ const text = await response.text();
154
+ data = { data: text, response };
155
+ }
156
+ }
157
+ if (debug) console.log("API Response:", data);
158
+ return data;
159
+ } catch (error) {
160
+ if (error instanceof ApiError) {
161
+ if (debug) console.error(error.toDetailedString());
162
+ throw error;
163
+ }
164
+ const message = error instanceof Error ? error.message : "An unexpected error occurred";
165
+ if (debug) console.error(`API Error (${method} ${endpoint}):`, error);
166
+ throw new ApiError({
167
+ message,
168
+ status: 0,
169
+ // 0 indicates network/client-side error
170
+ statusText: "Network Error",
171
+ body: null,
172
+ endpoint,
173
+ method
174
+ });
175
+ }
176
+ }
177
+ function createQueryString(params = {}) {
178
+ const searchParams = new URLSearchParams();
179
+ Object.entries(params).forEach(([key, value]) => {
180
+ if (value === void 0 || value === "") return;
181
+ if (Array.isArray(value)) {
182
+ if (value.length > 1) {
183
+ searchParams.append(`${key}[in]`, value.join(","));
184
+ } else if (value.length === 1) {
185
+ searchParams.append(key, String(value[0]));
186
+ }
187
+ } else if (value === null) {
188
+ searchParams.append(key, "null");
189
+ } else {
190
+ searchParams.append(key, String(value));
191
+ }
192
+ });
193
+ return searchParams.toString();
194
+ }
195
+
196
+ export { ApiError, configureSDK, createQueryString, getBaseUrl, getSDKConfig, handleApiRequest, setSDKConfigProvider };
197
+ //# sourceMappingURL=chunk-IHCBBLLW.js.map
198
+ //# sourceMappingURL=chunk-IHCBBLLW.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/core/api-handler.ts"],"names":["contentType"],"mappings":"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","file":"chunk-IHCBBLLW.js","sourcesContent":["/**\r\n * @classytic/commerce-sdk - API Handler\r\n *\r\n * Universal API request handler for Next.js applications.\r\n * Handles JSON, binary (PDF, images), CSV, and text responses.\r\n */\r\n\r\n// ==================== Types ====================\r\n\r\nexport type HttpMethod = \"GET\" | \"POST\" | \"PATCH\" | \"PUT\" | \"DELETE\";\r\n\r\nexport interface ApiRequestOptions {\r\n body?: unknown;\r\n token?: string | null;\r\n organizationId?: string | null;\r\n revalidate?: number;\r\n headerOptions?: Record<string, string>;\r\n tags?: string[];\r\n cache?: RequestCache;\r\n /**\r\n * Credentials mode for this specific request.\r\n * Overrides SDK-level credentials config.\r\n * - \"include\": Always send cookies\r\n * - \"same-origin\": Only send cookies for same-origin requests\r\n * - \"omit\": Never send cookies (pure bearer-token auth)\r\n */\r\n credentials?: RequestCredentials;\r\n}\r\n\r\nexport interface BlobResponse {\r\n data: Blob;\r\n response: Response;\r\n}\r\n\r\nexport interface TextResponse {\r\n data: string;\r\n response: Response;\r\n}\r\n\r\n/**\r\n * SDK Configuration\r\n */\r\nexport interface SDKConfig {\r\n /** Base URL for API requests (e.g., \"https://api.example.com\") */\r\n baseUrl: string;\r\n /** Default organization ID for multi-tenant support */\r\n organizationId?: string;\r\n /** Function to get current auth token */\r\n getToken?: () => string | null | Promise<string | null>;\r\n /** Default request cache mode */\r\n cache?: RequestCache;\r\n /** Default headers to include in all requests (e.g., API keys, custom headers) */\r\n headers?: Record<string, string>;\r\n /**\r\n * Default credentials mode for fetch requests.\r\n * Can be overridden per-request via ApiRequestOptions.credentials\r\n * - \"include\": Always send cookies (default for backward compatibility)\r\n * - \"same-origin\": Only send cookies for same-origin requests\r\n * - \"omit\": Never send cookies (use for pure bearer-token auth)\r\n * @default \"include\"\r\n */\r\n credentials?: RequestCredentials;\r\n}\r\n\r\n/**\r\n * Custom API Error class that preserves HTTP status and response body.\r\n * Provides better debugging context for API failures.\r\n *\r\n * @example\r\n * try {\r\n * await sdk.orders.create(data);\r\n * } catch (error) {\r\n * if (error instanceof ApiError) {\r\n * console.log(error.status); // 422\r\n * console.log(error.body); // { errors: [...] }\r\n * console.log(error.endpoint); // \"/api/v1/orders\"\r\n * }\r\n * }\r\n */\r\nexport class ApiError extends Error {\r\n /** HTTP status code (e.g., 400, 401, 404, 500) */\r\n public readonly status: number;\r\n /** HTTP status text (e.g., \"Bad Request\", \"Unauthorized\") */\r\n public readonly statusText: string;\r\n /** Raw response body - JSON object, string, or null if unparseable */\r\n public readonly body: unknown;\r\n /** The API endpoint that was called */\r\n public readonly endpoint: string;\r\n /** The HTTP method used */\r\n public readonly method: HttpMethod;\r\n\r\n constructor(options: {\r\n message: string;\r\n status: number;\r\n statusText: string;\r\n body: unknown;\r\n endpoint: string;\r\n method: HttpMethod;\r\n }) {\r\n super(options.message);\r\n this.name = \"ApiError\";\r\n this.status = options.status;\r\n this.statusText = options.statusText;\r\n this.body = options.body;\r\n this.endpoint = options.endpoint;\r\n this.method = options.method;\r\n\r\n // Maintains proper stack trace (V8 engines)\r\n if (Error.captureStackTrace) {\r\n Error.captureStackTrace(this, ApiError);\r\n }\r\n }\r\n\r\n /** Check if error is a client error (4xx) */\r\n isClientError(): boolean {\r\n return this.status >= 400 && this.status < 500;\r\n }\r\n\r\n /** Check if error is a server error (5xx) */\r\n isServerError(): boolean {\r\n return this.status >= 500;\r\n }\r\n\r\n /** Returns detailed string for logging */\r\n toDetailedString(): string {\r\n const bodyStr = typeof this.body === \"object\"\r\n ? JSON.stringify(this.body, null, 2)\r\n : String(this.body ?? \"\");\r\n return [\r\n `ApiError: ${this.message}`,\r\n ` Status: ${this.status} ${this.statusText}`,\r\n ` Endpoint: ${this.method} ${this.endpoint}`,\r\n bodyStr ? ` Body: ${bodyStr}` : null,\r\n ].filter(Boolean).join(\"\\n\");\r\n }\r\n}\r\n\r\n// Global SDK configuration (set via configureSDK)\r\nlet sdkConfig: SDKConfig | null = null;\r\nlet sdkConfigProvider: (() => SDKConfig | null) | null = null;\r\n\r\nfunction getActiveSDKConfig(): SDKConfig | null {\r\n return sdkConfigProvider?.() ?? sdkConfig;\r\n}\r\n\r\nexport function setSDKConfigProvider(\r\n provider: (() => SDKConfig | null) | null\r\n): void {\r\n sdkConfigProvider = provider;\r\n}\r\n\r\n/**\r\n * Configure the SDK with base URL and other options\r\n *\r\n * @example\r\n * // Basic configuration\r\n * configureSDK({\r\n * baseUrl: process.env.NEXT_PUBLIC_API_URL!,\r\n * getToken: () => localStorage.getItem('token'),\r\n * organizationId: 'org_123',\r\n * });\r\n *\r\n * @example\r\n * // With custom headers (API keys, etc.)\r\n * configureSDK({\r\n * baseUrl: process.env.NEXT_PUBLIC_API_URL!,\r\n * headers: {\r\n * 'x-api-key': process.env.API_KEY,\r\n * 'x-custom-header': 'value',\r\n * },\r\n * });\r\n */\r\nexport function configureSDK(config: SDKConfig): void {\r\n sdkConfig = config;\r\n}\r\n\r\n/**\r\n * Get current SDK configuration\r\n */\r\nexport function getSDKConfig(): SDKConfig | null {\r\n return getActiveSDKConfig();\r\n}\r\n\r\n/**\r\n * Get base URL from SDK config or throw if not configured\r\n */\r\nexport function getBaseUrl(): string {\r\n const config = getActiveSDKConfig();\r\n if (!config?.baseUrl) {\r\n throw new Error(\r\n \"SDK not configured. Call configureSDK({ baseUrl: '...' }) before making API requests.\"\r\n );\r\n }\r\n return config.baseUrl;\r\n}\r\n\r\n// ==================== API Request Handler ====================\r\n\r\n/**\r\n * Universal API request handler for Next.js applications\r\n * Handles JSON, binary (PDF, images), CSV, and text responses\r\n *\r\n * @template T - Expected response type\r\n * @param method - HTTP method\r\n * @param endpoint - API endpoint (will be appended to BASE_URL)\r\n * @param options - Request options\r\n * @param debug - Enable debug logging\r\n * @returns Promise resolving to the response data\r\n *\r\n * @example\r\n * // JSON response\r\n * const { success, data } = await handleApiRequest<ApiResponse<User>>('GET', '/users/me', { token });\r\n *\r\n * // Paginated response\r\n * const response = await handleApiRequest<PaginatedResponse<Product>>('GET', '/products?page=1');\r\n *\r\n * // Create with body\r\n * const result = await handleApiRequest('POST', '/orders', { token, body: orderData });\r\n */\r\nexport async function handleApiRequest<T = unknown>(\r\n method: HttpMethod,\r\n endpoint: string,\r\n options: ApiRequestOptions = {},\r\n debug = false\r\n): Promise<T> {\r\n const BASE_URL = getBaseUrl();\r\n const activeConfig = getActiveSDKConfig();\r\n\r\n const {\r\n body,\r\n token: optionToken,\r\n organizationId: optionOrgId,\r\n revalidate,\r\n headerOptions,\r\n tags,\r\n cache,\r\n credentials: optionCredentials,\r\n } = options;\r\n\r\n // Use provided token/orgId or fallback to SDK config\r\n const token = optionToken ?? (await activeConfig?.getToken?.()) ?? null;\r\n const organizationId = optionOrgId ?? activeConfig?.organizationId ?? null;\r\n\r\n try {\r\n let headers: Record<string, string> = {\r\n ...(activeConfig?.headers || {}),\r\n ...(token && { Authorization: `Bearer ${token}` }),\r\n ...(organizationId && { \"x-organization-id\": organizationId }),\r\n };\r\n\r\n // Only set 'Content-Type' to json if the body is not a FormData object\r\n if (!(body instanceof FormData)) {\r\n headers[\"Content-Type\"] = \"application/json\";\r\n }\r\n\r\n if (headerOptions) {\r\n headers = { ...headers, ...headerOptions };\r\n }\r\n\r\n // Credentials: per-request > SDK config > \"include\" (default for backward compatibility)\r\n const credentials = optionCredentials ?? activeConfig?.credentials ?? \"include\";\r\n\r\n const fetchOptions: RequestInit & {\r\n next?: { revalidate?: number; tags?: string[] };\r\n } = {\r\n method,\r\n headers,\r\n credentials,\r\n };\r\n\r\n // Add body if present\r\n if (body !== undefined && body !== null) {\r\n fetchOptions.body =\r\n body instanceof FormData ? body : JSON.stringify(body);\r\n }\r\n\r\n // Add Next.js specific options\r\n if (cache || activeConfig?.cache) {\r\n fetchOptions.cache = cache ?? activeConfig?.cache;\r\n }\r\n if (revalidate !== undefined) {\r\n fetchOptions.next = {\r\n ...fetchOptions.next,\r\n revalidate,\r\n };\r\n }\r\n if (tags) {\r\n fetchOptions.next = {\r\n ...fetchOptions.next,\r\n tags,\r\n };\r\n }\r\n\r\n const response = await fetch(`${BASE_URL}${endpoint}`, fetchOptions);\r\n\r\n if (!response.ok) {\r\n // Parse error body - try JSON first, fallback to text\r\n let errorBody: unknown = null;\r\n let errorMessage: string = response.statusText;\r\n\r\n const contentType = response.headers.get(\"Content-Type\");\r\n\r\n try {\r\n if (contentType?.includes(\"application/json\")) {\r\n errorBody = await response.json();\r\n // Extract message from common API error formats\r\n errorMessage =\r\n (errorBody as { message?: string })?.message ||\r\n (errorBody as { error?: string })?.error ||\r\n response.statusText;\r\n } else {\r\n // Preserve raw text/HTML body for debugging\r\n errorBody = await response.text();\r\n // Use first 200 chars of text as message if no statusText\r\n if (!response.statusText && typeof errorBody === \"string\") {\r\n errorMessage = errorBody.slice(0, 200);\r\n }\r\n }\r\n } catch {\r\n // Body parsing failed, use statusText\r\n errorBody = null;\r\n }\r\n\r\n throw new ApiError({\r\n message: errorMessage,\r\n status: response.status,\r\n statusText: response.statusText,\r\n body: errorBody,\r\n endpoint,\r\n method,\r\n });\r\n }\r\n\r\n // Detect response type based on content type header\r\n const contentType = response.headers.get(\"Content-Type\");\r\n\r\n let data: unknown;\r\n\r\n if (contentType?.includes(\"application/json\")) {\r\n data = await response.json();\r\n } else if (\r\n contentType?.includes(\"application/pdf\") ||\r\n contentType?.includes(\"image/\")\r\n ) {\r\n const blobData = await response.blob();\r\n data = { data: blobData, response };\r\n } else if (contentType?.includes(\"text/csv\")) {\r\n const csvData = await response.blob();\r\n data = { data: csvData, response };\r\n } else if (contentType?.includes(\"text/\")) {\r\n const text = await response.text();\r\n data = { data: text, response };\r\n } else {\r\n // For unknown content types, try blob first, fallback to text\r\n try {\r\n const blob = await response.clone().blob();\r\n data = { data: blob, response };\r\n } catch {\r\n const text = await response.text();\r\n data = { data: text, response };\r\n }\r\n }\r\n\r\n if (debug) console.log(\"API Response:\", data);\r\n\r\n return data as T;\r\n } catch (error) {\r\n // Re-throw ApiError as-is to preserve status/body context\r\n if (error instanceof ApiError) {\r\n if (debug) console.error(error.toDetailedString());\r\n throw error;\r\n }\r\n\r\n // Wrap unexpected errors (network failures, etc.) in ApiError\r\n const message = error instanceof Error\r\n ? error.message\r\n : \"An unexpected error occurred\";\r\n\r\n if (debug) console.error(`API Error (${method} ${endpoint}):`, error);\r\n\r\n throw new ApiError({\r\n message,\r\n status: 0, // 0 indicates network/client-side error\r\n statusText: \"Network Error\",\r\n body: null,\r\n endpoint,\r\n method,\r\n });\r\n }\r\n}\r\n\r\n// ==================== Query String Utilities ====================\r\n\r\n/**\r\n * Creates query string from parameters\r\n * Supports: ?field=value and arrays as field[in]=value1,value2\r\n *\r\n * @example\r\n * createQueryString({ page: 1, limit: 10, status: 'active' })\r\n * // => 'page=1&limit=10&status=active'\r\n *\r\n * createQueryString({ roles: ['admin', 'user'] })\r\n * // => 'roles[in]=admin,user'\r\n */\r\nexport function createQueryString<T extends Record<string, unknown>>(\r\n params: T = {} as T\r\n): string {\r\n const searchParams = new URLSearchParams();\r\n\r\n Object.entries(params).forEach(([key, value]) => {\r\n if (value === undefined || value === \"\") return;\r\n\r\n if (Array.isArray(value)) {\r\n if (value.length > 1) {\r\n searchParams.append(`${key}[in]`, value.join(\",\"));\r\n } else if (value.length === 1) {\r\n searchParams.append(key, String(value[0]));\r\n }\r\n } else if (value === null) {\r\n searchParams.append(key, \"null\");\r\n } else {\r\n searchParams.append(key, String(value));\r\n }\r\n });\r\n\r\n return searchParams.toString();\r\n}\r\n"]}
@@ -0,0 +1,76 @@
1
+ import { logisticsApi } from './chunk-2YAZ5WG6.js';
2
+ import { financeApi } from './chunk-N43VE355.js';
3
+ import { transactionApi } from './chunk-AQAISI4F.js';
4
+ import { updateCmsPage, getCmsPage, mediaApi } from './chunk-ERQ52WHY.js';
5
+ import { platformConfigApi, branchApi, userApi, couponApi } from './chunk-YYFKLOKO.js';
6
+ import { paymentApi } from './chunk-5E57JODA.js';
7
+ import { authApi } from './chunk-W22WB3WZ.js';
8
+ import { sizeGuideApi, categoryApi, productApi } from './chunk-FOTUJPM4.js';
9
+ import { customerApi, orderApi, cartApi } from './chunk-ANYGZ6O5.js';
10
+ import { purchaseApi } from './chunk-L4OEI4VZ.js';
11
+ import { transferApi } from './chunk-36NLLAVH.js';
12
+ import { requestApi } from './chunk-2TF7QNYV.js';
13
+ import { movementApi } from './chunk-24FDD6UR.js';
14
+ import { adjustmentApi } from './chunk-3OYSJB3P.js';
15
+ import { supplierApi } from './chunk-7LZCW4VF.js';
16
+ import { stockApi } from './chunk-X2CQFJPR.js';
17
+ import { posApi } from './chunk-CILP56G2.js';
18
+ import { configureSDK } from './chunk-IHCBBLLW.js';
19
+
20
+ // src/client.ts
21
+ var cmsApi = {
22
+ getPage: getCmsPage,
23
+ updatePage: updateCmsPage
24
+ };
25
+ function createCommerceSDK(config) {
26
+ configureSDK(config);
27
+ return {
28
+ // Auth
29
+ auth: authApi,
30
+ // Product & Catalog
31
+ product: productApi,
32
+ category: categoryApi,
33
+ sizeGuide: sizeGuideApi,
34
+ // Cart & Checkout
35
+ cart: cartApi,
36
+ order: orderApi,
37
+ coupon: couponApi,
38
+ // Customer & Users
39
+ customer: customerApi,
40
+ user: userApi,
41
+ // Branch & Location
42
+ branch: branchApi,
43
+ // Media
44
+ media: mediaApi,
45
+ // Payment & Finance
46
+ payment: paymentApi,
47
+ transaction: transactionApi,
48
+ finance: financeApi,
49
+ // Logistics & Shipping
50
+ logistics: logisticsApi,
51
+ // Platform Configuration
52
+ platform: platformConfigApi,
53
+ // CMS
54
+ cms: cmsApi,
55
+ // POS
56
+ pos: posApi,
57
+ // Inventory (grouped)
58
+ inventory: {
59
+ stock: stockApi,
60
+ purchase: purchaseApi,
61
+ transfer: transferApi,
62
+ adjustment: adjustmentApi,
63
+ movement: movementApi,
64
+ request: requestApi,
65
+ supplier: supplierApi
66
+ }
67
+ };
68
+ }
69
+ function initCommerceSDK(config) {
70
+ configureSDK(config);
71
+ }
72
+ var client_default = createCommerceSDK;
73
+
74
+ export { client_default, createCommerceSDK, initCommerceSDK };
75
+ //# sourceMappingURL=chunk-J4JBQET2.js.map
76
+ //# sourceMappingURL=chunk-J4JBQET2.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/client.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;AAiBA,IAAM,MAAA,GAAS;AAAA,EACb,OAAA,EAAS,UAAA;AAAA,EACT,UAAA,EAAY;AACd,CAAA;AA2GO,SAAS,kBACd,MAAA,EACmB;AAEnB,EAAA,YAAA,CAAa,MAAmB,CAAA;AAGhC,EAAA,OAAO;AAAA;AAAA,IAEL,IAAA,EAAM,OAAA;AAAA;AAAA,IAGN,OAAA,EAAS,UAAA;AAAA,IACT,QAAA,EAAU,WAAA;AAAA,IACV,SAAA,EAAW,YAAA;AAAA;AAAA,IAGX,IAAA,EAAM,OAAA;AAAA,IACN,KAAA,EAAO,QAAA;AAAA,IACP,MAAA,EAAQ,SAAA;AAAA;AAAA,IAGR,QAAA,EAAU,WAAA;AAAA,IACV,IAAA,EAAM,OAAA;AAAA;AAAA,IAGN,MAAA,EAAQ,SAAA;AAAA;AAAA,IAGR,KAAA,EAAO,QAAA;AAAA;AAAA,IAGP,OAAA,EAAS,UAAA;AAAA,IACT,WAAA,EAAa,cAAA;AAAA,IACb,OAAA,EAAS,UAAA;AAAA;AAAA,IAGT,SAAA,EAAW,YAAA;AAAA;AAAA,IAGX,QAAA,EAAU,iBAAA;AAAA;AAAA,IAGV,GAAA,EAAK,MAAA;AAAA;AAAA,IAGL,GAAA,EAAK,MAAA;AAAA;AAAA,IAGL,SAAA,EAAW;AAAA,MACT,KAAA,EAAO,QAAA;AAAA,MACP,QAAA,EAAU,WAAA;AAAA,MACV,QAAA,EAAU,WAAA;AAAA,MACV,UAAA,EAAY,aAAA;AAAA,MACZ,QAAA,EAAU,WAAA;AAAA,MACV,OAAA,EAAS,UAAA;AAAA,MACT,QAAA,EAAU;AAAA;AACZ,GACF;AACF;AAqBO,SAAS,gBAAgB,MAAA,EAAiC;AAC/D,EAAA,YAAA,CAAa,MAAmB,CAAA;AAClC;AAEA,IAAO,cAAA,GAAQ","file":"chunk-J4JBQET2.js","sourcesContent":["/**\r\n * @classytic/commerce-sdk - SDK Client Factory\r\n *\r\n * Create a configured SDK client instance for use in Next.js applications.\r\n */\r\n\r\nimport { configureSDK, type SDKConfig } from \"./core/api-handler\";\r\n\r\n// Import APIs from domain modules\r\nimport { authApi } from \"./auth\";\r\nimport { productApi, categoryApi, sizeGuideApi } from \"./catalog\";\r\nimport { cartApi, orderApi, customerApi, posApi } from \"./sales\";\r\nimport { transactionApi } from \"./transaction\";\r\nimport { couponApi, userApi, branchApi, platformConfigApi } from \"./platform\";\r\nimport { mediaApi, getCmsPage, updateCmsPage } from \"./content\";\r\n\r\n// Create CMS API wrapper\r\nconst cmsApi = {\r\n getPage: getCmsPage,\r\n updatePage: updateCmsPage,\r\n};\r\nimport { paymentApi } from \"./payments\";\r\nimport { financeApi } from \"./finance\";\r\nimport { logisticsApi } from \"./logistics\";\r\nimport {\r\n stockApi,\r\n purchaseApi,\r\n transferApi,\r\n adjustmentApi,\r\n movementApi,\r\n requestApi,\r\n supplierApi,\r\n} from \"./inventory\";\r\n\r\n/**\r\n * SDK Client Configuration Options\r\n */\r\nexport interface CommerceSDKConfig {\r\n /** Base URL for API requests (e.g., \"https://api.example.com\") */\r\n baseUrl: string;\r\n /** Default organization ID for multi-tenant support */\r\n organizationId?: string;\r\n /** Function to get current auth token */\r\n getToken?: () => string | null | Promise<string | null>;\r\n /** Default request cache mode */\r\n cache?: RequestCache;\r\n /** Default headers to include in all requests */\r\n headers?: Record<string, string>;\r\n}\r\n\r\n/**\r\n * Commerce SDK Client\r\n *\r\n * Provides typed access to all commerce APIs.\r\n */\r\nexport interface CommerceSDKClient {\r\n // Auth\r\n auth: typeof authApi;\r\n\r\n // Product & Catalog\r\n product: typeof productApi;\r\n category: typeof categoryApi;\r\n sizeGuide: typeof sizeGuideApi;\r\n\r\n // Cart & Checkout\r\n cart: typeof cartApi;\r\n order: typeof orderApi;\r\n coupon: typeof couponApi;\r\n\r\n // Customer & Users\r\n customer: typeof customerApi;\r\n user: typeof userApi;\r\n\r\n // Branch & Location\r\n branch: typeof branchApi;\r\n\r\n // Media\r\n media: typeof mediaApi;\r\n\r\n // Payment & Finance\r\n payment: typeof paymentApi;\r\n transaction: typeof transactionApi;\r\n finance: typeof financeApi;\r\n\r\n // Logistics & Shipping\r\n logistics: typeof logisticsApi;\r\n\r\n // Platform Configuration\r\n platform: typeof platformConfigApi;\r\n\r\n // CMS\r\n cms: typeof cmsApi;\r\n\r\n // POS\r\n pos: typeof posApi;\r\n\r\n // Inventory\r\n inventory: {\r\n stock: typeof stockApi;\r\n purchase: typeof purchaseApi;\r\n transfer: typeof transferApi;\r\n adjustment: typeof adjustmentApi;\r\n movement: typeof movementApi;\r\n request: typeof requestApi;\r\n supplier: typeof supplierApi;\r\n };\r\n}\r\n\r\n/**\r\n * Create a configured Commerce SDK client\r\n *\r\n * @example\r\n * ```typescript\r\n * // In your app initialization\r\n * import { createCommerceSDK } from '@classytic/commerce-sdk';\r\n *\r\n * const sdk = createCommerceSDK({\r\n * baseUrl: process.env.NEXT_PUBLIC_API_URL!,\r\n * getToken: () => getCookie('token'),\r\n * organizationId: 'org_123',\r\n * });\r\n *\r\n * // Use the SDK\r\n * const products = await sdk.product.getAll({ params: { page: 1 } });\r\n * const order = await sdk.order.create({ token, data: orderData });\r\n * ```\r\n */\r\nexport function createCommerceSDK(\r\n config: CommerceSDKConfig\r\n): CommerceSDKClient {\r\n // Configure the global SDK settings\r\n configureSDK(config as SDKConfig);\r\n\r\n // Return the client with all APIs\r\n return {\r\n // Auth\r\n auth: authApi,\r\n\r\n // Product & Catalog\r\n product: productApi,\r\n category: categoryApi,\r\n sizeGuide: sizeGuideApi,\r\n\r\n // Cart & Checkout\r\n cart: cartApi,\r\n order: orderApi,\r\n coupon: couponApi,\r\n\r\n // Customer & Users\r\n customer: customerApi,\r\n user: userApi,\r\n\r\n // Branch & Location\r\n branch: branchApi,\r\n\r\n // Media\r\n media: mediaApi,\r\n\r\n // Payment & Finance\r\n payment: paymentApi,\r\n transaction: transactionApi,\r\n finance: financeApi,\r\n\r\n // Logistics & Shipping\r\n logistics: logisticsApi,\r\n\r\n // Platform Configuration\r\n platform: platformConfigApi,\r\n\r\n // CMS\r\n cms: cmsApi,\r\n\r\n // POS\r\n pos: posApi,\r\n\r\n // Inventory (grouped)\r\n inventory: {\r\n stock: stockApi,\r\n purchase: purchaseApi,\r\n transfer: transferApi,\r\n adjustment: adjustmentApi,\r\n movement: movementApi,\r\n request: requestApi,\r\n supplier: supplierApi,\r\n },\r\n };\r\n}\r\n\r\n/**\r\n * Initialize SDK configuration without creating a client\r\n *\r\n * Useful when you want to configure the SDK globally and use\r\n * individual API instances directly.\r\n *\r\n * @example\r\n * ```typescript\r\n * import { initCommerceSDK, productApi } from '@classytic/commerce-sdk';\r\n *\r\n * // Initialize once at app startup\r\n * initCommerceSDK({\r\n * baseUrl: process.env.NEXT_PUBLIC_API_URL!,\r\n * });\r\n *\r\n * // Use APIs directly\r\n * const products = await productApi.getAll({ params: { page: 1 } });\r\n * ```\r\n */\r\nexport function initCommerceSDK(config: CommerceSDKConfig): void {\r\n configureSDK(config as SDKConfig);\r\n}\r\n\r\nexport default createCommerceSDK;\r\n"]}
@@ -0,0 +1,123 @@
1
+ import { BaseApi } from './chunk-QCTXAMLA.js';
2
+ import { handleApiRequest } from './chunk-IHCBBLLW.js';
3
+
4
+ // src/inventory/api/purchase.ts
5
+ var PurchaseApi = class extends BaseApi {
6
+ constructor(config = {}) {
7
+ super("inventory/purchases", config);
8
+ }
9
+ // ==================== Actions (Stripe Pattern) ====================
10
+ /**
11
+ * Perform a purchase action (receive/pay/cancel)
12
+ * POST /inventory/purchases/:id/action
13
+ */
14
+ async action({
15
+ token,
16
+ id,
17
+ action,
18
+ data = {},
19
+ options = {}
20
+ }) {
21
+ if (!id) {
22
+ throw new Error("Purchase ID is required");
23
+ }
24
+ return handleApiRequest("POST", `${this.baseUrl}/${id}/action`, {
25
+ token,
26
+ body: { action, ...data },
27
+ cache: this.config.cache,
28
+ ...options
29
+ });
30
+ }
31
+ /**
32
+ * Receive a purchase (auto-approves draft and creates stock movements)
33
+ * POST /inventory/purchases/:id/action { action: 'receive' }
34
+ */
35
+ async receive({
36
+ token,
37
+ id,
38
+ options = {}
39
+ }) {
40
+ return this.action({ token, id, action: "receive", options });
41
+ }
42
+ /**
43
+ * Record payment for a purchase
44
+ * POST /inventory/purchases/:id/action { action: 'pay', amount, method, reference }
45
+ */
46
+ async pay({
47
+ token,
48
+ id,
49
+ amount,
50
+ method,
51
+ reference,
52
+ accountNumber,
53
+ walletNumber,
54
+ bankName,
55
+ accountName,
56
+ proofUrl,
57
+ transactionDate,
58
+ notes,
59
+ options = {}
60
+ }) {
61
+ return this.action({
62
+ token,
63
+ id,
64
+ action: "pay",
65
+ data: {
66
+ amount,
67
+ method,
68
+ reference,
69
+ accountNumber,
70
+ walletNumber,
71
+ bankName,
72
+ accountName,
73
+ proofUrl,
74
+ transactionDate,
75
+ notes
76
+ },
77
+ options
78
+ });
79
+ }
80
+ /**
81
+ * Cancel a purchase (draft or approved only)
82
+ * POST /inventory/purchases/:id/action { action: 'cancel', reason }
83
+ */
84
+ async cancel({
85
+ token,
86
+ id,
87
+ reason,
88
+ options = {}
89
+ }) {
90
+ return this.action({
91
+ token,
92
+ id,
93
+ action: "cancel",
94
+ data: { reason },
95
+ options
96
+ });
97
+ }
98
+ // ==================== Legacy Methods (Backward Compatibility) ====================
99
+ /**
100
+ * Record a stock purchase (legacy method)
101
+ * Creates and optionally auto-receives a purchase
102
+ *
103
+ * @deprecated Use create() with autoReceive: true instead
104
+ */
105
+ async recordPurchase({
106
+ token,
107
+ data,
108
+ options = {}
109
+ }) {
110
+ const payload = { ...data, autoReceive: true };
111
+ return handleApiRequest("POST", this.baseUrl, {
112
+ token,
113
+ body: payload,
114
+ cache: this.config.cache,
115
+ ...options
116
+ });
117
+ }
118
+ };
119
+ var purchaseApi = new PurchaseApi();
120
+
121
+ export { PurchaseApi, purchaseApi };
122
+ //# sourceMappingURL=chunk-L4OEI4VZ.js.map
123
+ //# sourceMappingURL=chunk-L4OEI4VZ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/inventory/api/purchase.ts"],"names":[],"mappings":"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","file":"chunk-L4OEI4VZ.js","sourcesContent":["/**\r\n * Purchase API - Supplier Invoices & Stock Entry\r\n *\r\n * Base path: /api/v1/inventory/purchases\r\n *\r\n * Purchases are the only official way to bring new inventory into the system.\r\n * They are Head Office only and drive COGS (weighted average cost).\r\n *\r\n * Standard CRUD:\r\n * - create({ token, data }) - Create purchase invoice (draft)\r\n * - getAll({ token, params }) - List purchases with filtering\r\n * - getById({ token, id }) - Get purchase by ID\r\n * - update({ token, id, data }) - Update draft purchase\r\n *\r\n * Actions (Stripe pattern):\r\n * - receive({ token, id }) - Receive purchase (creates stock movements)\r\n * - pay({ token, id, amount, method, reference }) - Record payment\r\n * - cancel({ token, id, reason }) - Cancel draft/approved purchase\r\n */\r\n\r\nimport { BaseApi, type ApiResponse, type PaginatedResponse, type RequestOptions } from \"../../core/api-factory\";\r\nimport { handleApiRequest } from \"../../core/api-handler\";\r\nimport type {\r\n Purchase,\r\n CreatePurchasePayload,\r\n UpdatePurchasePayload,\r\n PurchaseActionType,\r\n StockMovement,\r\n StockEntry,\r\n} from \"../types\";\r\n\r\ntype FetchOptions = Omit<RequestOptions, \"token\" | \"organizationId\">;\r\n\r\nclass PurchaseApi extends BaseApi<Purchase, CreatePurchasePayload, UpdatePurchasePayload> {\r\n constructor(config = {}) {\r\n super(\"inventory/purchases\", config);\r\n }\r\n\r\n // ==================== Actions (Stripe Pattern) ====================\r\n\r\n /**\r\n * Perform a purchase action (receive/pay/cancel)\r\n * POST /inventory/purchases/:id/action\r\n */\r\n async action({\r\n token,\r\n id,\r\n action,\r\n data = {},\r\n options = {},\r\n }: {\r\n token: string;\r\n id: string;\r\n action: PurchaseActionType;\r\n data?: Record<string, unknown>;\r\n options?: FetchOptions;\r\n }): Promise<ApiResponse<Purchase>> {\r\n if (!id) {\r\n throw new Error(\"Purchase ID is required\");\r\n }\r\n\r\n return handleApiRequest(\"POST\", `${this.baseUrl}/${id}/action`, {\r\n token,\r\n body: { action, ...data },\r\n cache: this.config.cache,\r\n ...options,\r\n });\r\n }\r\n\r\n /**\r\n * Receive a purchase (auto-approves draft and creates stock movements)\r\n * POST /inventory/purchases/:id/action { action: 'receive' }\r\n */\r\n async receive({\r\n token,\r\n id,\r\n options = {},\r\n }: {\r\n token: string;\r\n id: string;\r\n options?: FetchOptions;\r\n }): Promise<ApiResponse<Purchase>> {\r\n return this.action({ token, id, action: \"receive\", options });\r\n }\r\n\r\n /**\r\n * Record payment for a purchase\r\n * POST /inventory/purchases/:id/action { action: 'pay', amount, method, reference }\r\n */\r\n async pay({\r\n token,\r\n id,\r\n amount,\r\n method,\r\n reference,\r\n accountNumber,\r\n walletNumber,\r\n bankName,\r\n accountName,\r\n proofUrl,\r\n transactionDate,\r\n notes,\r\n options = {},\r\n }: {\r\n token: string;\r\n id: string;\r\n amount: number;\r\n method: string;\r\n reference?: string;\r\n accountNumber?: string;\r\n walletNumber?: string;\r\n bankName?: string;\r\n accountName?: string;\r\n proofUrl?: string;\r\n transactionDate?: string;\r\n notes?: string;\r\n options?: FetchOptions;\r\n }): Promise<ApiResponse<Purchase>> {\r\n return this.action({\r\n token,\r\n id,\r\n action: \"pay\",\r\n data: {\r\n amount,\r\n method,\r\n reference,\r\n accountNumber,\r\n walletNumber,\r\n bankName,\r\n accountName,\r\n proofUrl,\r\n transactionDate,\r\n notes,\r\n },\r\n options,\r\n });\r\n }\r\n\r\n /**\r\n * Cancel a purchase (draft or approved only)\r\n * POST /inventory/purchases/:id/action { action: 'cancel', reason }\r\n */\r\n async cancel({\r\n token,\r\n id,\r\n reason,\r\n options = {},\r\n }: {\r\n token: string;\r\n id: string;\r\n reason?: string;\r\n options?: FetchOptions;\r\n }): Promise<ApiResponse<Purchase>> {\r\n return this.action({\r\n token,\r\n id,\r\n action: \"cancel\",\r\n data: { reason },\r\n options,\r\n });\r\n }\r\n\r\n // ==================== Legacy Methods (Backward Compatibility) ====================\r\n\r\n /**\r\n * Record a stock purchase (legacy method)\r\n * Creates and optionally auto-receives a purchase\r\n *\r\n * @deprecated Use create() with autoReceive: true instead\r\n */\r\n async recordPurchase({\r\n token,\r\n data,\r\n options = {},\r\n }: {\r\n token: string;\r\n data: CreatePurchasePayload;\r\n options?: FetchOptions;\r\n }): Promise<\r\n ApiResponse<{\r\n stockEntries: StockEntry[];\r\n movements: StockMovement[];\r\n }>\r\n > {\r\n // Set autoReceive to maintain backward compatibility\r\n const payload = { ...data, autoReceive: true };\r\n return handleApiRequest(\"POST\", this.baseUrl, {\r\n token,\r\n body: payload,\r\n cache: this.config.cache,\r\n ...options,\r\n });\r\n }\r\n}\r\n\r\nexport const purchaseApi = new PurchaseApi();\r\nexport { PurchaseApi };\r\n"]}