@classytic/commerce-sdk 0.1.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.

Potentially problematic release.


This version of @classytic/commerce-sdk might be problematic. Click here for more details.

Files changed (131) hide show
  1. package/LICENSE +14 -0
  2. package/README.md +104 -0
  3. package/dist/adjustment-DTSLM7AN.js +5 -0
  4. package/dist/adjustment-DTSLM7AN.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 +479 -0
  14. package/dist/catalog/index.js +9 -0
  15. package/dist/catalog/index.js.map +1 -0
  16. package/dist/chunk-4ZQK3FFN.js +40 -0
  17. package/dist/chunk-4ZQK3FFN.js.map +1 -0
  18. package/dist/chunk-5L6EXDGH.js +465 -0
  19. package/dist/chunk-5L6EXDGH.js.map +1 -0
  20. package/dist/chunk-5ZFW3FEI.js +183 -0
  21. package/dist/chunk-5ZFW3FEI.js.map +1 -0
  22. package/dist/chunk-66OQAZSL.js +94 -0
  23. package/dist/chunk-66OQAZSL.js.map +1 -0
  24. package/dist/chunk-6RYGA6MF.js +123 -0
  25. package/dist/chunk-6RYGA6MF.js.map +1 -0
  26. package/dist/chunk-B6MPVOV7.js +328 -0
  27. package/dist/chunk-B6MPVOV7.js.map +1 -0
  28. package/dist/chunk-BDA2WSJA.js +148 -0
  29. package/dist/chunk-BDA2WSJA.js.map +1 -0
  30. package/dist/chunk-EIVYT3HM.js +126 -0
  31. package/dist/chunk-EIVYT3HM.js.map +1 -0
  32. package/dist/chunk-EPQN7ZKZ.js +27 -0
  33. package/dist/chunk-EPQN7ZKZ.js.map +1 -0
  34. package/dist/chunk-FA7QFJ2G.js +177 -0
  35. package/dist/chunk-FA7QFJ2G.js.map +1 -0
  36. package/dist/chunk-I5TIKUIQ.js +261 -0
  37. package/dist/chunk-I5TIKUIQ.js.map +1 -0
  38. package/dist/chunk-ILQUH444.js +135 -0
  39. package/dist/chunk-ILQUH444.js.map +1 -0
  40. package/dist/chunk-IXMWZJLV.js +616 -0
  41. package/dist/chunk-IXMWZJLV.js.map +1 -0
  42. package/dist/chunk-KZIGRIQG.js +75 -0
  43. package/dist/chunk-KZIGRIQG.js.map +1 -0
  44. package/dist/chunk-OF5M6R2S.js +769 -0
  45. package/dist/chunk-OF5M6R2S.js.map +1 -0
  46. package/dist/chunk-PYYLHUV6.js +3 -0
  47. package/dist/chunk-PYYLHUV6.js.map +1 -0
  48. package/dist/chunk-QO5AGZFP.js +159 -0
  49. package/dist/chunk-QO5AGZFP.js.map +1 -0
  50. package/dist/chunk-QUMTBLNE.js +76 -0
  51. package/dist/chunk-QUMTBLNE.js.map +1 -0
  52. package/dist/chunk-R5Z7NYLH.js +126 -0
  53. package/dist/chunk-R5Z7NYLH.js.map +1 -0
  54. package/dist/chunk-SZYWG5IB.js +75 -0
  55. package/dist/chunk-SZYWG5IB.js.map +1 -0
  56. package/dist/chunk-U3XT35GZ.js +202 -0
  57. package/dist/chunk-U3XT35GZ.js.map +1 -0
  58. package/dist/chunk-UGELTUIZ.js +830 -0
  59. package/dist/chunk-UGELTUIZ.js.map +1 -0
  60. package/dist/chunk-VR36QVX2.js +122 -0
  61. package/dist/chunk-VR36QVX2.js.map +1 -0
  62. package/dist/chunk-WUOQK7BO.js +13 -0
  63. package/dist/chunk-WUOQK7BO.js.map +1 -0
  64. package/dist/chunk-X6PV5MHG.js +582 -0
  65. package/dist/chunk-X6PV5MHG.js.map +1 -0
  66. package/dist/chunk-ZWLMFLLH.js +534 -0
  67. package/dist/chunk-ZWLMFLLH.js.map +1 -0
  68. package/dist/content/index.d.ts +309 -0
  69. package/dist/content/index.js +6 -0
  70. package/dist/content/index.js.map +1 -0
  71. package/dist/core/index.d.ts +107 -0
  72. package/dist/core/index.js +5 -0
  73. package/dist/core/index.js.map +1 -0
  74. package/dist/core/react.d.ts +107 -0
  75. package/dist/core/react.js +5 -0
  76. package/dist/core/react.js.map +1 -0
  77. package/dist/coupon-CHFcw7cd.d.ts +632 -0
  78. package/dist/coupon-zGkvO-Xx.d.ts +129 -0
  79. package/dist/crud.factory-DyKaPHcU.d.ts +181 -0
  80. package/dist/finance/index.d.ts +81 -0
  81. package/dist/finance/index.js +5 -0
  82. package/dist/finance/index.js.map +1 -0
  83. package/dist/finance-BJdfKRw0.d.ts +135 -0
  84. package/dist/index.d.ts +31 -0
  85. package/dist/index.js +29 -0
  86. package/dist/index.js.map +1 -0
  87. package/dist/inventory/index.d.ts +512 -0
  88. package/dist/inventory/index.js +16 -0
  89. package/dist/inventory/index.js.map +1 -0
  90. package/dist/inventory-DCiIZh8P.d.ts +742 -0
  91. package/dist/logistics/index.d.ts +226 -0
  92. package/dist/logistics/index.js +7 -0
  93. package/dist/logistics/index.js.map +1 -0
  94. package/dist/logistics-V8a9lUN3.d.ts +428 -0
  95. package/dist/media-CNLJK93J.d.ts +721 -0
  96. package/dist/movement-7MV3ADY5.js +5 -0
  97. package/dist/movement-7MV3ADY5.js.map +1 -0
  98. package/dist/payment-BRboLqvU.d.ts +127 -0
  99. package/dist/payments/index.d.ts +55 -0
  100. package/dist/payments/index.js +6 -0
  101. package/dist/payments/index.js.map +1 -0
  102. package/dist/platform/index.d.ts +645 -0
  103. package/dist/platform/index.js +8 -0
  104. package/dist/platform/index.js.map +1 -0
  105. package/dist/pos-D1jkkFl0.d.ts +885 -0
  106. package/dist/product-p09zXkXB.d.ts +260 -0
  107. package/dist/purchase-24BGT2HA.js +5 -0
  108. package/dist/purchase-24BGT2HA.js.map +1 -0
  109. package/dist/request-652PS6VR.js +5 -0
  110. package/dist/request-652PS6VR.js.map +1 -0
  111. package/dist/sales/index.d.ts +585 -0
  112. package/dist/sales/index.js +9 -0
  113. package/dist/sales/index.js.map +1 -0
  114. package/dist/server.d.ts +120 -0
  115. package/dist/server.js +27 -0
  116. package/dist/server.js.map +1 -0
  117. package/dist/size-guide-DgjzjM5P.d.ts +554 -0
  118. package/dist/stock-DEApGC-w.d.ts +632 -0
  119. package/dist/stock-OOUW57VQ.js +5 -0
  120. package/dist/stock-OOUW57VQ.js.map +1 -0
  121. package/dist/supplier-OC6JAWV6.js +5 -0
  122. package/dist/supplier-OC6JAWV6.js.map +1 -0
  123. package/dist/transaction/index.d.ts +104 -0
  124. package/dist/transaction/index.js +8 -0
  125. package/dist/transaction/index.js.map +1 -0
  126. package/dist/transaction-BTmoHpWh.d.ts +428 -0
  127. package/dist/transaction-u5oaNuav.d.ts +84 -0
  128. package/dist/transfer-7SYSH3RG.js +5 -0
  129. package/dist/transfer-7SYSH3RG.js.map +1 -0
  130. package/dist/user-data-DdLjAGwO.d.ts +132 -0
  131. package/package.json +146 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/content/api/cms.ts","../src/content/api/media.ts","../src/content/hooks/media.ts","../src/content/hooks/cms.ts"],"names":["useQuery","useQueryClient","useMutation"],"mappings":"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","file":"chunk-ZWLMFLLH.js","sourcesContent":["/**\r\n * CMS API - Slug-based content management\r\n *\r\n * Two endpoints only:\r\n * - GET /api/v1/cms/:slug - Fetch page (public)\r\n * - PATCH /api/v1/cms/:slug - Update page (admin, auto-creates if missing)\r\n */\r\n\r\nimport { handleApiRequest } from \"../../core/api-handler\";\r\nimport type { ApiResponse, RequestOptions } from \"../../core/api-factory\";\r\nimport type { CMSPage, CMSPagePayload } from \"../types/cms\";\r\n\r\nconst CMS_BASE = \"/api/v1/cms\";\r\n\r\n/**\r\n * Get CMS page by slug (public)\r\n * Returns page data or null if not found\r\n * Gracefully handles 404 errors by returning null instead of throwing\r\n */\r\nexport async function getCmsPage({\r\n slug,\r\n options = {},\r\n}: {\r\n slug: string;\r\n options?: RequestOptions;\r\n}): Promise<ApiResponse<CMSPage | null>> {\r\n if (!slug) throw new Error(\"Slug is required\");\r\n\r\n try {\r\n return await handleApiRequest<ApiResponse<CMSPage | null>>(\r\n \"GET\",\r\n `${CMS_BASE}/${slug}`,\r\n options\r\n );\r\n } catch (error) {\r\n // If document not found (404), return null data gracefully\r\n if (error instanceof Error && error.message.includes(\"Document not found\")) {\r\n return {\r\n success: false,\r\n data: null,\r\n message: \"CMS page not found, using static fallback\",\r\n };\r\n }\r\n // Re-throw other errors (network issues, server errors, etc.)\r\n throw error;\r\n }\r\n}\r\n\r\n/**\r\n * Update CMS page by slug (admin)\r\n * Backend auto-creates if page doesn't exist\r\n */\r\nexport async function updateCmsPage({\r\n slug,\r\n token,\r\n data,\r\n options = {},\r\n}: {\r\n slug: string;\r\n token: string;\r\n data: CMSPagePayload;\r\n options?: RequestOptions;\r\n}): Promise<ApiResponse<CMSPage>> {\r\n if (!slug) throw new Error(\"Slug is required\");\r\n\r\n return handleApiRequest<ApiResponse<CMSPage>>(\r\n \"PATCH\",\r\n `${CMS_BASE}/${slug}`,\r\n { token, body: data, ...options }\r\n );\r\n}\r\n","// Media API - Image upload and management\r\nimport {\r\n type ApiResponse,\r\n type PaginatedResponse,\r\n type RequestOptions,\r\n type DeleteResponse,\r\n} from \"../../core/api-factory\";\r\nimport { handleApiRequest } from \"../../core/api-handler\";\r\nimport type {\r\n Media,\r\n MediaFolder,\r\n MediaQueryParams,\r\n UpdateMediaPayload,\r\n BulkDeleteResult,\r\n MoveFilesPayload,\r\n MoveFilesResult,\r\n} from \"../types/media\";\r\n\r\ntype FetchOptions = Omit<RequestOptions, \"token\" | \"organizationId\">;\r\n\r\n/**\r\n * Media API - Image upload and management\r\n *\r\n * Endpoints:\r\n * - POST /api/media/upload (single file upload)\r\n * - POST /api/media/upload-multiple (multiple files)\r\n * - GET /api/media (list with filters)\r\n * - GET /api/media/:id (get single)\r\n * - PATCH /api/media/:id (update alt/title)\r\n * - DELETE /api/media/:id (delete single)\r\n * - GET /api/media/folders (get allowed folders)\r\n *\r\n * Features:\r\n * - Auto WebP conversion\r\n * - Auto variants: thumbnail (150x200), medium (600x800)\r\n * - Max size: 50MB\r\n * - S3 storage with CDN\r\n *\r\n * Usage Examples:\r\n * - mediaApi.upload({ token: 'xxx', file, folder: 'products' })\r\n * - mediaApi.getAll({ params: { folder: 'products', limit: 20 }})\r\n * - mediaApi.update({ token: 'xxx', id: '123', data: { alt: 'New alt' }})\r\n * - mediaApi.delete({ token: 'xxx', id: '123' })\r\n */\r\nclass MediaApi {\r\n private readonly baseUrl: string;\r\n private readonly defaultCache: RequestCache;\r\n\r\n constructor(config: { basePath?: string; cache?: RequestCache } = {}) {\r\n this.baseUrl = `${config.basePath || \"/api/v1\"}/media`;\r\n this.defaultCache = config.cache || \"no-store\";\r\n }\r\n\r\n /**\r\n * Upload single file\r\n * POST /api/media/upload\r\n *\r\n * @example\r\n * const file = event.target.files[0];\r\n * const result = await mediaApi.upload({\r\n * token: 'xxx',\r\n * file,\r\n * folder: 'products',\r\n * alt: 'Product image'\r\n * });\r\n */\r\n async upload({\r\n token,\r\n file,\r\n folder,\r\n alt,\r\n title,\r\n options = {},\r\n }: {\r\n token: string;\r\n file: File | Blob;\r\n folder?: MediaFolder;\r\n alt?: string;\r\n title?: string;\r\n options?: FetchOptions;\r\n }): Promise<ApiResponse<Media>> {\r\n const formData = new FormData();\r\n // Fields MUST come before files for Fastify multipart streaming parser\r\n if (folder) formData.append(\"folder\", folder);\r\n if (alt) formData.append(\"alt\", alt);\r\n if (title) formData.append(\"title\", title);\r\n formData.append(\"file\", file);\r\n\r\n return handleApiRequest(\"POST\", `${this.baseUrl}/upload`, {\r\n token,\r\n body: formData,\r\n cache: this.defaultCache,\r\n ...options,\r\n });\r\n }\r\n\r\n /**\r\n * Upload multiple files (max 20)\r\n * POST /api/media/upload-multiple\r\n *\r\n * @example\r\n * const files = Array.from(event.target.files);\r\n * const result = await mediaApi.uploadMultiple({\r\n * token: 'xxx',\r\n * files,\r\n * folder: 'products'\r\n * });\r\n */\r\n async uploadMultiple({\r\n token,\r\n files,\r\n folder,\r\n options = {},\r\n }: {\r\n token: string;\r\n files: (File | Blob)[];\r\n folder?: MediaFolder;\r\n options?: FetchOptions;\r\n }): Promise<ApiResponse<Media[]>> {\r\n const formData = new FormData();\r\n // Fields MUST come before files for Fastify multipart streaming parser\r\n if (folder) formData.append(\"folder\", folder);\r\n files.forEach((file) => formData.append(\"files[]\", file));\r\n\r\n return handleApiRequest(\"POST\", `${this.baseUrl}/upload-multiple`, {\r\n token,\r\n body: formData,\r\n cache: this.defaultCache,\r\n ...options,\r\n });\r\n }\r\n\r\n /**\r\n * Get all media with filtering\r\n * GET /api/media\r\n *\r\n * @example\r\n * const result = await mediaApi.getAll({\r\n * token: 'xxx',\r\n * params: {\r\n * folder: 'products',\r\n * search: 'shirt',\r\n * limit: 20,\r\n * sort: '-createdAt'\r\n * }\r\n * });\r\n */\r\n async getAll({\r\n token,\r\n params = {},\r\n options = {},\r\n }: {\r\n token: string;\r\n params?: MediaQueryParams;\r\n options?: FetchOptions;\r\n } = {} as any): Promise<PaginatedResponse<Media>> {\r\n // Filter out undefined/null values before creating query string\r\n const cleanParams = Object.fromEntries(\r\n Object.entries(params).filter(([, v]) => v !== undefined && v !== null)\r\n );\r\n const queryString = new URLSearchParams(\r\n cleanParams as Record<string, string>\r\n ).toString();\r\n const url = queryString ? `${this.baseUrl}?${queryString}` : this.baseUrl;\r\n\r\n return handleApiRequest(\"GET\", url, {\r\n token,\r\n cache: this.defaultCache,\r\n ...options,\r\n });\r\n }\r\n\r\n /**\r\n * Get single media by ID\r\n * GET /api/media/:id\r\n *\r\n * @example\r\n * const result = await mediaApi.getById({ token: 'xxx', id: '123abc' });\r\n */\r\n async getById({\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<Media>> {\r\n if (!id) throw new Error(\"ID is required\");\r\n\r\n return handleApiRequest(\"GET\", `${this.baseUrl}/${id}`, {\r\n token,\r\n cache: this.defaultCache,\r\n ...options,\r\n });\r\n }\r\n\r\n /**\r\n * Update media metadata (alt, title)\r\n * PATCH /api/media/:id\r\n *\r\n * @example\r\n * await mediaApi.update({\r\n * token: 'xxx',\r\n * id: '123',\r\n * data: { alt: 'New alt text', title: 'New title' }\r\n * });\r\n */\r\n async update({\r\n token,\r\n id,\r\n data,\r\n options = {},\r\n }: {\r\n token: string;\r\n id: string;\r\n data: UpdateMediaPayload;\r\n options?: FetchOptions;\r\n }): Promise<ApiResponse<Media>> {\r\n if (!id) throw new Error(\"ID is required\");\r\n\r\n return handleApiRequest(\"PATCH\", `${this.baseUrl}/${id}`, {\r\n token,\r\n body: data,\r\n cache: this.defaultCache,\r\n ...options,\r\n });\r\n }\r\n\r\n /**\r\n * Delete single media\r\n * DELETE /api/media/:id\r\n *\r\n * @example\r\n * await mediaApi.delete({ token: 'xxx', id: '123' });\r\n */\r\n async delete({\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<DeleteResponse> {\r\n if (!id) throw new Error(\"ID is required\");\r\n\r\n return handleApiRequest(\"DELETE\", `${this.baseUrl}/${id}`, {\r\n token,\r\n cache: this.defaultCache,\r\n ...options,\r\n });\r\n }\r\n\r\n /**\r\n * Bulk delete multiple files\r\n * POST /api/media/bulk-delete\r\n *\r\n * @example\r\n * await mediaApi.bulkDelete({\r\n * token: 'xxx',\r\n * ids: ['123', '456', '789']\r\n * });\r\n */\r\n async bulkDelete({\r\n token,\r\n ids,\r\n options = {},\r\n }: {\r\n token: string;\r\n ids: string[];\r\n options?: FetchOptions;\r\n }): Promise<ApiResponse<BulkDeleteResult>> {\r\n if (!ids.length) throw new Error(\"IDs array is required\");\r\n\r\n return handleApiRequest(\"POST\", `${this.baseUrl}/bulk-delete`, {\r\n token,\r\n body: { ids },\r\n cache: this.defaultCache,\r\n ...options,\r\n });\r\n }\r\n\r\n /**\r\n * Move files to different folder\r\n * POST /api/media/move\r\n *\r\n * @example\r\n * await mediaApi.moveToFolder({\r\n * token: 'xxx',\r\n * ids: ['123', '456'],\r\n * targetFolder: 'banners'\r\n * });\r\n */\r\n async moveToFolder({\r\n token,\r\n data,\r\n options = {},\r\n }: {\r\n token: string;\r\n data: MoveFilesPayload;\r\n options?: FetchOptions;\r\n }): Promise<ApiResponse<MoveFilesResult>> {\r\n if (!data.ids.length) throw new Error(\"IDs array is required\");\r\n if (!data.targetFolder) throw new Error(\"Target folder is required\");\r\n\r\n return handleApiRequest(\"POST\", `${this.baseUrl}/move`, {\r\n token,\r\n body: data,\r\n cache: this.defaultCache,\r\n ...options,\r\n });\r\n }\r\n\r\n /**\r\n * Get allowed folders\r\n * GET /api/media/folders\r\n *\r\n * @example\r\n * const result = await mediaApi.getFolders({ token: 'xxx' });\r\n * // result.data = ['general', 'products', 'categories', ...]\r\n */\r\n async getFolders({\r\n token,\r\n options = {},\r\n }: {\r\n token: string;\r\n options?: FetchOptions;\r\n }): Promise<ApiResponse<MediaFolder[]>> {\r\n return handleApiRequest(\"GET\", `${this.baseUrl}/folders`, {\r\n token,\r\n cache: this.defaultCache,\r\n ...options,\r\n });\r\n }\r\n\r\n /**\r\n * Helper: Get variant URL by name\r\n * Falls back to original URL if variant not found\r\n *\r\n * @example\r\n * const thumbnailUrl = mediaApi.getVariantUrl(media, 'thumbnail');\r\n * <img src={thumbnailUrl} />\r\n */\r\n getVariantUrl(media: Media, variantName: string): string {\r\n return (\r\n media.variants?.find((v) => v.name === variantName)?.url || media.url\r\n );\r\n }\r\n\r\n /**\r\n * Helper: Get thumbnail URL\r\n */\r\n getThumbnailUrl(media: Media): string {\r\n return this.getVariantUrl(media, \"thumbnail\");\r\n }\r\n\r\n /**\r\n * Helper: Get medium URL\r\n */\r\n getMediumUrl(media: Media): string {\r\n return this.getVariantUrl(media, \"medium\");\r\n }\r\n\r\n}\r\n\r\n// Create and export a singleton instance\r\nexport const mediaApi = new MediaApi();\r\nexport { MediaApi };\r\n","\"use client\";\n\nimport { useQuery, useMutation, useQueryClient } from \"@tanstack/react-query\";\nimport { mediaApi } from \"../api/media\";\nimport { getToastHandler } from \"../../core/react/mutation.factory\";\nimport type {\n Media,\n MediaFolder,\n MediaQueryParams,\n UpdateMediaPayload,\n BulkDeleteResult,\n MoveFilesPayload,\n MoveFilesResult,\n} from \"../types/media\";\n\n// ============================================\n// Query Keys\n// ============================================\n\nexport const MEDIA_KEYS = {\n all: [\"media\"] as const,\n lists: () => [...MEDIA_KEYS.all, \"list\"] as const,\n list: (params: MediaQueryParams) => [...MEDIA_KEYS.lists(), params] as const,\n details: () => [...MEDIA_KEYS.all, \"detail\"] as const,\n detail: (id: string) => [...MEDIA_KEYS.details(), id] as const,\n folders: () => [...MEDIA_KEYS.all, \"folders\"] as const,\n};\n\n// ============================================\n// Types\n// ============================================\n\nexport interface UseMediaListOptions {\n enabled?: boolean;\n staleTime?: number;\n gcTime?: number;\n refetchOnWindowFocus?: boolean;\n}\n\nexport interface UseMediaUploadReturn {\n upload: (params: { files: (File | Blob)[]; folder?: MediaFolder }) => void;\n uploadAsync: (params: { files: (File | Blob)[]; folder?: MediaFolder }) => Promise<Media[]>;\n isUploading: boolean;\n error: Error | null;\n}\n\nexport interface UseMediaBulkDeleteReturn {\n bulkDelete: (ids: string[]) => void;\n bulkDeleteAsync: (ids: string[]) => Promise<BulkDeleteResult>;\n isDeleting: boolean;\n error: Error | null;\n}\n\nexport interface UseMediaMoveReturn {\n move: (data: MoveFilesPayload) => void;\n moveAsync: (data: MoveFilesPayload) => Promise<MoveFilesResult>;\n isMoving: boolean;\n error: Error | null;\n}\n\nexport interface UseMediaUpdateReturn {\n update: (params: { id: string; data: UpdateMediaPayload }) => void;\n updateAsync: (params: { id: string; data: UpdateMediaPayload }) => Promise<Media>;\n isUpdating: boolean;\n error: Error | null;\n}\n\n// ============================================\n// Query Hooks\n// ============================================\n\n/**\n * Hook to get media list with folder filtering\n *\n * @param token - Auth token (required)\n * @param params - Query params (folder, search, limit, etc.)\n * @param options - React Query options\n *\n * @example\n * ```tsx\n * function MediaLibrary() {\n * const { data, isLoading } = useMediaList(token, {\n * folder: 'products',\n * limit: 20,\n * });\n *\n * if (isLoading) return <Spinner />;\n *\n * return (\n * <div className=\"grid\">\n * {data?.docs?.map(media => (\n * <img key={media._id} src={media.variants?.thumbnail?.url || media.url} />\n * ))}\n * </div>\n * );\n * }\n * ```\n */\nexport function useMediaList(\n token: string | null,\n params: MediaQueryParams = {},\n options: UseMediaListOptions = {}\n) {\n const {\n enabled = true,\n staleTime = 2 * 60 * 1000,\n gcTime = 5 * 60 * 1000,\n refetchOnWindowFocus = false,\n } = options;\n\n return useQuery({\n queryKey: MEDIA_KEYS.list(params),\n queryFn: () => mediaApi.getAll({ token: token!, params }),\n enabled: enabled && !!token,\n staleTime,\n gcTime,\n refetchOnWindowFocus,\n });\n}\n\n/**\n * Hook to get single media by ID\n *\n * @param token - Auth token (required)\n * @param id - Media ID\n * @param options - React Query options\n *\n * @example\n * ```tsx\n * function MediaDetail({ id }) {\n * const { data, isLoading } = useMediaDetail(token, id);\n *\n * if (isLoading) return <Spinner />;\n *\n * return (\n * <div>\n * <img src={data?.data?.url} alt={data?.data?.alt} />\n * <p>{data?.data?.title}</p>\n * </div>\n * );\n * }\n * ```\n */\nexport function useMediaDetail(\n token: string | null,\n id: string | null,\n options: UseMediaListOptions = {}\n) {\n const { enabled = true, staleTime = 2 * 60 * 1000, gcTime = 5 * 60 * 1000 } = options;\n\n return useQuery({\n queryKey: MEDIA_KEYS.detail(id!),\n queryFn: () => mediaApi.getById({ token: token!, id: id! }),\n enabled: enabled && !!token && !!id,\n staleTime,\n gcTime,\n });\n}\n\n/**\n * Hook to get allowed folders\n *\n * @param token - Auth token (required)\n * @param options - React Query options\n *\n * @example\n * ```tsx\n * function FolderSelector() {\n * const { data, isLoading } = useMediaFolders(token);\n *\n * return (\n * <Select>\n * {data?.data?.map(folder => (\n * <SelectItem key={folder} value={folder}>{folder}</SelectItem>\n * ))}\n * </Select>\n * );\n * }\n * ```\n */\nexport function useMediaFolders(token: string | null, options: UseMediaListOptions = {}) {\n const { enabled = true, staleTime = 10 * 60 * 1000, gcTime = 15 * 60 * 1000 } = options;\n\n return useQuery({\n queryKey: MEDIA_KEYS.folders(),\n queryFn: () => mediaApi.getFolders({ token: token! }),\n enabled: enabled && !!token,\n staleTime,\n gcTime,\n });\n}\n\n// ============================================\n// Mutation Hooks\n// ============================================\n\n/**\n * Hook to upload multiple media files\n *\n * @param token - Auth token (required)\n *\n * @example\n * ```tsx\n * function MediaUploader() {\n * const { upload, isUploading } = useMediaUpload(token);\n *\n * const handleFiles = (e) => {\n * const files = Array.from(e.target.files);\n * upload({ files, folder: 'products' });\n * };\n *\n * return (\n * <input type=\"file\" multiple onChange={handleFiles} disabled={isUploading} />\n * );\n * }\n * ```\n */\nexport function useMediaUpload(token: string): UseMediaUploadReturn {\n const queryClient = useQueryClient();\n const toast = getToastHandler();\n\n const mutation = useMutation({\n mutationFn: async ({ files, folder }: { files: (File | Blob)[]; folder?: MediaFolder }) => {\n const response = await mediaApi.uploadMultiple({ token, files, folder });\n return response.data as Media[];\n },\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: MEDIA_KEYS.lists() });\n toast.success(\"Media uploaded successfully\");\n },\n onError: (error: Error) => {\n toast.error(error.message || \"Failed to upload media\");\n },\n });\n\n return {\n upload: (params) => mutation.mutate(params),\n uploadAsync: (params) => mutation.mutateAsync(params),\n isUploading: mutation.isPending,\n error: mutation.error,\n };\n}\n\n/**\n * Hook to bulk delete media with optimistic updates\n *\n * @param token - Auth token (required)\n *\n * @example\n * ```tsx\n * function MediaManager({ selectedIds }) {\n * const { bulkDelete, isDeleting } = useMediaBulkDelete(token);\n *\n * return (\n * <Button\n * variant=\"destructive\"\n * onClick={() => bulkDelete(selectedIds)}\n * disabled={isDeleting}\n * >\n * Delete Selected\n * </Button>\n * );\n * }\n * ```\n */\nexport function useMediaBulkDelete(token: string): UseMediaBulkDeleteReturn {\n const queryClient = useQueryClient();\n const toast = getToastHandler();\n\n const mutation = useMutation<\n BulkDeleteResult,\n Error,\n string[],\n { previousLists: [unknown, unknown][] }\n >({\n mutationFn: async (ids: string[]) => {\n const response = await mediaApi.bulkDelete({ token, ids });\n return response.data as BulkDeleteResult;\n },\n onMutate: async (ids) => {\n await queryClient.cancelQueries({ queryKey: MEDIA_KEYS.lists() });\n\n const previousLists = queryClient.getQueriesData({ queryKey: MEDIA_KEYS.lists() });\n\n // Optimistically update cache\n queryClient.setQueriesData({ queryKey: MEDIA_KEYS.lists() }, (old: unknown) => {\n const data = old as { docs?: Media[]; total?: number } | undefined;\n if (!data?.docs) return old;\n return {\n ...data,\n docs: data.docs.filter((item: Media) => !ids.includes(item._id)),\n total: (data.total || 0) - ids.length,\n };\n });\n\n return { previousLists: previousLists as [unknown, unknown][] };\n },\n onError: (_error, _ids, context) => {\n if (context?.previousLists) {\n context.previousLists.forEach(([queryKey, data]) => {\n queryClient.setQueryData(queryKey as unknown[], data);\n });\n }\n toast.error(\"Failed to delete media\");\n },\n onSuccess: (data) => {\n const deletedCount = data.success.length;\n toast.success(`${deletedCount} item(s) deleted successfully`);\n },\n onSettled: () => {\n queryClient.invalidateQueries({ queryKey: MEDIA_KEYS.lists() });\n },\n });\n\n return {\n bulkDelete: (ids) => mutation.mutate(ids),\n bulkDeleteAsync: (ids) => mutation.mutateAsync(ids),\n isDeleting: mutation.isPending,\n error: mutation.error,\n };\n}\n\n/**\n * Hook to move media to different folder\n *\n * @param token - Auth token (required)\n *\n * @example\n * ```tsx\n * function MoveDialog({ selectedIds }) {\n * const { move, isMoving } = useMediaMove(token);\n *\n * const handleMove = (folder) => {\n * move({ ids: selectedIds, targetFolder: folder });\n * };\n *\n * return <FolderSelect onSelect={handleMove} disabled={isMoving} />;\n * }\n * ```\n */\nexport function useMediaMove(token: string): UseMediaMoveReturn {\n const queryClient = useQueryClient();\n const toast = getToastHandler();\n\n const mutation = useMutation<MoveFilesResult, Error, MoveFilesPayload>({\n mutationFn: async (data: MoveFilesPayload) => {\n const response = await mediaApi.moveToFolder({ token, data });\n return response.data as MoveFilesResult;\n },\n onSuccess: (data, variables) => {\n queryClient.invalidateQueries({ queryKey: MEDIA_KEYS.lists() });\n toast.success(`${data.modifiedCount} item(s) moved to ${variables.targetFolder}`);\n },\n onError: (error: Error) => {\n toast.error(error.message || \"Failed to move media\");\n },\n });\n\n return {\n move: (data) => mutation.mutate(data),\n moveAsync: (data) => mutation.mutateAsync(data),\n isMoving: mutation.isPending,\n error: mutation.error,\n };\n}\n\n/**\n * Hook to update media metadata\n *\n * @param token - Auth token (required)\n *\n * @example\n * ```tsx\n * function MediaEdit({ media }) {\n * const { update, isUpdating } = useMediaUpdate(token);\n * const [alt, setAlt] = useState(media.alt);\n *\n * const handleSave = () => {\n * update({ id: media._id, data: { alt } });\n * };\n *\n * return (\n * <>\n * <Input value={alt} onChange={e => setAlt(e.target.value)} />\n * <Button onClick={handleSave} disabled={isUpdating}>Save</Button>\n * </>\n * );\n * }\n * ```\n */\nexport function useMediaUpdate(token: string): UseMediaUpdateReturn {\n const queryClient = useQueryClient();\n const toast = getToastHandler();\n\n const mutation = useMutation({\n mutationFn: async ({ id, data }: { id: string; data: UpdateMediaPayload }) => {\n const response = await mediaApi.update({ token, id, data });\n return response.data as Media;\n },\n onMutate: async ({ id, data }) => {\n await queryClient.cancelQueries({ queryKey: MEDIA_KEYS.detail(id) });\n\n const previous = queryClient.getQueryData(MEDIA_KEYS.detail(id));\n\n queryClient.setQueryData(MEDIA_KEYS.detail(id), (old: unknown) => ({\n ...(old as object),\n ...data,\n }));\n\n return { previous, id };\n },\n onError: (_error, _variables, context) => {\n if (context?.previous) {\n queryClient.setQueryData(MEDIA_KEYS.detail(context.id), context.previous);\n }\n toast.error(\"Failed to update media\");\n },\n onSuccess: () => {\n toast.success(\"Media updated successfully\");\n },\n onSettled: (_data, _error, variables) => {\n queryClient.invalidateQueries({ queryKey: MEDIA_KEYS.detail(variables.id) });\n queryClient.invalidateQueries({ queryKey: MEDIA_KEYS.lists() });\n },\n });\n\n return {\n update: (params) => mutation.mutate(params),\n updateAsync: (params) => mutation.mutateAsync(params),\n isUpdating: mutation.isPending,\n error: mutation.error,\n };\n}\n\n// ============================================\n// Helper Functions (re-exported from API)\n// ============================================\n\n/**\n * Get variant URL by name, falls back to original URL\n */\nexport function getMediaVariantUrl(media: Media, variantName: string): string {\n return media.variants?.find((v) => v.name === variantName)?.url || media.url;\n}\n\n/**\n * Get thumbnail URL\n */\nexport function getMediaThumbnailUrl(media: Media): string {\n return getMediaVariantUrl(media, \"thumbnail\");\n}\n\n/**\n * Get medium URL\n */\nexport function getMediaMediumUrl(media: Media): string {\n return getMediaVariantUrl(media, \"medium\");\n}\n","\"use client\";\r\n\r\n/**\r\n * CMS Hooks\r\n *\r\n * React hooks for CMS page operations.\r\n */\r\n\r\nimport { useQuery, useMutation, useQueryClient } from \"@tanstack/react-query\";\r\nimport { getCmsPage, updateCmsPage } from \"../api/cms\";\r\nimport { getToastHandler } from \"../../core/react/mutation.factory\";\r\nimport type { CMSPage, CMSPagePayload } from \"../types/cms\";\r\n\r\n// ============================================\r\n// Query Keys\r\n// ============================================\r\n\r\nexport const CMS_KEYS = {\r\n all: [\"cms\"] as const,\r\n page: (slug: string) => [...CMS_KEYS.all, slug] as const,\r\n};\r\n\r\n// ============================================\r\n// Types\r\n// ============================================\r\n\r\ninterface QueryOptions {\r\n enabled?: boolean;\r\n staleTime?: number;\r\n}\r\n\r\nexport interface UseCMSPageReturn {\r\n page: CMSPage | null;\r\n isLoading: boolean;\r\n isFetching: boolean;\r\n error: Error | null;\r\n refetch: () => void;\r\n}\r\n\r\nexport interface UseCMSUpdateReturn {\r\n updatePage: (params: { slug: string; data: CMSPagePayload }) => Promise<CMSPage>;\r\n isUpdating: boolean;\r\n}\r\n\r\n// ============================================\r\n// Hooks\r\n// ============================================\r\n\r\n/**\r\n * Fetch CMS page by slug\r\n *\r\n * @param slug - Page slug (e.g., 'about', 'terms', 'privacy')\r\n * @param options - Query options\r\n *\r\n * @example\r\n * ```tsx\r\n * function AboutPage() {\r\n * const { page, isLoading } = useCMSPage('about');\r\n *\r\n * if (isLoading) return <Skeleton />;\r\n * if (!page) return <StaticAboutPage />;\r\n *\r\n * return (\r\n * <article>\r\n * <h1>{page.title}</h1>\r\n * <div dangerouslySetInnerHTML={{ __html: page.content }} />\r\n * </article>\r\n * );\r\n * }\r\n * ```\r\n */\r\nexport function useCMSPage(\r\n slug: string,\r\n options: QueryOptions = {}\r\n): UseCMSPageReturn {\r\n const { data, isLoading, isFetching, error, refetch } = useQuery({\r\n queryKey: CMS_KEYS.page(slug),\r\n queryFn: async () => {\r\n const response = await getCmsPage({ slug });\r\n return response.data;\r\n },\r\n enabled: !!slug && options.enabled !== false,\r\n staleTime: options.staleTime ?? 5 * 60 * 1000, // 5 minutes\r\n });\r\n\r\n return {\r\n page: data || null,\r\n isLoading,\r\n isFetching,\r\n error: error as Error | null,\r\n refetch,\r\n };\r\n}\r\n\r\n/**\r\n * Update CMS page (admin)\r\n * Backend auto-creates if page doesn't exist\r\n *\r\n * @param token - Admin token\r\n *\r\n * @example\r\n * ```tsx\r\n * function CMSEditor({ slug }) {\r\n * const { page } = useCMSPage(slug);\r\n * const { updatePage, isUpdating } = useCMSUpdate(token);\r\n *\r\n * const handleSave = async (content: string) => {\r\n * await updatePage({\r\n * slug,\r\n * data: { content, title: page?.title },\r\n * });\r\n * };\r\n *\r\n * return (\r\n * <Editor\r\n * content={page?.content || ''}\r\n * onSave={handleSave}\r\n * isSaving={isUpdating}\r\n * />\r\n * );\r\n * }\r\n * ```\r\n */\r\nexport function useCMSUpdate(token: string): UseCMSUpdateReturn {\r\n const queryClient = useQueryClient();\r\n const toast = getToastHandler();\r\n\r\n const mutation = useMutation({\r\n mutationFn: async ({ slug, data }: { slug: string; data: CMSPagePayload }) => {\r\n const response = await updateCmsPage({ slug, token, data });\r\n return response.data as CMSPage;\r\n },\r\n onSuccess: (_, { slug }) => {\r\n queryClient.invalidateQueries({ queryKey: CMS_KEYS.page(slug) });\r\n toast.success(\"Page saved successfully\");\r\n\r\n // Trigger ISR revalidation (optional)\r\n if (typeof window !== \"undefined\") {\r\n fetch(\"/revalidate\", {\r\n method: \"POST\",\r\n headers: { \"Content-Type\": \"application/json\" },\r\n body: JSON.stringify({ slug, type: \"both\" }),\r\n }).catch(() => {\r\n // Silently ignore revalidation errors\r\n });\r\n }\r\n },\r\n onError: (error: Error) => {\r\n toast.error(error.message || \"Failed to save page\");\r\n },\r\n });\r\n\r\n return {\r\n updatePage: mutation.mutateAsync,\r\n isUpdating: mutation.isPending,\r\n };\r\n}\r\n"]}
@@ -0,0 +1,309 @@
1
+ import { q as MediaQueryParams, l as Media, i as MediaFolder, r as BulkDeleteResult, p as MoveFilesPayload, s as MoveFilesResult, o as UpdateMediaPayload, b as CMSPage, c as CMSPagePayload } from '../media-CNLJK93J.js';
2
+ export { A as AboutPageContent, B as BulkDeletePayload, f as CMSContentBySlug, a as CMSMetadata, C as CMSPageStatus, h as CMSSlug, d as ContactPageContent, F as FAQPageContent, H as HomePageContent, M as MediaApi, j as MediaDimensions, k as MediaVariant, P as PolicyPageContent, R as ReturnsPageContent, e as ShippingPageContent, S as SizeGuidePageContent, n as UploadMultiplePayload, U as UploadPayload, V as VariantName, g as getCmsPage, m as mediaApi, u as updateCmsPage } from '../media-CNLJK93J.js';
3
+ import * as _tanstack_react_query from '@tanstack/react-query';
4
+ import { P as PaginatedResponse, A as ApiResponse } from '../api-factory-B_h4RKBm.js';
5
+
6
+ declare const MEDIA_KEYS: {
7
+ all: readonly ["media"];
8
+ lists: () => readonly ["media", "list"];
9
+ list: (params: MediaQueryParams) => readonly ["media", "list", MediaQueryParams];
10
+ details: () => readonly ["media", "detail"];
11
+ detail: (id: string) => readonly ["media", "detail", string];
12
+ folders: () => readonly ["media", "folders"];
13
+ };
14
+ interface UseMediaListOptions {
15
+ enabled?: boolean;
16
+ staleTime?: number;
17
+ gcTime?: number;
18
+ refetchOnWindowFocus?: boolean;
19
+ }
20
+ interface UseMediaUploadReturn {
21
+ upload: (params: {
22
+ files: (File | Blob)[];
23
+ folder?: MediaFolder;
24
+ }) => void;
25
+ uploadAsync: (params: {
26
+ files: (File | Blob)[];
27
+ folder?: MediaFolder;
28
+ }) => Promise<Media[]>;
29
+ isUploading: boolean;
30
+ error: Error | null;
31
+ }
32
+ interface UseMediaBulkDeleteReturn {
33
+ bulkDelete: (ids: string[]) => void;
34
+ bulkDeleteAsync: (ids: string[]) => Promise<BulkDeleteResult>;
35
+ isDeleting: boolean;
36
+ error: Error | null;
37
+ }
38
+ interface UseMediaMoveReturn {
39
+ move: (data: MoveFilesPayload) => void;
40
+ moveAsync: (data: MoveFilesPayload) => Promise<MoveFilesResult>;
41
+ isMoving: boolean;
42
+ error: Error | null;
43
+ }
44
+ interface UseMediaUpdateReturn {
45
+ update: (params: {
46
+ id: string;
47
+ data: UpdateMediaPayload;
48
+ }) => void;
49
+ updateAsync: (params: {
50
+ id: string;
51
+ data: UpdateMediaPayload;
52
+ }) => Promise<Media>;
53
+ isUpdating: boolean;
54
+ error: Error | null;
55
+ }
56
+ /**
57
+ * Hook to get media list with folder filtering
58
+ *
59
+ * @param token - Auth token (required)
60
+ * @param params - Query params (folder, search, limit, etc.)
61
+ * @param options - React Query options
62
+ *
63
+ * @example
64
+ * ```tsx
65
+ * function MediaLibrary() {
66
+ * const { data, isLoading } = useMediaList(token, {
67
+ * folder: 'products',
68
+ * limit: 20,
69
+ * });
70
+ *
71
+ * if (isLoading) return <Spinner />;
72
+ *
73
+ * return (
74
+ * <div className="grid">
75
+ * {data?.docs?.map(media => (
76
+ * <img key={media._id} src={media.variants?.thumbnail?.url || media.url} />
77
+ * ))}
78
+ * </div>
79
+ * );
80
+ * }
81
+ * ```
82
+ */
83
+ declare function useMediaList(token: string | null, params?: MediaQueryParams, options?: UseMediaListOptions): _tanstack_react_query.UseQueryResult<PaginatedResponse<Media>, Error>;
84
+ /**
85
+ * Hook to get single media by ID
86
+ *
87
+ * @param token - Auth token (required)
88
+ * @param id - Media ID
89
+ * @param options - React Query options
90
+ *
91
+ * @example
92
+ * ```tsx
93
+ * function MediaDetail({ id }) {
94
+ * const { data, isLoading } = useMediaDetail(token, id);
95
+ *
96
+ * if (isLoading) return <Spinner />;
97
+ *
98
+ * return (
99
+ * <div>
100
+ * <img src={data?.data?.url} alt={data?.data?.alt} />
101
+ * <p>{data?.data?.title}</p>
102
+ * </div>
103
+ * );
104
+ * }
105
+ * ```
106
+ */
107
+ declare function useMediaDetail(token: string | null, id: string | null, options?: UseMediaListOptions): _tanstack_react_query.UseQueryResult<ApiResponse<Media>, Error>;
108
+ /**
109
+ * Hook to get allowed folders
110
+ *
111
+ * @param token - Auth token (required)
112
+ * @param options - React Query options
113
+ *
114
+ * @example
115
+ * ```tsx
116
+ * function FolderSelector() {
117
+ * const { data, isLoading } = useMediaFolders(token);
118
+ *
119
+ * return (
120
+ * <Select>
121
+ * {data?.data?.map(folder => (
122
+ * <SelectItem key={folder} value={folder}>{folder}</SelectItem>
123
+ * ))}
124
+ * </Select>
125
+ * );
126
+ * }
127
+ * ```
128
+ */
129
+ declare function useMediaFolders(token: string | null, options?: UseMediaListOptions): _tanstack_react_query.UseQueryResult<ApiResponse<MediaFolder[]>, Error>;
130
+ /**
131
+ * Hook to upload multiple media files
132
+ *
133
+ * @param token - Auth token (required)
134
+ *
135
+ * @example
136
+ * ```tsx
137
+ * function MediaUploader() {
138
+ * const { upload, isUploading } = useMediaUpload(token);
139
+ *
140
+ * const handleFiles = (e) => {
141
+ * const files = Array.from(e.target.files);
142
+ * upload({ files, folder: 'products' });
143
+ * };
144
+ *
145
+ * return (
146
+ * <input type="file" multiple onChange={handleFiles} disabled={isUploading} />
147
+ * );
148
+ * }
149
+ * ```
150
+ */
151
+ declare function useMediaUpload(token: string): UseMediaUploadReturn;
152
+ /**
153
+ * Hook to bulk delete media with optimistic updates
154
+ *
155
+ * @param token - Auth token (required)
156
+ *
157
+ * @example
158
+ * ```tsx
159
+ * function MediaManager({ selectedIds }) {
160
+ * const { bulkDelete, isDeleting } = useMediaBulkDelete(token);
161
+ *
162
+ * return (
163
+ * <Button
164
+ * variant="destructive"
165
+ * onClick={() => bulkDelete(selectedIds)}
166
+ * disabled={isDeleting}
167
+ * >
168
+ * Delete Selected
169
+ * </Button>
170
+ * );
171
+ * }
172
+ * ```
173
+ */
174
+ declare function useMediaBulkDelete(token: string): UseMediaBulkDeleteReturn;
175
+ /**
176
+ * Hook to move media to different folder
177
+ *
178
+ * @param token - Auth token (required)
179
+ *
180
+ * @example
181
+ * ```tsx
182
+ * function MoveDialog({ selectedIds }) {
183
+ * const { move, isMoving } = useMediaMove(token);
184
+ *
185
+ * const handleMove = (folder) => {
186
+ * move({ ids: selectedIds, targetFolder: folder });
187
+ * };
188
+ *
189
+ * return <FolderSelect onSelect={handleMove} disabled={isMoving} />;
190
+ * }
191
+ * ```
192
+ */
193
+ declare function useMediaMove(token: string): UseMediaMoveReturn;
194
+ /**
195
+ * Hook to update media metadata
196
+ *
197
+ * @param token - Auth token (required)
198
+ *
199
+ * @example
200
+ * ```tsx
201
+ * function MediaEdit({ media }) {
202
+ * const { update, isUpdating } = useMediaUpdate(token);
203
+ * const [alt, setAlt] = useState(media.alt);
204
+ *
205
+ * const handleSave = () => {
206
+ * update({ id: media._id, data: { alt } });
207
+ * };
208
+ *
209
+ * return (
210
+ * <>
211
+ * <Input value={alt} onChange={e => setAlt(e.target.value)} />
212
+ * <Button onClick={handleSave} disabled={isUpdating}>Save</Button>
213
+ * </>
214
+ * );
215
+ * }
216
+ * ```
217
+ */
218
+ declare function useMediaUpdate(token: string): UseMediaUpdateReturn;
219
+ /**
220
+ * Get variant URL by name, falls back to original URL
221
+ */
222
+ declare function getMediaVariantUrl(media: Media, variantName: string): string;
223
+ /**
224
+ * Get thumbnail URL
225
+ */
226
+ declare function getMediaThumbnailUrl(media: Media): string;
227
+ /**
228
+ * Get medium URL
229
+ */
230
+ declare function getMediaMediumUrl(media: Media): string;
231
+
232
+ declare const CMS_KEYS: {
233
+ all: readonly ["cms"];
234
+ page: (slug: string) => readonly ["cms", string];
235
+ };
236
+ interface QueryOptions {
237
+ enabled?: boolean;
238
+ staleTime?: number;
239
+ }
240
+ interface UseCMSPageReturn {
241
+ page: CMSPage | null;
242
+ isLoading: boolean;
243
+ isFetching: boolean;
244
+ error: Error | null;
245
+ refetch: () => void;
246
+ }
247
+ interface UseCMSUpdateReturn {
248
+ updatePage: (params: {
249
+ slug: string;
250
+ data: CMSPagePayload;
251
+ }) => Promise<CMSPage>;
252
+ isUpdating: boolean;
253
+ }
254
+ /**
255
+ * Fetch CMS page by slug
256
+ *
257
+ * @param slug - Page slug (e.g., 'about', 'terms', 'privacy')
258
+ * @param options - Query options
259
+ *
260
+ * @example
261
+ * ```tsx
262
+ * function AboutPage() {
263
+ * const { page, isLoading } = useCMSPage('about');
264
+ *
265
+ * if (isLoading) return <Skeleton />;
266
+ * if (!page) return <StaticAboutPage />;
267
+ *
268
+ * return (
269
+ * <article>
270
+ * <h1>{page.title}</h1>
271
+ * <div dangerouslySetInnerHTML={{ __html: page.content }} />
272
+ * </article>
273
+ * );
274
+ * }
275
+ * ```
276
+ */
277
+ declare function useCMSPage(slug: string, options?: QueryOptions): UseCMSPageReturn;
278
+ /**
279
+ * Update CMS page (admin)
280
+ * Backend auto-creates if page doesn't exist
281
+ *
282
+ * @param token - Admin token
283
+ *
284
+ * @example
285
+ * ```tsx
286
+ * function CMSEditor({ slug }) {
287
+ * const { page } = useCMSPage(slug);
288
+ * const { updatePage, isUpdating } = useCMSUpdate(token);
289
+ *
290
+ * const handleSave = async (content: string) => {
291
+ * await updatePage({
292
+ * slug,
293
+ * data: { content, title: page?.title },
294
+ * });
295
+ * };
296
+ *
297
+ * return (
298
+ * <Editor
299
+ * content={page?.content || ''}
300
+ * onSave={handleSave}
301
+ * isSaving={isUpdating}
302
+ * />
303
+ * );
304
+ * }
305
+ * ```
306
+ */
307
+ declare function useCMSUpdate(token: string): UseCMSUpdateReturn;
308
+
309
+ export { BulkDeleteResult, CMSPage, CMSPagePayload, CMS_KEYS, MEDIA_KEYS, Media, MediaFolder, MediaQueryParams, MoveFilesPayload, MoveFilesResult, UpdateMediaPayload, type UseCMSPageReturn, type UseCMSUpdateReturn, type UseMediaBulkDeleteReturn, type UseMediaListOptions, type UseMediaMoveReturn, type UseMediaUpdateReturn, type UseMediaUploadReturn, getMediaMediumUrl, getMediaThumbnailUrl, getMediaVariantUrl, useCMSPage, useCMSUpdate, useMediaBulkDelete, useMediaDetail, useMediaFolders, useMediaList, useMediaMove, useMediaUpdate, useMediaUpload };
@@ -0,0 +1,6 @@
1
+ "use client";
2
+ export { CMS_KEYS, MEDIA_KEYS, MediaApi, getCmsPage, getMediaMediumUrl, getMediaThumbnailUrl, getMediaVariantUrl, mediaApi, updateCmsPage, useCMSPage, useCMSUpdate, useMediaBulkDelete, useMediaDetail, useMediaFolders, useMediaList, useMediaMove, useMediaUpdate, useMediaUpload } from '../chunk-ZWLMFLLH.js';
3
+ import '../chunk-U3XT35GZ.js';
4
+ import '../chunk-VR36QVX2.js';
5
+ //# sourceMappingURL=index.js.map
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"index.js"}
@@ -0,0 +1,107 @@
1
+ export { d as AggregatePaginationResponse, A as ApiResponse, B as BaseApi, f as BaseApiConfig, D as DeleteResponse, E as ExtractDoc, F as FilterOperator, K as KeysetPaginationResponse, O as OffsetPaginationResponse, P as PaginatedResponse, Q as QueryParams, R as RequestOptions, S as SortDirection, e as SortSpec, c as createCrudApi, b as isAggregatePagination, a as isKeysetPagination, i as isOffsetPagination } from '../api-factory-B_h4RKBm.js';
2
+
3
+ /**
4
+ * @classytic/commerce-sdk - API Handler
5
+ *
6
+ * Universal API request handler for Next.js applications.
7
+ * Handles JSON, binary (PDF, images), CSV, and text responses.
8
+ */
9
+ type HttpMethod = "GET" | "POST" | "PATCH" | "PUT" | "DELETE";
10
+ interface ApiRequestOptions {
11
+ body?: unknown;
12
+ token?: string | null;
13
+ organizationId?: string | null;
14
+ revalidate?: number;
15
+ headerOptions?: Record<string, string>;
16
+ tags?: string[];
17
+ cache?: RequestCache;
18
+ }
19
+ interface BlobResponse {
20
+ data: Blob;
21
+ response: Response;
22
+ }
23
+ interface TextResponse {
24
+ data: string;
25
+ response: Response;
26
+ }
27
+ /**
28
+ * SDK Configuration
29
+ */
30
+ interface SDKConfig {
31
+ /** Base URL for API requests (e.g., "https://api.example.com") */
32
+ baseUrl: string;
33
+ /** Default organization ID for multi-tenant support */
34
+ organizationId?: string;
35
+ /** Function to get current auth token */
36
+ getToken?: () => string | null | Promise<string | null>;
37
+ /** Default request cache mode */
38
+ cache?: RequestCache;
39
+ /** Default headers to include in all requests (e.g., API keys, custom headers) */
40
+ headers?: Record<string, string>;
41
+ }
42
+ /**
43
+ * Configure the SDK with base URL and other options
44
+ *
45
+ * @example
46
+ * // Basic configuration
47
+ * configureSDK({
48
+ * baseUrl: process.env.NEXT_PUBLIC_API_URL!,
49
+ * getToken: () => localStorage.getItem('token'),
50
+ * organizationId: 'org_123',
51
+ * });
52
+ *
53
+ * @example
54
+ * // With custom headers (API keys, etc.)
55
+ * configureSDK({
56
+ * baseUrl: process.env.NEXT_PUBLIC_API_URL!,
57
+ * headers: {
58
+ * 'x-api-key': process.env.API_KEY,
59
+ * 'x-custom-header': 'value',
60
+ * },
61
+ * });
62
+ */
63
+ declare function configureSDK(config: SDKConfig): void;
64
+ /**
65
+ * Get current SDK configuration
66
+ */
67
+ declare function getSDKConfig(): SDKConfig | null;
68
+ /**
69
+ * Get base URL from SDK config or throw if not configured
70
+ */
71
+ declare function getBaseUrl(): string;
72
+ /**
73
+ * Universal API request handler for Next.js applications
74
+ * Handles JSON, binary (PDF, images), CSV, and text responses
75
+ *
76
+ * @template T - Expected response type
77
+ * @param method - HTTP method
78
+ * @param endpoint - API endpoint (will be appended to BASE_URL)
79
+ * @param options - Request options
80
+ * @param debug - Enable debug logging
81
+ * @returns Promise resolving to the response data
82
+ *
83
+ * @example
84
+ * // JSON response
85
+ * const { success, data } = await handleApiRequest<ApiResponse<User>>('GET', '/users/me', { token });
86
+ *
87
+ * // Paginated response
88
+ * const response = await handleApiRequest<PaginatedResponse<Product>>('GET', '/products?page=1');
89
+ *
90
+ * // Create with body
91
+ * const result = await handleApiRequest('POST', '/orders', { token, body: orderData });
92
+ */
93
+ declare function handleApiRequest<T = unknown>(method: HttpMethod, endpoint: string, options?: ApiRequestOptions, debug?: boolean): Promise<T>;
94
+ /**
95
+ * Creates query string from parameters
96
+ * Supports: ?field=value and arrays as field[in]=value1,value2
97
+ *
98
+ * @example
99
+ * createQueryString({ page: 1, limit: 10, status: 'active' })
100
+ * // => 'page=1&limit=10&status=active'
101
+ *
102
+ * createQueryString({ roles: ['admin', 'user'] })
103
+ * // => 'roles[in]=admin,user'
104
+ */
105
+ declare function createQueryString<T extends Record<string, unknown>>(params?: T): string;
106
+
107
+ export { type ApiRequestOptions, type BlobResponse, type HttpMethod, type SDKConfig, type TextResponse, configureSDK, createQueryString, getBaseUrl, getSDKConfig, handleApiRequest };
@@ -0,0 +1,5 @@
1
+ import '../chunk-PYYLHUV6.js';
2
+ export { BaseApi, createCrudApi, isAggregatePagination, isKeysetPagination, isOffsetPagination } from '../chunk-I5TIKUIQ.js';
3
+ export { configureSDK, createQueryString, getBaseUrl, getSDKConfig, handleApiRequest } from '../chunk-VR36QVX2.js';
4
+ //# sourceMappingURL=index.js.map
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"index.js"}
@@ -0,0 +1,107 @@
1
+ export { o as CreateDetailQueryOptions, n as CreateListQueryOptions, d as CrudActions, C as CrudApi, a as CrudHooksConfig, b as CrudHooksReturn, j as DEFAULT_QUERY_CONFIG, D as DetailOptions, m as DetailQueryResult, L as ListOptions, l as ListQueryResult, N as NavigateFn, e as NavigationOptions, P as PaginationData, Q as QueryConfig, k as QueryKeys, c as createCrudHooks, g as createDetailQuery, f as createListQuery, h as createQueryKeys, i as getItemId, u as updateListCache } from '../crud.factory-DyKaPHcU.js';
2
+ import * as _tanstack_react_query from '@tanstack/react-query';
3
+ import { QueryKey, QueryClient } from '@tanstack/react-query';
4
+
5
+ interface ToastHandler {
6
+ success: (message: string) => void;
7
+ error: (message: string) => void;
8
+ }
9
+ /**
10
+ * Configure the toast handler for mutations
11
+ * @example
12
+ * import { toast } from 'sonner';
13
+ * configureToast({ success: toast.success, error: toast.error });
14
+ */
15
+ declare function configureToast(handler: ToastHandler): void;
16
+ /**
17
+ * Get the current toast handler (for internal use)
18
+ */
19
+ declare function getToastHandler(): ToastHandler;
20
+ interface MutationMessages {
21
+ success?: string | ((data: unknown, variables: unknown) => string);
22
+ error?: string | ((error: Error, variables: unknown) => string);
23
+ }
24
+ interface MutationWithTransitionConfig<TData, TVariables> {
25
+ mutationFn: (variables: TVariables) => Promise<TData>;
26
+ invalidateQueries?: QueryKey[];
27
+ onSuccess?: (data: TData, variables: TVariables, context: unknown) => void;
28
+ onError?: (error: Error, variables: TVariables, context: unknown) => void;
29
+ messages?: MutationMessages;
30
+ useTransition?: boolean;
31
+ showToast?: boolean;
32
+ }
33
+ declare function useMutationWithTransition<TData, TVariables>(config: MutationWithTransitionConfig<TData, TVariables>): {
34
+ mutate: _tanstack_react_query.UseMutateFunction<TData, Error, TVariables, unknown>;
35
+ mutateAsync: _tanstack_react_query.UseMutateAsyncFunction<TData, Error, TVariables, unknown>;
36
+ isLoading: boolean;
37
+ isPending: boolean;
38
+ isSuccess: boolean;
39
+ error: Error | null;
40
+ data: TData | undefined;
41
+ reset: () => void;
42
+ };
43
+ interface MutationWithOptimisticConfig<TData, TVariables> {
44
+ mutationFn: (variables: TVariables) => Promise<TData>;
45
+ queryKeys?: QueryKey[];
46
+ optimisticUpdate?: (oldData: unknown, variables: TVariables) => unknown;
47
+ messages?: MutationMessages;
48
+ onSuccess?: (data: TData, variables: TVariables, context: unknown) => void;
49
+ onError?: (error: Error, variables: TVariables, context: unknown) => void;
50
+ showToast?: boolean;
51
+ }
52
+ declare function useMutationWithOptimistic<TData, TVariables>(config: MutationWithOptimisticConfig<TData, TVariables>): {
53
+ mutate: _tanstack_react_query.UseMutateFunction<TData, Error, TVariables, {
54
+ previousData: {
55
+ queryKey: readonly unknown[];
56
+ data: unknown;
57
+ }[];
58
+ }>;
59
+ mutateAsync: _tanstack_react_query.UseMutateAsyncFunction<TData, Error, TVariables, {
60
+ previousData: {
61
+ queryKey: readonly unknown[];
62
+ data: unknown;
63
+ }[];
64
+ }>;
65
+ isLoading: boolean;
66
+ isPending: boolean;
67
+ isSuccess: boolean;
68
+ error: Error | null;
69
+ data: TData | undefined;
70
+ reset: () => void;
71
+ };
72
+ interface CreateOptimisticMutationConfig<TData, TVariables> {
73
+ mutationFn: (variables: TVariables) => Promise<TData>;
74
+ queryClient: QueryClient;
75
+ queryKeys: QueryKey[];
76
+ optimisticUpdate?: (oldData: unknown, variables: TVariables) => unknown;
77
+ onSuccess?: (data: TData, variables: TVariables, context: unknown) => void;
78
+ onError?: (error: Error, variables: TVariables, context: unknown) => void;
79
+ messages?: MutationMessages;
80
+ }
81
+ declare function createOptimisticMutation<TData, TVariables>({ mutationFn, queryClient, queryKeys, optimisticUpdate, onSuccess, onError, messages, }: CreateOptimisticMutationConfig<TData, TVariables>): _tanstack_react_query.UseMutationResult<TData, Error, TVariables, {
82
+ previous: {
83
+ key: readonly unknown[];
84
+ data: [readonly unknown[], unknown][];
85
+ }[];
86
+ }>;
87
+ declare const QUERY_CONFIGS: {
88
+ readonly realtime: {
89
+ readonly staleTime: 20000;
90
+ readonly refetchInterval: 30000;
91
+ };
92
+ readonly frequent: {
93
+ readonly staleTime: 60000;
94
+ readonly refetchInterval: false;
95
+ };
96
+ readonly stable: {
97
+ readonly staleTime: 300000;
98
+ readonly refetchInterval: false;
99
+ };
100
+ readonly static: {
101
+ readonly staleTime: 600000;
102
+ readonly refetchInterval: false;
103
+ };
104
+ };
105
+ declare const createMessage: <T>(fn: T) => T;
106
+
107
+ export { type CreateOptimisticMutationConfig, type MutationMessages, type MutationWithOptimisticConfig, type MutationWithTransitionConfig, QUERY_CONFIGS, type ToastHandler, configureToast, createMessage, createOptimisticMutation, getToastHandler, useMutationWithOptimistic, useMutationWithTransition };
@@ -0,0 +1,5 @@
1
+ "use client";
2
+ export { DEFAULT_QUERY_CONFIG, createCrudHooks, createDetailQuery, createListQuery, createQueryKeys, getItemId, updateListCache } from '../chunk-B6MPVOV7.js';
3
+ export { QUERY_CONFIGS, configureToast, createMessage, createOptimisticMutation, getToastHandler, useMutationWithOptimistic, useMutationWithTransition } from '../chunk-U3XT35GZ.js';
4
+ //# sourceMappingURL=react.js.map
5
+ //# sourceMappingURL=react.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"react.js"}