@softimist/api 1.0.2 → 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +19 -9
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +21 -6
- package/dist/index.d.ts +21 -6
- package/dist/index.js +19 -9
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -268,6 +268,12 @@ var BaseApiClient = class {
|
|
|
268
268
|
});
|
|
269
269
|
return response.data;
|
|
270
270
|
}
|
|
271
|
+
async export(url, config) {
|
|
272
|
+
return this.axiosInstance.get(url, {
|
|
273
|
+
responseType: "arraybuffer",
|
|
274
|
+
...config
|
|
275
|
+
});
|
|
276
|
+
}
|
|
271
277
|
/**
|
|
272
278
|
* Get the underlying axios instance for advanced usage
|
|
273
279
|
*/
|
|
@@ -341,14 +347,12 @@ function useApi(httpClient, url, options = {}) {
|
|
|
341
347
|
...restOptions
|
|
342
348
|
});
|
|
343
349
|
}
|
|
344
|
-
function useApiAction(
|
|
350
|
+
function useApiAction(options) {
|
|
345
351
|
const { action, showToast = true, invalidateQueries, onSuccess, onError } = options;
|
|
346
|
-
const [isExecuted, setIsExecuted] = (0, import_react.useState)(false);
|
|
347
352
|
const mutation = (0, import_react_query2.useMutation)({
|
|
348
353
|
mutationFn: action,
|
|
349
354
|
onSuccess: (res) => {
|
|
350
355
|
onSuccess?.(res.data);
|
|
351
|
-
setIsExecuted(true);
|
|
352
356
|
if (showToast) {
|
|
353
357
|
import_sonner.toast.success(res.message || "Success");
|
|
354
358
|
}
|
|
@@ -366,15 +370,21 @@ function useApiAction(httpClient, options) {
|
|
|
366
370
|
}
|
|
367
371
|
}
|
|
368
372
|
});
|
|
369
|
-
const execute = () => {
|
|
370
|
-
mutation.mutate();
|
|
371
|
-
};
|
|
372
373
|
return {
|
|
374
|
+
/** execute mutation */
|
|
375
|
+
execute: mutation.mutate,
|
|
376
|
+
/** async version if needed */
|
|
377
|
+
executeAsync: mutation.mutateAsync,
|
|
378
|
+
/** states */
|
|
373
379
|
isLoading: mutation.isPending,
|
|
374
|
-
|
|
380
|
+
isSuccess: mutation.isSuccess,
|
|
381
|
+
isError: mutation.isError,
|
|
382
|
+
isExecuted: mutation.status !== "idle",
|
|
383
|
+
/** data & error */
|
|
375
384
|
data: mutation.data?.data,
|
|
376
|
-
|
|
377
|
-
|
|
385
|
+
error: mutation.error ?? void 0,
|
|
386
|
+
/** reset to idle */
|
|
387
|
+
reset: mutation.reset
|
|
378
388
|
};
|
|
379
389
|
}
|
|
380
390
|
var parseAsFilterArray = (0, import_nuqs.createParser)({
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/client.ts","../src/hooks.ts","../src/tanstack-query.tsx","../src/utils.ts"],"sourcesContent":["/**\n * @softimist/api - Shared API Types, Interfaces, and Hooks\n *\n * Main exports for the API package\n */\n\n// Server Response Types (Backend API)\nexport type { ServerResponse, ServerPaginatedResponse, PaginationMeta } from './types';\n\n// Hook Return Types (Client-side React Hooks)\nexport type { UsePaginatedApiReturn } from './types';\n\n// HTTP Client Abstraction\nexport type { HttpClient, HttpResponse, PaginationOptions, UsePaginatedApiHook } from './types';\n\n// Filter Types\nexport type {\n\tFilter,\n\tSelectFilter,\n\tMultiSelectFilter,\n\tDateFilter,\n\tBooleanFilter,\n\tNumberFilter,\n\tRangeFilter,\n\tStringFilter,\n} from './filter';\n\n// Base API Client\nexport { BaseApiClient, type BaseApiClientConfig, type RequestConfig } from './client';\n\n// React Hooks\nexport { useApi, useApiAction, usePaginatedApi, useMockPaginatedApi } from './hooks';\n\n// Utility Functions\nexport { getErrorMessage, getSuccessMessage } from './utils';\n\n// TanStack Query\nexport { QueryProvider, makeQueryClient, getQueryClient } from './tanstack-query';\n\nexport { useInfiniteQuery, useQuery } from '@tanstack/react-query';\n","/**\n * @softimist/api - Base API Client\n *\n * Base class for API clients that can be extended by module-specific implementations.\n * Uses axios for HTTP requests and provides common functionality like authentication,\n * error handling, and request/response interceptors.\n *\n * All HTTP methods return unwrapped server response data directly (e.g., ServerResponse<T>).\n */\n\nimport axios, { type AxiosInstance, type AxiosRequestConfig } from \"axios\";\nimport type { HttpClient } from \"./types\";\n\n/**\n * Configuration options for BaseApiClient\n */\nexport interface BaseApiClientConfig {\n\tbaseURL?: string;\n\tgetAuthToken?: () => string | null;\n\tgetRefreshToken?: () => string | null;\n\tsetAuthToken?: (token: string) => void;\n\tsetRefreshToken?: (token: string) => void;\n\tclearAuthTokens?: () => void;\n\trefreshTokenUrl?: string;\n\ttimeout?: number;\n\theaders?: Record<string, string>;\n}\n\n/**\n * Request configuration passed to HTTP methods\n */\nexport interface RequestConfig {\n\theaders?: Record<string, string>;\n\tparams?: Record<string, any>;\n\t[key: string]: any;\n}\n\n/**\n * Base API Client class\n * Provides common HTTP functionality using axios that can be extended by module-specific clients\n *\n * @example\n * ```ts\n * class WebsiteApiClient extends BaseApiClient {\n * async getPages(): Promise<ServerPaginatedResponse<Page>> {\n * return this.get<ServerPaginatedResponse<Page>>('/api/v1/website/pages');\n * }\n * }\n * ```\n */\nexport class BaseApiClient implements HttpClient {\n\tprotected axiosInstance: AxiosInstance;\n\tprotected getAuthToken?: () => string | null;\n\tprotected getRefreshToken?: () => string | null;\n\tprotected setAuthToken?: (token: string) => void;\n\tprotected setRefreshToken?: (token: string) => void;\n\tprotected clearAuthTokens?: () => void;\n\tprotected refreshTokenUrl?: string;\n\tprivate isRefreshing = false;\n\tprivate failedQueue: Array<{\n\t\tresolve: (value?: any) => void;\n\t\treject: (error?: any) => void;\n\t}> = [];\n\n\tconstructor(config: BaseApiClientConfig = {}) {\n\t\tconst defaultHeaders = {\n\t\t\t\"Content-Type\": \"application/json\",\n\t\t\tAccept: \"application/json\",\n\t\t\t...config.headers,\n\t\t};\n\n\t\tthis.axiosInstance = axios.create({\n\t\t\tbaseURL: config.baseURL || \"\",\n\t\t\ttimeout: config.timeout || 30000,\n\t\t\theaders: defaultHeaders,\n\t\t});\n\n\t\tthis.getAuthToken = config.getAuthToken;\n\t\tthis.getRefreshToken = config.getRefreshToken;\n\t\tthis.setAuthToken = config.setAuthToken;\n\t\tthis.setRefreshToken = config.setRefreshToken;\n\t\tthis.clearAuthTokens = config.clearAuthTokens;\n\t\tthis.refreshTokenUrl =\n\t\t\tconfig.refreshTokenUrl || `${config.baseURL || \"\"}/v1/auth/refresh`;\n\n\t\t// Set up request interceptor for authentication\n\t\tthis.axiosInstance.interceptors.request.use(\n\t\t\t(requestConfig) => {\n\t\t\t\tif (this.getAuthToken) {\n\t\t\t\t\tconst token = this.getAuthToken();\n\t\t\t\t\tif (token) {\n\t\t\t\t\t\trequestConfig.headers.Authorization = `Bearer ${token}`;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn requestConfig;\n\t\t\t},\n\t\t\t(error) => {\n\t\t\t\treturn Promise.reject(error);\n\t\t\t},\n\t\t);\n\n\t\t// Set up response interceptor for error handling and token refresh\n\t\tthis.axiosInstance.interceptors.response.use(\n\t\t\t(response) => response,\n\t\t\tasync (error) => {\n\t\t\t\tconst originalRequest = error.config;\n\n\t\t\t\t// Handle 401 errors with token refresh\n\t\t\t\tif (\n\t\t\t\t\terror.response?.status === 401 &&\n\t\t\t\t\t!originalRequest._retry &&\n\t\t\t\t\tthis.getRefreshToken\n\t\t\t\t) {\n\t\t\t\t\tif (this.isRefreshing) {\n\t\t\t\t\t\t// If we're already refreshing, queue this request\n\t\t\t\t\t\treturn new Promise((resolve, reject) => {\n\t\t\t\t\t\t\tthis.failedQueue.push({ resolve, reject });\n\t\t\t\t\t\t})\n\t\t\t\t\t\t\t.then((token) => {\n\t\t\t\t\t\t\t\toriginalRequest.headers.Authorization = `Bearer ${token}`;\n\t\t\t\t\t\t\t\treturn this.axiosInstance(originalRequest);\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t.catch((err) => {\n\t\t\t\t\t\t\t\treturn Promise.reject(err);\n\t\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\toriginalRequest._retry = true;\n\t\t\t\t\tthis.isRefreshing = true;\n\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst accessToken = await this.refreshAuthToken();\n\n\t\t\t\t\t\t// Update the original request with new token\n\t\t\t\t\t\toriginalRequest.headers.Authorization = `Bearer ${accessToken}`;\n\n\t\t\t\t\t\t// Process queued requests\n\t\t\t\t\t\tthis.processQueue(null, accessToken);\n\t\t\t\t\t\tthis.isRefreshing = false;\n\n\t\t\t\t\t\t// Retry the original request\n\t\t\t\t\t\treturn this.axiosInstance(originalRequest);\n\t\t\t\t\t} catch (refreshError) {\n\t\t\t\t\t\t// Refresh token is invalid, clear all tokens\n\t\t\t\t\t\tthis.processQueue(refreshError, null);\n\t\t\t\t\t\tthis.isRefreshing = false;\n\t\t\t\t\t\treturn Promise.reject(this.handleError(refreshError));\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn Promise.reject(this.handleError(error));\n\t\t\t},\n\t\t);\n\t}\n\n\t/**\n\t * Process queued requests after token refresh\n\t */\n\tprivate processQueue(error: any, token: string | null = null) {\n\t\tthis.failedQueue.forEach(({ resolve, reject }) => {\n\t\t\tif (error) {\n\t\t\t\treject(error);\n\t\t\t} else {\n\t\t\t\tresolve(token);\n\t\t\t}\n\t\t});\n\t\tthis.failedQueue = [];\n\t}\n\n\t/**\n\t * Refresh authentication token\n\t */\n\tprivate async refreshAuthToken(): Promise<string> {\n\t\tif (!this.getRefreshToken) {\n\t\t\tthrow new Error(\"No refresh token function provided\");\n\t\t}\n\n\t\tconst refreshToken = this.getRefreshToken();\n\t\tif (!refreshToken) {\n\t\t\tif (this.clearAuthTokens) {\n\t\t\t\tthis.clearAuthTokens();\n\t\t\t}\n\t\t\tthrow new Error(\"No refresh token available\");\n\t\t}\n\n\t\ttry {\n\t\t\t// Use a fresh axios instance for refresh token request to avoid circular interceptor issues\n\t\t\tconst response = await axios.post(\n\t\t\t\tthis.refreshTokenUrl!,\n\t\t\t\t{\n\t\t\t\t\trefresh_token: refreshToken,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tbaseURL: \"\", // Use absolute URL or empty to avoid baseURL duplication\n\t\t\t\t},\n\t\t\t);\n\n\t\t\tconst { access_token, refresh_token } = response.data;\n\n\t\t\tif (this.setAuthToken) {\n\t\t\t\tthis.setAuthToken(access_token);\n\t\t\t}\n\t\t\tif (refresh_token && this.setRefreshToken) {\n\t\t\t\tthis.setRefreshToken(refresh_token);\n\t\t\t}\n\n\t\t\treturn access_token;\n\t\t} catch (error) {\n\t\t\t// Refresh token is invalid, clear all tokens\n\t\t\tif (this.clearAuthTokens) {\n\t\t\t\tthis.clearAuthTokens();\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\t/**\n\t * Handle request errors\n\t */\n\tprotected handleError(error: any): Error {\n\t\tif (error.response) {\n\t\t\t// Server responded with error status\n\t\t\tconst message =\n\t\t\t\terror.response.data?.message ||\n\t\t\t\terror.response.data?.error ||\n\t\t\t\terror.message ||\n\t\t\t\t\"An unknown error occurred\";\n\t\t\terror.message = message;\n\t\t\treturn error;\n\t\t}\n\t\treturn error;\n\t}\n\n\t/**\n\t * Make HTTP GET request\n\t * Returns unwrapped server response data\n\t */\n\tasync get<T = any>(url: string, config?: RequestConfig): Promise<T> {\n\t\tconst axiosConfig: AxiosRequestConfig = {\n\t\t\tparams: config?.params,\n\t\t\theaders: config?.headers,\n\t\t\t...config,\n\t\t};\n\t\tdelete axiosConfig.params;\n\t\tdelete axiosConfig.headers;\n\n\t\tconst response = await this.axiosInstance.get<T>(url, {\n\t\t\t...axiosConfig,\n\t\t\tparams: config?.params,\n\t\t\theaders: config?.headers,\n\t\t});\n\n\t\treturn response.data;\n\t}\n\n\t/**\n\t * Make HTTP POST request\n\t * Returns unwrapped server response data\n\t */\n\tasync post<T = any>(\n\t\turl: string,\n\t\tdata?: any,\n\t\tconfig?: RequestConfig,\n\t): Promise<T> {\n\t\tconst axiosConfig: AxiosRequestConfig = {\n\t\t\theaders: config?.headers,\n\t\t\t...config,\n\t\t};\n\t\tdelete axiosConfig.headers;\n\n\t\tconst response = await this.axiosInstance.post<T>(url, data, {\n\t\t\t...axiosConfig,\n\t\t\theaders: config?.headers,\n\t\t});\n\n\t\treturn response.data;\n\t}\n\n\t/**\n\t * Make HTTP PATCH request\n\t * Returns unwrapped server response data\n\t */\n\tasync patch<T = any>(\n\t\turl: string,\n\t\tdata?: any,\n\t\tconfig?: RequestConfig,\n\t): Promise<T> {\n\t\tconst axiosConfig: AxiosRequestConfig = {\n\t\t\theaders: config?.headers,\n\t\t\t...config,\n\t\t};\n\t\tdelete axiosConfig.headers;\n\n\t\tconst response = await this.axiosInstance.patch<T>(url, data, {\n\t\t\t...axiosConfig,\n\t\t\theaders: config?.headers,\n\t\t});\n\n\t\treturn response.data;\n\t}\n\n\t/**\n\t * Make HTTP PUT request\n\t * Returns unwrapped server response data\n\t */\n\tasync put<T = any>(\n\t\turl: string,\n\t\tdata?: any,\n\t\tconfig?: RequestConfig,\n\t): Promise<T> {\n\t\tconst axiosConfig: AxiosRequestConfig = {\n\t\t\theaders: config?.headers,\n\t\t\t...config,\n\t\t};\n\t\tdelete axiosConfig.headers;\n\n\t\tconst response = await this.axiosInstance.put<T>(url, data, {\n\t\t\t...axiosConfig,\n\t\t\theaders: config?.headers,\n\t\t});\n\n\t\treturn response.data;\n\t}\n\n\t/**\n\t * Make HTTP DELETE request\n\t * Returns unwrapped server response data\n\t */\n\tasync delete<T = any>(url: string, config?: RequestConfig): Promise<T> {\n\t\tconst axiosConfig: AxiosRequestConfig = {\n\t\t\theaders: config?.headers,\n\t\t\t...config,\n\t\t};\n\t\tdelete axiosConfig.headers;\n\n\t\tconst response = await this.axiosInstance.delete<T>(url, {\n\t\t\t...axiosConfig,\n\t\t\theaders: config?.headers,\n\t\t});\n\n\t\treturn response.data;\n\t}\n\n\t/**\n\t * Get the underlying axios instance for advanced usage\n\t */\n\tget axios(): AxiosInstance {\n\t\treturn this.axiosInstance;\n\t}\n\n\t/**\n\t * Create a new client instance with a different baseURL\n\t * Useful for server-side requests or different API endpoints\n\t */\n\twithBaseURL(baseURL: string): this {\n\t\tconst ConfigClass = this.constructor as new (\n\t\t\tconfig: BaseApiClientConfig,\n\t\t) => this;\n\n\t\t// Create a fresh copy of headers to avoid reference issues\n\t\tconst headers = { ...this.axiosInstance.defaults.headers } as Record<\n\t\t\tstring,\n\t\t\tstring\n\t\t>;\n\n\t\treturn new ConfigClass({\n\t\t\tbaseURL,\n\t\t\tgetAuthToken: this.getAuthToken,\n\t\t\tgetRefreshToken: this.getRefreshToken,\n\t\t\tsetAuthToken: this.setAuthToken,\n\t\t\tsetRefreshToken: this.setRefreshToken,\n\t\t\tclearAuthTokens: this.clearAuthTokens,\n\t\t\trefreshTokenUrl: this.refreshTokenUrl,\n\t\t\ttimeout: this.axiosInstance.defaults.timeout,\n\t\t\theaders,\n\t\t});\n\t}\n}\n","/**\n * @softimist/api - React Hooks for API interactions\n *\n * Generic hooks that work with any HttpClient implementation\n */\n'use client';\n\nimport { useQuery, useMutation, type QueryKey, type UseQueryOptions } from '@tanstack/react-query';\nimport { createParser, parseAsInteger, parseAsString, useQueryState } from 'nuqs';\nimport { useState } from 'react';\nimport { toast } from 'sonner';\nimport type {\n\tHttpClient,\n\tPaginationOptions,\n\tServerPaginatedResponse,\n\tServerResponse,\n\tUsePaginatedApiReturn,\n} from './types';\nimport type { Filter } from './filter';\nimport { getQueryClient } from './tanstack-query';\n\n/**\n * Hook for making simple API GET requests\n */\nexport function useApi<T>(\n\thttpClient: HttpClient,\n\turl: string | null,\n\toptions: Omit<UseQueryOptions<ServerResponse<T>>, 'queryKey' | 'queryFn' | 'enabled'> & {\n\t\tqueryKey?: QueryKey;\n\t\tenabled?: boolean;\n\t} = {},\n) {\n\tconst { queryKey, enabled = true, ...restOptions } = options;\n\n\treturn useQuery<ServerResponse<T>>({\n\t\tqueryKey: queryKey || [url],\n\t\tqueryFn: async () => {\n\t\t\tif (!url) throw new Error('URL is required');\n\t\t\treturn httpClient.get<ServerResponse<T>>(url);\n\t\t},\n\t\tenabled: url !== null && enabled,\n\t\t...restOptions,\n\t});\n}\n\n/**\n * Hook for making API mutations (POST, PATCH, PUT, DELETE) with toast notifications\n */\nexport function useApiAction<T>(\n\thttpClient: HttpClient,\n\toptions: {\n\t\taction: () => Promise<ServerResponse<T>>;\n\t\tshowToast?: boolean;\n\t\tinvalidateQueries?: QueryKey[];\n\t\tonSuccess?: (data: T) => void;\n\t\tonError?: (error: Error) => void;\n\t},\n) {\n\tconst { action, showToast = true, invalidateQueries, onSuccess, onError } = options;\n\tconst [isExecuted, setIsExecuted] = useState(false);\n\n\tconst mutation = useMutation({\n\t\tmutationFn: action,\n\n\t\tonSuccess: (res) => {\n\t\t\tonSuccess?.(res.data);\n\t\t\tsetIsExecuted(true);\n\t\t\tif (showToast) {\n\t\t\t\ttoast.success(res.message || 'Success');\n\t\t\t}\n\t\t\tif (invalidateQueries && invalidateQueries.length > 0) {\n\t\t\t\tconst queryClient = getQueryClient();\n\t\t\t\tinvalidateQueries.forEach((queryKey) => {\n\t\t\t\t\tqueryClient.invalidateQueries({ queryKey });\n\t\t\t\t});\n\t\t\t}\n\t\t},\n\t\tonError: (err: Error) => {\n\t\t\tonError?.(err);\n\t\t\tif (showToast) {\n\t\t\t\ttoast.error(err.message || 'An error occurred');\n\t\t\t}\n\t\t},\n\t});\n\n\tconst execute = () => {\n\t\tmutation.mutate();\n\t};\n\n\treturn {\n\t\tisLoading: mutation.isPending,\n\t\terror: mutation.error ?? undefined,\n\t\tdata: mutation.data?.data,\n\t\texecute,\n\t\tisExecuted,\n\t};\n}\n\nconst parseAsFilterArray = createParser<Filter[]>({\n\tparse: (value) => {\n\t\treturn JSON.parse(value);\n\t},\n\tserialize: (value) => {\n\t\treturn JSON.stringify(value);\n\t},\n});\n\nfunction usePaginationState(options: PaginationOptions) {\n\tconst { persist = true, params: defaultParams } = options;\n\tconst defaultPerPage = (defaultParams?.per_page as number) || 20;\n\tconst defaultPage = (defaultParams?.page as number) || 1;\n\tconst [perPageQuery, setPerPageQuery] = useQueryState(\n\t\t'per_page',\n\t\tparseAsInteger.withDefault(defaultPerPage),\n\t);\n\tconst [pageQuery, setPageQuery] = useQueryState('page', parseAsInteger.withDefault(defaultPage));\n\tconst [searchQuery, setSearchQuery] = useQueryState('search', parseAsString.withDefault(''));\n\tconst [filtersQuery, setFiltersQuery] = useQueryState(\n\t\t'filters',\n\t\tparseAsFilterArray.withDefault([]),\n\t);\n\tconst [sortQuery, setSortQuery] = useQueryState('sort', parseAsString.withDefault(''));\n\n\tconst [perPageState, setPerPageState] = useState<number>(defaultPerPage);\n\tconst [pageState, setPageState] = useState<number>(defaultPage);\n\tconst [searchState, setSearchState] = useState<string>('');\n\tconst [filtersState, setFiltersState] = useState<Filter[]>([]);\n\tconst [sortState, setSortState] = useState<string>();\n\n\tconst perPage = persist ? perPageQuery : perPageState;\n\tconst page = persist ? pageQuery : pageState;\n\tconst search = persist ? searchQuery : searchState;\n\tconst filters = persist ? filtersQuery : filtersState;\n\tconst sort = persist ? sortQuery : sortState;\n\n\tconst setPerPage = (value: number | ((prev: number) => number)) => {\n\t\tif (persist) {\n\t\t\tsetPerPageQuery(value);\n\t\t} else {\n\t\t\tsetPerPageState(value);\n\t\t}\n\t};\n\n\tconst setPage = (value: number | ((prev: number) => number)) => {\n\t\tif (persist) {\n\t\t\tsetPageQuery(value);\n\t\t} else {\n\t\t\tsetPageState(value);\n\t\t}\n\t};\n\n\tconst setSearch = (value: string | ((prev: string) => string)) => {\n\t\tif (persist) {\n\t\t\tsetSearchQuery(value);\n\t\t} else {\n\t\t\tsetSearchState(value);\n\t\t}\n\t};\n\n\tconst setFilters = (value: Filter[] | ((prev: Filter[]) => Filter[])) => {\n\t\tif (persist) {\n\t\t\tsetFiltersQuery(value);\n\t\t} else {\n\t\t\tsetFiltersState(value);\n\t\t}\n\t};\n\n\tconst setSort = (value: string | ((prev: string) => string)) => {\n\t\tif (persist) {\n\t\t\tsetSortQuery(value);\n\t\t} else {\n\t\t\tsetSortState(typeof value === 'function' ? value(sortState || '') : value);\n\t\t}\n\t};\n\n\tconst getParams = () => {\n\t\tconst params = new URLSearchParams();\n\t\tif (defaultParams) {\n\t\t\tObject.entries(defaultParams).forEach(([key, value]) => {\n\t\t\t\tif (value !== undefined) {\n\t\t\t\t\tparams.set(key, value.toString());\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t\tif (perPage) params.set('per_page', perPage.toString());\n\t\tif (page) params.set('page', page.toString());\n\t\tif (search) params.set('search', search);\n\t\tif (sort) {\n\t\t\tconst [sortBy, sortDirection] = sort.split(':');\n\t\t\tif (sortBy) params.set('sort_by', sortBy);\n\t\t\tif (sortDirection) params.set('sort_dir', sortDirection);\n\t\t}\n\t\tfilters?.forEach((filter) => {\n\t\t\tif (Array.isArray(filter.value)) {\n\t\t\t\tfilter.value.forEach((v) => {\n\t\t\t\t\tparams.append(filter.key, v.toString());\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tparams.set(filter.key, filter.value.toString());\n\t\t\t}\n\t\t});\n\t\treturn params;\n\t};\n\n\treturn {\n\t\tperPage,\n\t\tpage,\n\t\tsearch,\n\t\tfilters,\n\t\tsort,\n\t\tsetPerPage,\n\t\tsetPage,\n\t\tsetSearch,\n\t\tsetFilters,\n\t\tsetSort,\n\t\tgetParams,\n\t};\n}\n\n/**\n * Hook for making paginated API requests with URL state management\n */\nexport function usePaginatedApi<T>(\n\thttpClient: HttpClient,\n\tpath: string | null,\n\toptions: PaginationOptions = {},\n): UsePaginatedApiReturn<T> {\n\tconst {\n\t\tperPage,\n\t\tpage,\n\t\tsearch,\n\t\tfilters,\n\t\tsort,\n\t\tsetPerPage,\n\t\tsetPage,\n\t\tsetSearch,\n\t\tsetFilters,\n\t\tsetSort,\n\t\tgetParams,\n\t} = usePaginationState(options);\n\n\tconst getUrl = (): string | null => {\n\t\tif (!path) return null;\n\t\tconst params = getParams();\n\t\treturn params.size === 0 ? path : `${path}?${params.toString()}`;\n\t};\n\n\tconst url = getUrl();\n\n\tconst { data, isLoading, error, refetch, isSuccess, isFetching } = useQuery({\n\t\tqueryKey: [path, options, page, perPage, search, filters, sort],\n\t\tqueryFn: async () => {\n\t\t\tif (!url) throw new Error('URL is required');\n\t\t\treturn httpClient.get<ServerPaginatedResponse<T>>(url);\n\t\t},\n\t\tenabled: !!url,\n\t});\n\n\tfunction getBulkActionUrl(\n\t\taction: string,\n\t\tadditionalFilters?: Record<string, string | string[]>,\n\t): string {\n\t\tconst params = getParams();\n\t\tparams.delete('page');\n\t\tparams.delete('per_page');\n\t\tObject.entries(additionalFilters || {}).forEach(([key, value]) => {\n\t\t\tif (value === undefined) {\n\t\t\t\tparams.delete(key);\n\t\t\t} else if (Array.isArray(value)) {\n\t\t\t\tvalue.forEach((v) => {\n\t\t\t\t\tparams.append(key, v);\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tparams.set(key, value);\n\t\t\t}\n\t\t});\n\t\tif (params.size === 0) return `${path}/${action}`;\n\t\treturn `${path}/${action}?${params.toString()}`;\n\t}\n\n\tfunction setFilter(key: string, value: any) {\n\t\tif (value === undefined) {\n\t\t\tremoveFilter(key);\n\t\t\treturn;\n\t\t}\n\t\tconst index = filters.findIndex((filter) => filter.key === key);\n\t\tif (index === -1) {\n\t\t\tsetFilters([...filters, { key, value }]);\n\t\t} else {\n\t\t\tsetFilters([...filters.slice(0, index), { key, value }, ...filters.slice(index + 1)]);\n\t\t}\n\t}\n\n\tfunction removeFilter(key: string) {\n\t\tsetFilters(filters.filter((filter) => filter.key !== key));\n\t}\n\n\tfunction getFilterValue(key: string) {\n\t\treturn filters.find((filter) => filter.key === key)?.value;\n\t}\n\n\tfunction resetFilters() {\n\t\tsetFilters([]);\n\t}\n\n\treturn {\n\t\tmessage: data?.message || '',\n\t\tdata: data?.data || [],\n\t\tpagination: data?.pagination,\n\t\tisLoading,\n\t\tisSuccess,\n\t\tisFetching,\n\t\terror: error as Error | null,\n\t\tmutate: refetch,\n\t\tpage,\n\t\tsetPage,\n\t\tperPage,\n\t\tsetPerPage,\n\t\tsearch,\n\t\tsetSearch,\n\t\tfilters,\n\t\tsetFilters,\n\t\tsetFilter,\n\t\tremoveFilter,\n\t\tgetFilterValue,\n\t\tresetFilters,\n\t\tgetBulkActionUrl,\n\t\tsort,\n\t\tsetSort,\n\t};\n}\n\n/**\n * Mock hook for testing/development\n * Returns a mock paginated response with the provided data\n */\nexport function useMockPaginatedApi<T>(data: T[]): UsePaginatedApiReturn<T> {\n\treturn {\n\t\tdata,\n\t\tpagination: {\n\t\t\ttotal: data.length,\n\t\t\tper_page: 10,\n\t\t\tcurrent_page: 1,\n\t\t\ttotal_pages: Math.ceil(data.length / 10),\n\t\t\tfrom: 1,\n\t\t\tto: data.length,\n\t\t},\n\t\tmessage: 'Data fetched successfully',\n\t\tisLoading: false,\n\t\tisSuccess: true,\n\t\tisFetching: false,\n\t\tmutate: () => {},\n\t\tpage: 1,\n\t\tsetPage: () => {},\n\t\tperPage: 10,\n\t\tsetPerPage: () => {},\n\t\tsearch: '',\n\t\tsetSearch: () => {},\n\t\tfilters: [],\n\t\tsetFilters: () => {},\n\t\tgetFilterValue: () => undefined,\n\t\tresetFilters: () => {},\n\t\tsetFilter: () => {},\n\t\tremoveFilter: () => {},\n\t\tsort: '',\n\t\tsetSort: () => {},\n\t\tgetBulkActionUrl: () => '',\n\t};\n}\n","'use client';\n\nimport { QueryClient, QueryClientProvider } from '@tanstack/react-query';\nimport { ReactNode } from 'react';\n\nexport function makeQueryClient() {\n return new QueryClient({\n defaultOptions: {\n queries: {\n refetchOnWindowFocus: false,\n refetchOnReconnect: false,\n },\n },\n });\n}\n\nlet browserQueryClient: QueryClient | undefined = undefined;\n\nexport function getQueryClient() {\n if (typeof window === 'undefined') {\n return makeQueryClient();\n } else {\n if (!browserQueryClient) browserQueryClient = makeQueryClient();\n return browserQueryClient;\n }\n}\n\n\nexport function QueryProvider({ children }: { children: ReactNode }) {\n const queryClient = getQueryClient();\n\n return <QueryClientProvider client={queryClient}>{children}</QueryClientProvider>;\n}\n","/**\n * @softimist/api - Utility Functions\n * \n * Common utility functions for API error and response handling\n */\n\ntype ApiErrorLike = {\n message?: unknown;\n response?: {\n data?: {\n message?: unknown;\n error?: unknown;\n };\n };\n};\n\n/**\n * Extract error message from various error types\n */\nexport function getErrorMessage(error: unknown): string {\n const err = error as ApiErrorLike | null | undefined;\n \n // Try to get message from API response\n const apiMessage = err?.response?.data?.message;\n if (typeof apiMessage === 'string' && apiMessage.trim() !== '') {\n return apiMessage;\n }\n\n // Try to get error from API response\n const apiError = err?.response?.data?.error;\n if (typeof apiError === 'string' && apiError.trim() !== '') {\n return apiError;\n }\n\n // Try to get message from error object\n const message = err?.message;\n if (typeof message === 'string' && message.trim() !== '') {\n return message;\n }\n\n // Try Error instance message\n if (error instanceof Error && error.message.trim() !== '') {\n return error.message;\n }\n\n return 'Something went wrong';\n}\n\n/**\n * Extract success message from API response\n */\nexport function getSuccessMessage(response: any, defaultMessage?: string): string {\n return response?.data?.message || defaultMessage || 'Success';\n}\n"],"mappings":"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","names":["axios","import_react_query","import_react_query"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/client.ts","../src/hooks.ts","../src/tanstack-query.tsx","../src/utils.ts"],"sourcesContent":["/**\n * @softimist/api - Shared API Types, Interfaces, and Hooks\n *\n * Main exports for the API package\n */\n\n// Server Response Types (Backend API)\nexport type { ServerResponse, ServerPaginatedResponse, PaginationMeta } from './types';\n\n// Hook Return Types (Client-side React Hooks)\nexport type { UsePaginatedApiReturn } from './types';\n\n// HTTP Client Abstraction\nexport type { HttpClient, HttpResponse, PaginationOptions, UsePaginatedApiHook } from './types';\n\n// Filter Types\nexport type {\n\tFilter,\n\tSelectFilter,\n\tMultiSelectFilter,\n\tDateFilter,\n\tBooleanFilter,\n\tNumberFilter,\n\tRangeFilter,\n\tStringFilter,\n} from './filter';\n\n// Base API Client\nexport { BaseApiClient, type BaseApiClientConfig, type RequestConfig } from './client';\n\n// React Hooks\nexport { useApi, useApiAction, usePaginatedApi, useMockPaginatedApi } from './hooks';\n\n// Utility Functions\nexport { getErrorMessage, getSuccessMessage } from './utils';\n\n// TanStack Query\nexport { QueryProvider, makeQueryClient, getQueryClient } from './tanstack-query';\n\nexport { useInfiniteQuery, useQuery } from '@tanstack/react-query';\n","/**\n * @softimist/api - Base API Client\n *\n * Base class for API clients that can be extended by module-specific implementations.\n * Uses axios for HTTP requests and provides common functionality like authentication,\n * error handling, and request/response interceptors.\n *\n * All HTTP methods return unwrapped server response data directly (e.g., ServerResponse<T>).\n */\n\nimport axios, { AxiosResponse, type AxiosInstance, type AxiosRequestConfig } from 'axios';\nimport type { HttpClient } from './types';\n\n/**\n * Configuration options for BaseApiClient\n */\nexport interface BaseApiClientConfig {\n\tbaseURL?: string;\n\tgetAuthToken?: () => string | null;\n\tgetRefreshToken?: () => string | null;\n\tsetAuthToken?: (token: string) => void;\n\tsetRefreshToken?: (token: string) => void;\n\tclearAuthTokens?: () => void;\n\trefreshTokenUrl?: string;\n\ttimeout?: number;\n\theaders?: Record<string, string>;\n}\n\n/**\n * Request configuration passed to HTTP methods\n */\nexport interface RequestConfig {\n\theaders?: Record<string, string>;\n\tparams?: Record<string, any>;\n\t[key: string]: any;\n}\n\n/**\n * Base API Client class\n * Provides common HTTP functionality using axios that can be extended by module-specific clients\n *\n * @example\n * ```ts\n * class WebsiteApiClient extends BaseApiClient {\n * async getPages(): Promise<ServerPaginatedResponse<Page>> {\n * return this.get<ServerPaginatedResponse<Page>>('/api/v1/website/pages');\n * }\n * }\n * ```\n */\nexport class BaseApiClient implements HttpClient {\n\tprotected axiosInstance: AxiosInstance;\n\tprotected getAuthToken?: () => string | null;\n\tprotected getRefreshToken?: () => string | null;\n\tprotected setAuthToken?: (token: string) => void;\n\tprotected setRefreshToken?: (token: string) => void;\n\tprotected clearAuthTokens?: () => void;\n\tprotected refreshTokenUrl?: string;\n\tprivate isRefreshing = false;\n\tprivate failedQueue: Array<{\n\t\tresolve: (value?: any) => void;\n\t\treject: (error?: any) => void;\n\t}> = [];\n\n\tconstructor(config: BaseApiClientConfig = {}) {\n\t\tconst defaultHeaders = {\n\t\t\t'Content-Type': 'application/json',\n\t\t\tAccept: 'application/json',\n\t\t\t...config.headers,\n\t\t};\n\n\t\tthis.axiosInstance = axios.create({\n\t\t\tbaseURL: config.baseURL || '',\n\t\t\ttimeout: config.timeout || 30000,\n\t\t\theaders: defaultHeaders,\n\t\t});\n\n\t\tthis.getAuthToken = config.getAuthToken;\n\t\tthis.getRefreshToken = config.getRefreshToken;\n\t\tthis.setAuthToken = config.setAuthToken;\n\t\tthis.setRefreshToken = config.setRefreshToken;\n\t\tthis.clearAuthTokens = config.clearAuthTokens;\n\t\tthis.refreshTokenUrl = config.refreshTokenUrl || `${config.baseURL || ''}/v1/auth/refresh`;\n\n\t\t// Set up request interceptor for authentication\n\t\tthis.axiosInstance.interceptors.request.use(\n\t\t\t(requestConfig) => {\n\t\t\t\tif (this.getAuthToken) {\n\t\t\t\t\tconst token = this.getAuthToken();\n\t\t\t\t\tif (token) {\n\t\t\t\t\t\trequestConfig.headers.Authorization = `Bearer ${token}`;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn requestConfig;\n\t\t\t},\n\t\t\t(error) => {\n\t\t\t\treturn Promise.reject(error);\n\t\t\t},\n\t\t);\n\n\t\t// Set up response interceptor for error handling and token refresh\n\t\tthis.axiosInstance.interceptors.response.use(\n\t\t\t(response) => response,\n\t\t\tasync (error) => {\n\t\t\t\tconst originalRequest = error.config;\n\n\t\t\t\t// Handle 401 errors with token refresh\n\t\t\t\tif (error.response?.status === 401 && !originalRequest._retry && this.getRefreshToken) {\n\t\t\t\t\tif (this.isRefreshing) {\n\t\t\t\t\t\t// If we're already refreshing, queue this request\n\t\t\t\t\t\treturn new Promise((resolve, reject) => {\n\t\t\t\t\t\t\tthis.failedQueue.push({ resolve, reject });\n\t\t\t\t\t\t})\n\t\t\t\t\t\t\t.then((token) => {\n\t\t\t\t\t\t\t\toriginalRequest.headers.Authorization = `Bearer ${token}`;\n\t\t\t\t\t\t\t\treturn this.axiosInstance(originalRequest);\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t.catch((err) => {\n\t\t\t\t\t\t\t\treturn Promise.reject(err);\n\t\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\toriginalRequest._retry = true;\n\t\t\t\t\tthis.isRefreshing = true;\n\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst accessToken = await this.refreshAuthToken();\n\n\t\t\t\t\t\t// Update the original request with new token\n\t\t\t\t\t\toriginalRequest.headers.Authorization = `Bearer ${accessToken}`;\n\n\t\t\t\t\t\t// Process queued requests\n\t\t\t\t\t\tthis.processQueue(null, accessToken);\n\t\t\t\t\t\tthis.isRefreshing = false;\n\n\t\t\t\t\t\t// Retry the original request\n\t\t\t\t\t\treturn this.axiosInstance(originalRequest);\n\t\t\t\t\t} catch (refreshError) {\n\t\t\t\t\t\t// Refresh token is invalid, clear all tokens\n\t\t\t\t\t\tthis.processQueue(refreshError, null);\n\t\t\t\t\t\tthis.isRefreshing = false;\n\t\t\t\t\t\treturn Promise.reject(this.handleError(refreshError));\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn Promise.reject(this.handleError(error));\n\t\t\t},\n\t\t);\n\t}\n\n\t/**\n\t * Process queued requests after token refresh\n\t */\n\tprivate processQueue(error: any, token: string | null = null) {\n\t\tthis.failedQueue.forEach(({ resolve, reject }) => {\n\t\t\tif (error) {\n\t\t\t\treject(error);\n\t\t\t} else {\n\t\t\t\tresolve(token);\n\t\t\t}\n\t\t});\n\t\tthis.failedQueue = [];\n\t}\n\n\t/**\n\t * Refresh authentication token\n\t */\n\tprivate async refreshAuthToken(): Promise<string> {\n\t\tif (!this.getRefreshToken) {\n\t\t\tthrow new Error('No refresh token function provided');\n\t\t}\n\n\t\tconst refreshToken = this.getRefreshToken();\n\t\tif (!refreshToken) {\n\t\t\tif (this.clearAuthTokens) {\n\t\t\t\tthis.clearAuthTokens();\n\t\t\t}\n\t\t\tthrow new Error('No refresh token available');\n\t\t}\n\n\t\ttry {\n\t\t\t// Use a fresh axios instance for refresh token request to avoid circular interceptor issues\n\t\t\tconst response = await axios.post(\n\t\t\t\tthis.refreshTokenUrl!,\n\t\t\t\t{\n\t\t\t\t\trefresh_token: refreshToken,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tbaseURL: '', // Use absolute URL or empty to avoid baseURL duplication\n\t\t\t\t},\n\t\t\t);\n\n\t\t\tconst { access_token, refresh_token } = response.data;\n\n\t\t\tif (this.setAuthToken) {\n\t\t\t\tthis.setAuthToken(access_token);\n\t\t\t}\n\t\t\tif (refresh_token && this.setRefreshToken) {\n\t\t\t\tthis.setRefreshToken(refresh_token);\n\t\t\t}\n\n\t\t\treturn access_token;\n\t\t} catch (error) {\n\t\t\t// Refresh token is invalid, clear all tokens\n\t\t\tif (this.clearAuthTokens) {\n\t\t\t\tthis.clearAuthTokens();\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\t/**\n\t * Handle request errors\n\t */\n\tprotected handleError(error: any): Error {\n\t\tif (error.response) {\n\t\t\t// Server responded with error status\n\t\t\tconst message =\n\t\t\t\terror.response.data?.message ||\n\t\t\t\terror.response.data?.error ||\n\t\t\t\terror.message ||\n\t\t\t\t'An unknown error occurred';\n\t\t\terror.message = message;\n\t\t\treturn error;\n\t\t}\n\t\treturn error;\n\t}\n\n\t/**\n\t * Make HTTP GET request\n\t * Returns unwrapped server response data\n\t */\n\tasync get<T = any>(url: string, config?: RequestConfig): Promise<T> {\n\t\tconst axiosConfig: AxiosRequestConfig = {\n\t\t\tparams: config?.params,\n\t\t\theaders: config?.headers,\n\t\t\t...config,\n\t\t};\n\t\tdelete axiosConfig.params;\n\t\tdelete axiosConfig.headers;\n\n\t\tconst response = await this.axiosInstance.get<T>(url, {\n\t\t\t...axiosConfig,\n\t\t\tparams: config?.params,\n\t\t\theaders: config?.headers,\n\t\t});\n\n\t\treturn response.data;\n\t}\n\n\t/**\n\t * Make HTTP POST request\n\t * Returns unwrapped server response data\n\t */\n\tasync post<T = any>(url: string, data?: any, config?: RequestConfig): Promise<T> {\n\t\tconst axiosConfig: AxiosRequestConfig = {\n\t\t\theaders: config?.headers,\n\t\t\t...config,\n\t\t};\n\t\tdelete axiosConfig.headers;\n\n\t\tconst response = await this.axiosInstance.post<T>(url, data, {\n\t\t\t...axiosConfig,\n\t\t\theaders: config?.headers,\n\t\t});\n\n\t\treturn response.data;\n\t}\n\n\t/**\n\t * Make HTTP PATCH request\n\t * Returns unwrapped server response data\n\t */\n\tasync patch<T = any>(url: string, data?: any, config?: RequestConfig): Promise<T> {\n\t\tconst axiosConfig: AxiosRequestConfig = {\n\t\t\theaders: config?.headers,\n\t\t\t...config,\n\t\t};\n\t\tdelete axiosConfig.headers;\n\n\t\tconst response = await this.axiosInstance.patch<T>(url, data, {\n\t\t\t...axiosConfig,\n\t\t\theaders: config?.headers,\n\t\t});\n\n\t\treturn response.data;\n\t}\n\n\t/**\n\t * Make HTTP PUT request\n\t * Returns unwrapped server response data\n\t */\n\tasync put<T = any>(url: string, data?: any, config?: RequestConfig): Promise<T> {\n\t\tconst axiosConfig: AxiosRequestConfig = {\n\t\t\theaders: config?.headers,\n\t\t\t...config,\n\t\t};\n\t\tdelete axiosConfig.headers;\n\n\t\tconst response = await this.axiosInstance.put<T>(url, data, {\n\t\t\t...axiosConfig,\n\t\t\theaders: config?.headers,\n\t\t});\n\n\t\treturn response.data;\n\t}\n\n\t/**\n\t * Make HTTP DELETE request\n\t * Returns unwrapped server response data\n\t */\n\tasync delete<T = any>(url: string, config?: RequestConfig): Promise<T> {\n\t\tconst axiosConfig: AxiosRequestConfig = {\n\t\t\theaders: config?.headers,\n\t\t\t...config,\n\t\t};\n\t\tdelete axiosConfig.headers;\n\n\t\tconst response = await this.axiosInstance.delete<T>(url, {\n\t\t\t...axiosConfig,\n\t\t\theaders: config?.headers,\n\t\t});\n\n\t\treturn response.data;\n\t}\n\n\tasync export(\n\t\turl: string,\n\t\tconfig?: AxiosRequestConfig & {\n\t\t\tonDownloadProgress?: (event: ProgressEvent) => void;\n\t\t},\n\t): Promise<AxiosResponse<ArrayBuffer>> {\n\t\treturn this.axiosInstance.get(url, {\n\t\t\tresponseType: 'arraybuffer',\n\t\t\t...config,\n\t\t});\n\t}\n\n\t/**\n\t * Get the underlying axios instance for advanced usage\n\t */\n\tget axios(): AxiosInstance {\n\t\treturn this.axiosInstance;\n\t}\n\n\t/**\n\t * Create a new client instance with a different baseURL\n\t * Useful for server-side requests or different API endpoints\n\t */\n\twithBaseURL(baseURL: string): this {\n\t\tconst ConfigClass = this.constructor as new (config: BaseApiClientConfig) => this;\n\n\t\t// Create a fresh copy of headers to avoid reference issues\n\t\tconst headers = { ...this.axiosInstance.defaults.headers } as Record<string, string>;\n\n\t\treturn new ConfigClass({\n\t\t\tbaseURL,\n\t\t\tgetAuthToken: this.getAuthToken,\n\t\t\tgetRefreshToken: this.getRefreshToken,\n\t\t\tsetAuthToken: this.setAuthToken,\n\t\t\tsetRefreshToken: this.setRefreshToken,\n\t\t\tclearAuthTokens: this.clearAuthTokens,\n\t\t\trefreshTokenUrl: this.refreshTokenUrl,\n\t\t\ttimeout: this.axiosInstance.defaults.timeout,\n\t\t\theaders,\n\t\t});\n\t}\n}\n","/**\n * @softimist/api - React Hooks for API interactions\n *\n * Generic hooks that work with any HttpClient implementation\n */\n'use client';\n\nimport { useQuery, useMutation, type QueryKey, type UseQueryOptions } from '@tanstack/react-query';\nimport { createParser, parseAsInteger, parseAsString, useQueryState } from 'nuqs';\nimport { useState } from 'react';\nimport { toast } from 'sonner';\nimport type {\n\tHttpClient,\n\tPaginationOptions,\n\tServerPaginatedResponse,\n\tServerResponse,\n\tUsePaginatedApiReturn,\n} from './types';\nimport type { Filter } from './filter';\nimport { getQueryClient } from './tanstack-query';\n\n/**\n * Hook for making simple API GET requests\n */\nexport function useApi<T>(\n\thttpClient: HttpClient,\n\turl: string | null,\n\toptions: Omit<UseQueryOptions<ServerResponse<T>>, 'queryKey' | 'queryFn' | 'enabled'> & {\n\t\tqueryKey?: QueryKey;\n\t\tenabled?: boolean;\n\t} = {},\n) {\n\tconst { queryKey, enabled = true, ...restOptions } = options;\n\n\treturn useQuery<ServerResponse<T>>({\n\t\tqueryKey: queryKey || [url],\n\t\tqueryFn: async () => {\n\t\t\tif (!url) throw new Error('URL is required');\n\t\t\treturn httpClient.get<ServerResponse<T>>(url);\n\t\t},\n\t\tenabled: url !== null && enabled,\n\t\t...restOptions,\n\t});\n}\n\n/**\n * Hook for making API mutations (POST, PATCH, PUT, DELETE) with toast notifications\n *\n * @template T - The response data type\n * @template TArg - The argument type for the action (defaults to void for backward compatibility)\n */\nexport function useApiAction<T, TArg = void>(\n\toptions: {\n\t\taction: (arg: TArg) => Promise<ServerResponse<T>>;\n\t\tshowToast?: boolean;\n\t\tinvalidateQueries?: QueryKey[];\n\t\tonSuccess?: (data: T) => void;\n\t\tonError?: (error: Error) => void;\n\t},\n) {\n\tconst { action, showToast = true, invalidateQueries, onSuccess, onError } = options;\n\n\tconst mutation = useMutation({\n\t\tmutationFn: action,\n\n\t\tonSuccess: (res) => {\n\t\t\tonSuccess?.(res.data);\n\t\t\tif (showToast) {\n\t\t\t\ttoast.success(res.message || 'Success');\n\t\t\t}\n\t\t\tif (invalidateQueries && invalidateQueries.length > 0) {\n\t\t\t\tconst queryClient = getQueryClient();\n\t\t\t\tinvalidateQueries.forEach((queryKey) => {\n\t\t\t\t\tqueryClient.invalidateQueries({ queryKey });\n\t\t\t\t});\n\t\t\t}\n\t\t},\n\t\tonError: (err: Error) => {\n\t\t\tonError?.(err);\n\t\t\tif (showToast) {\n\t\t\t\ttoast.error(err.message || 'An error occurred');\n\t\t\t}\n\t\t},\n\t});\n\n\treturn {\n /** execute mutation */\n execute: mutation.mutate,\n\n /** async version if needed */\n executeAsync: mutation.mutateAsync,\n\n /** states */\n isLoading: mutation.isPending,\n isSuccess: mutation.isSuccess,\n isError: mutation.isError,\n isExecuted: mutation.status !== 'idle',\n\n /** data & error */\n data: mutation.data?.data,\n error: mutation.error ?? undefined,\n\n /** reset to idle */\n reset: mutation.reset,\n };\n}\n\nconst parseAsFilterArray = createParser<Filter[]>({\n\tparse: (value) => {\n\t\treturn JSON.parse(value);\n\t},\n\tserialize: (value) => {\n\t\treturn JSON.stringify(value);\n\t},\n});\n\nfunction usePaginationState(options: PaginationOptions) {\n\tconst { persist = true, params: defaultParams } = options;\n\tconst defaultPerPage = (defaultParams?.per_page as number) || 20;\n\tconst defaultPage = (defaultParams?.page as number) || 1;\n\tconst [perPageQuery, setPerPageQuery] = useQueryState(\n\t\t'per_page',\n\t\tparseAsInteger.withDefault(defaultPerPage),\n\t);\n\tconst [pageQuery, setPageQuery] = useQueryState('page', parseAsInteger.withDefault(defaultPage));\n\tconst [searchQuery, setSearchQuery] = useQueryState('search', parseAsString.withDefault(''));\n\tconst [filtersQuery, setFiltersQuery] = useQueryState(\n\t\t'filters',\n\t\tparseAsFilterArray.withDefault([]),\n\t);\n\tconst [sortQuery, setSortQuery] = useQueryState('sort', parseAsString.withDefault(''));\n\n\tconst [perPageState, setPerPageState] = useState<number>(defaultPerPage);\n\tconst [pageState, setPageState] = useState<number>(defaultPage);\n\tconst [searchState, setSearchState] = useState<string>('');\n\tconst [filtersState, setFiltersState] = useState<Filter[]>([]);\n\tconst [sortState, setSortState] = useState<string>();\n\n\tconst perPage = persist ? perPageQuery : perPageState;\n\tconst page = persist ? pageQuery : pageState;\n\tconst search = persist ? searchQuery : searchState;\n\tconst filters = persist ? filtersQuery : filtersState;\n\tconst sort = persist ? sortQuery : sortState;\n\n\tconst setPerPage = (value: number | ((prev: number) => number)) => {\n\t\tif (persist) {\n\t\t\tsetPerPageQuery(value);\n\t\t} else {\n\t\t\tsetPerPageState(value);\n\t\t}\n\t};\n\n\tconst setPage = (value: number | ((prev: number) => number)) => {\n\t\tif (persist) {\n\t\t\tsetPageQuery(value);\n\t\t} else {\n\t\t\tsetPageState(value);\n\t\t}\n\t};\n\n\tconst setSearch = (value: string | ((prev: string) => string)) => {\n\t\tif (persist) {\n\t\t\tsetSearchQuery(value);\n\t\t} else {\n\t\t\tsetSearchState(value);\n\t\t}\n\t};\n\n\tconst setFilters = (value: Filter[] | ((prev: Filter[]) => Filter[])) => {\n\t\tif (persist) {\n\t\t\tsetFiltersQuery(value);\n\t\t} else {\n\t\t\tsetFiltersState(value);\n\t\t}\n\t};\n\n\tconst setSort = (value: string | ((prev: string) => string)) => {\n\t\tif (persist) {\n\t\t\tsetSortQuery(value);\n\t\t} else {\n\t\t\tsetSortState(typeof value === 'function' ? value(sortState || '') : value);\n\t\t}\n\t};\n\n\tconst getParams = () => {\n\t\tconst params = new URLSearchParams();\n\t\tif (defaultParams) {\n\t\t\tObject.entries(defaultParams).forEach(([key, value]) => {\n\t\t\t\tif (value !== undefined) {\n\t\t\t\t\tparams.set(key, value.toString());\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t\tif (perPage) params.set('per_page', perPage.toString());\n\t\tif (page) params.set('page', page.toString());\n\t\tif (search) params.set('search', search);\n\t\tif (sort) {\n\t\t\tconst [sortBy, sortDirection] = sort.split(':');\n\t\t\tif (sortBy) params.set('sort_by', sortBy);\n\t\t\tif (sortDirection) params.set('sort_dir', sortDirection);\n\t\t}\n\t\tfilters?.forEach((filter) => {\n\t\t\tif (Array.isArray(filter.value)) {\n\t\t\t\tfilter.value.forEach((v) => {\n\t\t\t\t\tparams.append(filter.key, v.toString());\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tparams.set(filter.key, filter.value.toString());\n\t\t\t}\n\t\t});\n\t\treturn params;\n\t};\n\n\treturn {\n\t\tperPage,\n\t\tpage,\n\t\tsearch,\n\t\tfilters,\n\t\tsort,\n\t\tsetPerPage,\n\t\tsetPage,\n\t\tsetSearch,\n\t\tsetFilters,\n\t\tsetSort,\n\t\tgetParams,\n\t};\n}\n\n/**\n * Hook for making paginated API requests with URL state management\n */\nexport function usePaginatedApi<T>(\n\thttpClient: HttpClient,\n\tpath: string | null,\n\toptions: PaginationOptions = {},\n): UsePaginatedApiReturn<T> {\n\tconst {\n\t\tperPage,\n\t\tpage,\n\t\tsearch,\n\t\tfilters,\n\t\tsort,\n\t\tsetPerPage,\n\t\tsetPage,\n\t\tsetSearch,\n\t\tsetFilters,\n\t\tsetSort,\n\t\tgetParams,\n\t} = usePaginationState(options);\n\n\tconst getUrl = (): string | null => {\n\t\tif (!path) return null;\n\t\tconst params = getParams();\n\t\treturn params.size === 0 ? path : `${path}?${params.toString()}`;\n\t};\n\n\tconst url = getUrl();\n\n\tconst { data, isLoading, error, refetch, isSuccess, isFetching } = useQuery({\n\t\tqueryKey: [path, options, page, perPage, search, filters, sort],\n\t\tqueryFn: async () => {\n\t\t\tif (!url) throw new Error('URL is required');\n\t\t\treturn httpClient.get<ServerPaginatedResponse<T>>(url);\n\t\t},\n\t\tenabled: !!url,\n\t});\n\n\tfunction getBulkActionUrl(\n\t\taction: string,\n\t\tadditionalFilters?: Record<string, string | string[]>,\n\t): string {\n\t\tconst params = getParams();\n\t\tparams.delete('page');\n\t\tparams.delete('per_page');\n\t\tObject.entries(additionalFilters || {}).forEach(([key, value]) => {\n\t\t\tif (value === undefined) {\n\t\t\t\tparams.delete(key);\n\t\t\t} else if (Array.isArray(value)) {\n\t\t\t\tvalue.forEach((v) => {\n\t\t\t\t\tparams.append(key, v);\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tparams.set(key, value);\n\t\t\t}\n\t\t});\n\t\tif (params.size === 0) return `${path}/${action}`;\n\t\treturn `${path}/${action}?${params.toString()}`;\n\t}\n\n\tfunction setFilter(key: string, value: any) {\n\t\tif (value === undefined) {\n\t\t\tremoveFilter(key);\n\t\t\treturn;\n\t\t}\n\t\tconst index = filters.findIndex((filter) => filter.key === key);\n\t\tif (index === -1) {\n\t\t\tsetFilters([...filters, { key, value }]);\n\t\t} else {\n\t\t\tsetFilters([...filters.slice(0, index), { key, value }, ...filters.slice(index + 1)]);\n\t\t}\n\t}\n\n\tfunction removeFilter(key: string) {\n\t\tsetFilters(filters.filter((filter) => filter.key !== key));\n\t}\n\n\tfunction getFilterValue(key: string) {\n\t\treturn filters.find((filter) => filter.key === key)?.value;\n\t}\n\n\tfunction resetFilters() {\n\t\tsetFilters([]);\n\t}\n\n\treturn {\n\t\tmessage: data?.message || '',\n\t\tdata: data?.data || [],\n\t\tpagination: data?.pagination,\n\t\tisLoading,\n\t\tisSuccess,\n\t\tisFetching,\n\t\terror: error as Error | null,\n\t\tmutate: refetch,\n\t\tpage,\n\t\tsetPage,\n\t\tperPage,\n\t\tsetPerPage,\n\t\tsearch,\n\t\tsetSearch,\n\t\tfilters,\n\t\tsetFilters,\n\t\tsetFilter,\n\t\tremoveFilter,\n\t\tgetFilterValue,\n\t\tresetFilters,\n\t\tgetBulkActionUrl,\n\t\tsort,\n\t\tsetSort,\n\t};\n}\n\n/**\n * Mock hook for testing/development\n * Returns a mock paginated response with the provided data\n */\nexport function useMockPaginatedApi<T>(data: T[]): UsePaginatedApiReturn<T> {\n\treturn {\n\t\tdata,\n\t\tpagination: {\n\t\t\ttotal: data.length,\n\t\t\tper_page: 10,\n\t\t\tcurrent_page: 1,\n\t\t\ttotal_pages: Math.ceil(data.length / 10),\n\t\t\tfrom: 1,\n\t\t\tto: data.length,\n\t\t},\n\t\tmessage: 'Data fetched successfully',\n\t\tisLoading: false,\n\t\tisSuccess: true,\n\t\tisFetching: false,\n\t\tmutate: () => {},\n\t\tpage: 1,\n\t\tsetPage: () => {},\n\t\tperPage: 10,\n\t\tsetPerPage: () => {},\n\t\tsearch: '',\n\t\tsetSearch: () => {},\n\t\tfilters: [],\n\t\tsetFilters: () => {},\n\t\tgetFilterValue: () => undefined,\n\t\tresetFilters: () => {},\n\t\tsetFilter: () => {},\n\t\tremoveFilter: () => {},\n\t\tsort: '',\n\t\tsetSort: () => {},\n\t\tgetBulkActionUrl: () => '',\n\t};\n}\n","'use client';\n\nimport { QueryClient, QueryClientProvider } from '@tanstack/react-query';\nimport { ReactNode } from 'react';\n\nexport function makeQueryClient() {\n return new QueryClient({\n defaultOptions: {\n queries: {\n refetchOnWindowFocus: false,\n refetchOnReconnect: false,\n },\n },\n });\n}\n\nlet browserQueryClient: QueryClient | undefined = undefined;\n\nexport function getQueryClient() {\n if (typeof window === 'undefined') {\n return makeQueryClient();\n } else {\n if (!browserQueryClient) browserQueryClient = makeQueryClient();\n return browserQueryClient;\n }\n}\n\n\nexport function QueryProvider({ children }: { children: ReactNode }) {\n const queryClient = getQueryClient();\n\n return <QueryClientProvider client={queryClient}>{children}</QueryClientProvider>;\n}\n","/**\n * @softimist/api - Utility Functions\n * \n * Common utility functions for API error and response handling\n */\n\ntype ApiErrorLike = {\n message?: unknown;\n response?: {\n data?: {\n message?: unknown;\n error?: unknown;\n };\n };\n};\n\n/**\n * Extract error message from various error types\n */\nexport function getErrorMessage(error: unknown): string {\n const err = error as ApiErrorLike | null | undefined;\n \n // Try to get message from API response\n const apiMessage = err?.response?.data?.message;\n if (typeof apiMessage === 'string' && apiMessage.trim() !== '') {\n return apiMessage;\n }\n\n // Try to get error from API response\n const apiError = err?.response?.data?.error;\n if (typeof apiError === 'string' && apiError.trim() !== '') {\n return apiError;\n }\n\n // Try to get message from error object\n const message = err?.message;\n if (typeof message === 'string' && message.trim() !== '') {\n return message;\n }\n\n // Try Error instance message\n if (error instanceof Error && error.message.trim() !== '') {\n return error.message;\n }\n\n return 'Something went wrong';\n}\n\n/**\n * Extract success message from API response\n */\nexport function getSuccessMessage(response: any, defaultMessage?: string): string {\n return response?.data?.message || defaultMessage || 'Success';\n}\n"],"mappings":"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","names":["axios","import_react_query","import_react_query"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AxiosInstance } from 'axios';
|
|
1
|
+
import { AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios';
|
|
2
2
|
import * as _tanstack_react_query from '@tanstack/react-query';
|
|
3
3
|
import { UseQueryOptions, QueryKey, QueryClient } from '@tanstack/react-query';
|
|
4
4
|
export { useInfiniteQuery, useQuery } from '@tanstack/react-query';
|
|
@@ -231,6 +231,9 @@ declare class BaseApiClient implements HttpClient {
|
|
|
231
231
|
* Returns unwrapped server response data
|
|
232
232
|
*/
|
|
233
233
|
delete<T = any>(url: string, config?: RequestConfig): Promise<T>;
|
|
234
|
+
export(url: string, config?: AxiosRequestConfig & {
|
|
235
|
+
onDownloadProgress?: (event: ProgressEvent) => void;
|
|
236
|
+
}): Promise<AxiosResponse<ArrayBuffer>>;
|
|
234
237
|
/**
|
|
235
238
|
* Get the underlying axios instance for advanced usage
|
|
236
239
|
*/
|
|
@@ -251,19 +254,31 @@ declare function useApi<T>(httpClient: HttpClient, url: string | null, options?:
|
|
|
251
254
|
}): _tanstack_react_query.UseQueryResult<ServerResponse<T>, Error>;
|
|
252
255
|
/**
|
|
253
256
|
* Hook for making API mutations (POST, PATCH, PUT, DELETE) with toast notifications
|
|
257
|
+
*
|
|
258
|
+
* @template T - The response data type
|
|
259
|
+
* @template TArg - The argument type for the action (defaults to void for backward compatibility)
|
|
254
260
|
*/
|
|
255
|
-
declare function useApiAction<T>(
|
|
256
|
-
action: () => Promise<ServerResponse<T>>;
|
|
261
|
+
declare function useApiAction<T, TArg = void>(options: {
|
|
262
|
+
action: (arg: TArg) => Promise<ServerResponse<T>>;
|
|
257
263
|
showToast?: boolean;
|
|
258
264
|
invalidateQueries?: QueryKey[];
|
|
259
265
|
onSuccess?: (data: T) => void;
|
|
260
266
|
onError?: (error: Error) => void;
|
|
261
267
|
}): {
|
|
268
|
+
/** execute mutation */
|
|
269
|
+
execute: _tanstack_react_query.UseMutateFunction<ServerResponse<T>, Error, TArg, unknown>;
|
|
270
|
+
/** async version if needed */
|
|
271
|
+
executeAsync: _tanstack_react_query.UseMutateAsyncFunction<ServerResponse<T>, Error, TArg, unknown>;
|
|
272
|
+
/** states */
|
|
262
273
|
isLoading: boolean;
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
execute: () => void;
|
|
274
|
+
isSuccess: boolean;
|
|
275
|
+
isError: boolean;
|
|
266
276
|
isExecuted: boolean;
|
|
277
|
+
/** data & error */
|
|
278
|
+
data: T | undefined;
|
|
279
|
+
error: Error | undefined;
|
|
280
|
+
/** reset to idle */
|
|
281
|
+
reset: () => void;
|
|
267
282
|
};
|
|
268
283
|
/**
|
|
269
284
|
* Hook for making paginated API requests with URL state management
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AxiosInstance } from 'axios';
|
|
1
|
+
import { AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios';
|
|
2
2
|
import * as _tanstack_react_query from '@tanstack/react-query';
|
|
3
3
|
import { UseQueryOptions, QueryKey, QueryClient } from '@tanstack/react-query';
|
|
4
4
|
export { useInfiniteQuery, useQuery } from '@tanstack/react-query';
|
|
@@ -231,6 +231,9 @@ declare class BaseApiClient implements HttpClient {
|
|
|
231
231
|
* Returns unwrapped server response data
|
|
232
232
|
*/
|
|
233
233
|
delete<T = any>(url: string, config?: RequestConfig): Promise<T>;
|
|
234
|
+
export(url: string, config?: AxiosRequestConfig & {
|
|
235
|
+
onDownloadProgress?: (event: ProgressEvent) => void;
|
|
236
|
+
}): Promise<AxiosResponse<ArrayBuffer>>;
|
|
234
237
|
/**
|
|
235
238
|
* Get the underlying axios instance for advanced usage
|
|
236
239
|
*/
|
|
@@ -251,19 +254,31 @@ declare function useApi<T>(httpClient: HttpClient, url: string | null, options?:
|
|
|
251
254
|
}): _tanstack_react_query.UseQueryResult<ServerResponse<T>, Error>;
|
|
252
255
|
/**
|
|
253
256
|
* Hook for making API mutations (POST, PATCH, PUT, DELETE) with toast notifications
|
|
257
|
+
*
|
|
258
|
+
* @template T - The response data type
|
|
259
|
+
* @template TArg - The argument type for the action (defaults to void for backward compatibility)
|
|
254
260
|
*/
|
|
255
|
-
declare function useApiAction<T>(
|
|
256
|
-
action: () => Promise<ServerResponse<T>>;
|
|
261
|
+
declare function useApiAction<T, TArg = void>(options: {
|
|
262
|
+
action: (arg: TArg) => Promise<ServerResponse<T>>;
|
|
257
263
|
showToast?: boolean;
|
|
258
264
|
invalidateQueries?: QueryKey[];
|
|
259
265
|
onSuccess?: (data: T) => void;
|
|
260
266
|
onError?: (error: Error) => void;
|
|
261
267
|
}): {
|
|
268
|
+
/** execute mutation */
|
|
269
|
+
execute: _tanstack_react_query.UseMutateFunction<ServerResponse<T>, Error, TArg, unknown>;
|
|
270
|
+
/** async version if needed */
|
|
271
|
+
executeAsync: _tanstack_react_query.UseMutateAsyncFunction<ServerResponse<T>, Error, TArg, unknown>;
|
|
272
|
+
/** states */
|
|
262
273
|
isLoading: boolean;
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
execute: () => void;
|
|
274
|
+
isSuccess: boolean;
|
|
275
|
+
isError: boolean;
|
|
266
276
|
isExecuted: boolean;
|
|
277
|
+
/** data & error */
|
|
278
|
+
data: T | undefined;
|
|
279
|
+
error: Error | undefined;
|
|
280
|
+
/** reset to idle */
|
|
281
|
+
reset: () => void;
|
|
267
282
|
};
|
|
268
283
|
/**
|
|
269
284
|
* Hook for making paginated API requests with URL state management
|
package/dist/index.js
CHANGED
|
@@ -221,6 +221,12 @@ var BaseApiClient = class {
|
|
|
221
221
|
});
|
|
222
222
|
return response.data;
|
|
223
223
|
}
|
|
224
|
+
async export(url, config) {
|
|
225
|
+
return this.axiosInstance.get(url, {
|
|
226
|
+
responseType: "arraybuffer",
|
|
227
|
+
...config
|
|
228
|
+
});
|
|
229
|
+
}
|
|
224
230
|
/**
|
|
225
231
|
* Get the underlying axios instance for advanced usage
|
|
226
232
|
*/
|
|
@@ -294,14 +300,12 @@ function useApi(httpClient, url, options = {}) {
|
|
|
294
300
|
...restOptions
|
|
295
301
|
});
|
|
296
302
|
}
|
|
297
|
-
function useApiAction(
|
|
303
|
+
function useApiAction(options) {
|
|
298
304
|
const { action, showToast = true, invalidateQueries, onSuccess, onError } = options;
|
|
299
|
-
const [isExecuted, setIsExecuted] = useState(false);
|
|
300
305
|
const mutation = useMutation({
|
|
301
306
|
mutationFn: action,
|
|
302
307
|
onSuccess: (res) => {
|
|
303
308
|
onSuccess?.(res.data);
|
|
304
|
-
setIsExecuted(true);
|
|
305
309
|
if (showToast) {
|
|
306
310
|
toast.success(res.message || "Success");
|
|
307
311
|
}
|
|
@@ -319,15 +323,21 @@ function useApiAction(httpClient, options) {
|
|
|
319
323
|
}
|
|
320
324
|
}
|
|
321
325
|
});
|
|
322
|
-
const execute = () => {
|
|
323
|
-
mutation.mutate();
|
|
324
|
-
};
|
|
325
326
|
return {
|
|
327
|
+
/** execute mutation */
|
|
328
|
+
execute: mutation.mutate,
|
|
329
|
+
/** async version if needed */
|
|
330
|
+
executeAsync: mutation.mutateAsync,
|
|
331
|
+
/** states */
|
|
326
332
|
isLoading: mutation.isPending,
|
|
327
|
-
|
|
333
|
+
isSuccess: mutation.isSuccess,
|
|
334
|
+
isError: mutation.isError,
|
|
335
|
+
isExecuted: mutation.status !== "idle",
|
|
336
|
+
/** data & error */
|
|
328
337
|
data: mutation.data?.data,
|
|
329
|
-
|
|
330
|
-
|
|
338
|
+
error: mutation.error ?? void 0,
|
|
339
|
+
/** reset to idle */
|
|
340
|
+
reset: mutation.reset
|
|
331
341
|
};
|
|
332
342
|
}
|
|
333
343
|
var parseAsFilterArray = createParser({
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/client.ts","../src/hooks.ts","../src/tanstack-query.tsx","../src/utils.ts","../src/index.ts"],"sourcesContent":["/**\n * @softimist/api - Base API Client\n *\n * Base class for API clients that can be extended by module-specific implementations.\n * Uses axios for HTTP requests and provides common functionality like authentication,\n * error handling, and request/response interceptors.\n *\n * All HTTP methods return unwrapped server response data directly (e.g., ServerResponse<T>).\n */\n\nimport axios, { type AxiosInstance, type AxiosRequestConfig } from \"axios\";\nimport type { HttpClient } from \"./types\";\n\n/**\n * Configuration options for BaseApiClient\n */\nexport interface BaseApiClientConfig {\n\tbaseURL?: string;\n\tgetAuthToken?: () => string | null;\n\tgetRefreshToken?: () => string | null;\n\tsetAuthToken?: (token: string) => void;\n\tsetRefreshToken?: (token: string) => void;\n\tclearAuthTokens?: () => void;\n\trefreshTokenUrl?: string;\n\ttimeout?: number;\n\theaders?: Record<string, string>;\n}\n\n/**\n * Request configuration passed to HTTP methods\n */\nexport interface RequestConfig {\n\theaders?: Record<string, string>;\n\tparams?: Record<string, any>;\n\t[key: string]: any;\n}\n\n/**\n * Base API Client class\n * Provides common HTTP functionality using axios that can be extended by module-specific clients\n *\n * @example\n * ```ts\n * class WebsiteApiClient extends BaseApiClient {\n * async getPages(): Promise<ServerPaginatedResponse<Page>> {\n * return this.get<ServerPaginatedResponse<Page>>('/api/v1/website/pages');\n * }\n * }\n * ```\n */\nexport class BaseApiClient implements HttpClient {\n\tprotected axiosInstance: AxiosInstance;\n\tprotected getAuthToken?: () => string | null;\n\tprotected getRefreshToken?: () => string | null;\n\tprotected setAuthToken?: (token: string) => void;\n\tprotected setRefreshToken?: (token: string) => void;\n\tprotected clearAuthTokens?: () => void;\n\tprotected refreshTokenUrl?: string;\n\tprivate isRefreshing = false;\n\tprivate failedQueue: Array<{\n\t\tresolve: (value?: any) => void;\n\t\treject: (error?: any) => void;\n\t}> = [];\n\n\tconstructor(config: BaseApiClientConfig = {}) {\n\t\tconst defaultHeaders = {\n\t\t\t\"Content-Type\": \"application/json\",\n\t\t\tAccept: \"application/json\",\n\t\t\t...config.headers,\n\t\t};\n\n\t\tthis.axiosInstance = axios.create({\n\t\t\tbaseURL: config.baseURL || \"\",\n\t\t\ttimeout: config.timeout || 30000,\n\t\t\theaders: defaultHeaders,\n\t\t});\n\n\t\tthis.getAuthToken = config.getAuthToken;\n\t\tthis.getRefreshToken = config.getRefreshToken;\n\t\tthis.setAuthToken = config.setAuthToken;\n\t\tthis.setRefreshToken = config.setRefreshToken;\n\t\tthis.clearAuthTokens = config.clearAuthTokens;\n\t\tthis.refreshTokenUrl =\n\t\t\tconfig.refreshTokenUrl || `${config.baseURL || \"\"}/v1/auth/refresh`;\n\n\t\t// Set up request interceptor for authentication\n\t\tthis.axiosInstance.interceptors.request.use(\n\t\t\t(requestConfig) => {\n\t\t\t\tif (this.getAuthToken) {\n\t\t\t\t\tconst token = this.getAuthToken();\n\t\t\t\t\tif (token) {\n\t\t\t\t\t\trequestConfig.headers.Authorization = `Bearer ${token}`;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn requestConfig;\n\t\t\t},\n\t\t\t(error) => {\n\t\t\t\treturn Promise.reject(error);\n\t\t\t},\n\t\t);\n\n\t\t// Set up response interceptor for error handling and token refresh\n\t\tthis.axiosInstance.interceptors.response.use(\n\t\t\t(response) => response,\n\t\t\tasync (error) => {\n\t\t\t\tconst originalRequest = error.config;\n\n\t\t\t\t// Handle 401 errors with token refresh\n\t\t\t\tif (\n\t\t\t\t\terror.response?.status === 401 &&\n\t\t\t\t\t!originalRequest._retry &&\n\t\t\t\t\tthis.getRefreshToken\n\t\t\t\t) {\n\t\t\t\t\tif (this.isRefreshing) {\n\t\t\t\t\t\t// If we're already refreshing, queue this request\n\t\t\t\t\t\treturn new Promise((resolve, reject) => {\n\t\t\t\t\t\t\tthis.failedQueue.push({ resolve, reject });\n\t\t\t\t\t\t})\n\t\t\t\t\t\t\t.then((token) => {\n\t\t\t\t\t\t\t\toriginalRequest.headers.Authorization = `Bearer ${token}`;\n\t\t\t\t\t\t\t\treturn this.axiosInstance(originalRequest);\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t.catch((err) => {\n\t\t\t\t\t\t\t\treturn Promise.reject(err);\n\t\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\toriginalRequest._retry = true;\n\t\t\t\t\tthis.isRefreshing = true;\n\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst accessToken = await this.refreshAuthToken();\n\n\t\t\t\t\t\t// Update the original request with new token\n\t\t\t\t\t\toriginalRequest.headers.Authorization = `Bearer ${accessToken}`;\n\n\t\t\t\t\t\t// Process queued requests\n\t\t\t\t\t\tthis.processQueue(null, accessToken);\n\t\t\t\t\t\tthis.isRefreshing = false;\n\n\t\t\t\t\t\t// Retry the original request\n\t\t\t\t\t\treturn this.axiosInstance(originalRequest);\n\t\t\t\t\t} catch (refreshError) {\n\t\t\t\t\t\t// Refresh token is invalid, clear all tokens\n\t\t\t\t\t\tthis.processQueue(refreshError, null);\n\t\t\t\t\t\tthis.isRefreshing = false;\n\t\t\t\t\t\treturn Promise.reject(this.handleError(refreshError));\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn Promise.reject(this.handleError(error));\n\t\t\t},\n\t\t);\n\t}\n\n\t/**\n\t * Process queued requests after token refresh\n\t */\n\tprivate processQueue(error: any, token: string | null = null) {\n\t\tthis.failedQueue.forEach(({ resolve, reject }) => {\n\t\t\tif (error) {\n\t\t\t\treject(error);\n\t\t\t} else {\n\t\t\t\tresolve(token);\n\t\t\t}\n\t\t});\n\t\tthis.failedQueue = [];\n\t}\n\n\t/**\n\t * Refresh authentication token\n\t */\n\tprivate async refreshAuthToken(): Promise<string> {\n\t\tif (!this.getRefreshToken) {\n\t\t\tthrow new Error(\"No refresh token function provided\");\n\t\t}\n\n\t\tconst refreshToken = this.getRefreshToken();\n\t\tif (!refreshToken) {\n\t\t\tif (this.clearAuthTokens) {\n\t\t\t\tthis.clearAuthTokens();\n\t\t\t}\n\t\t\tthrow new Error(\"No refresh token available\");\n\t\t}\n\n\t\ttry {\n\t\t\t// Use a fresh axios instance for refresh token request to avoid circular interceptor issues\n\t\t\tconst response = await axios.post(\n\t\t\t\tthis.refreshTokenUrl!,\n\t\t\t\t{\n\t\t\t\t\trefresh_token: refreshToken,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tbaseURL: \"\", // Use absolute URL or empty to avoid baseURL duplication\n\t\t\t\t},\n\t\t\t);\n\n\t\t\tconst { access_token, refresh_token } = response.data;\n\n\t\t\tif (this.setAuthToken) {\n\t\t\t\tthis.setAuthToken(access_token);\n\t\t\t}\n\t\t\tif (refresh_token && this.setRefreshToken) {\n\t\t\t\tthis.setRefreshToken(refresh_token);\n\t\t\t}\n\n\t\t\treturn access_token;\n\t\t} catch (error) {\n\t\t\t// Refresh token is invalid, clear all tokens\n\t\t\tif (this.clearAuthTokens) {\n\t\t\t\tthis.clearAuthTokens();\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\t/**\n\t * Handle request errors\n\t */\n\tprotected handleError(error: any): Error {\n\t\tif (error.response) {\n\t\t\t// Server responded with error status\n\t\t\tconst message =\n\t\t\t\terror.response.data?.message ||\n\t\t\t\terror.response.data?.error ||\n\t\t\t\terror.message ||\n\t\t\t\t\"An unknown error occurred\";\n\t\t\terror.message = message;\n\t\t\treturn error;\n\t\t}\n\t\treturn error;\n\t}\n\n\t/**\n\t * Make HTTP GET request\n\t * Returns unwrapped server response data\n\t */\n\tasync get<T = any>(url: string, config?: RequestConfig): Promise<T> {\n\t\tconst axiosConfig: AxiosRequestConfig = {\n\t\t\tparams: config?.params,\n\t\t\theaders: config?.headers,\n\t\t\t...config,\n\t\t};\n\t\tdelete axiosConfig.params;\n\t\tdelete axiosConfig.headers;\n\n\t\tconst response = await this.axiosInstance.get<T>(url, {\n\t\t\t...axiosConfig,\n\t\t\tparams: config?.params,\n\t\t\theaders: config?.headers,\n\t\t});\n\n\t\treturn response.data;\n\t}\n\n\t/**\n\t * Make HTTP POST request\n\t * Returns unwrapped server response data\n\t */\n\tasync post<T = any>(\n\t\turl: string,\n\t\tdata?: any,\n\t\tconfig?: RequestConfig,\n\t): Promise<T> {\n\t\tconst axiosConfig: AxiosRequestConfig = {\n\t\t\theaders: config?.headers,\n\t\t\t...config,\n\t\t};\n\t\tdelete axiosConfig.headers;\n\n\t\tconst response = await this.axiosInstance.post<T>(url, data, {\n\t\t\t...axiosConfig,\n\t\t\theaders: config?.headers,\n\t\t});\n\n\t\treturn response.data;\n\t}\n\n\t/**\n\t * Make HTTP PATCH request\n\t * Returns unwrapped server response data\n\t */\n\tasync patch<T = any>(\n\t\turl: string,\n\t\tdata?: any,\n\t\tconfig?: RequestConfig,\n\t): Promise<T> {\n\t\tconst axiosConfig: AxiosRequestConfig = {\n\t\t\theaders: config?.headers,\n\t\t\t...config,\n\t\t};\n\t\tdelete axiosConfig.headers;\n\n\t\tconst response = await this.axiosInstance.patch<T>(url, data, {\n\t\t\t...axiosConfig,\n\t\t\theaders: config?.headers,\n\t\t});\n\n\t\treturn response.data;\n\t}\n\n\t/**\n\t * Make HTTP PUT request\n\t * Returns unwrapped server response data\n\t */\n\tasync put<T = any>(\n\t\turl: string,\n\t\tdata?: any,\n\t\tconfig?: RequestConfig,\n\t): Promise<T> {\n\t\tconst axiosConfig: AxiosRequestConfig = {\n\t\t\theaders: config?.headers,\n\t\t\t...config,\n\t\t};\n\t\tdelete axiosConfig.headers;\n\n\t\tconst response = await this.axiosInstance.put<T>(url, data, {\n\t\t\t...axiosConfig,\n\t\t\theaders: config?.headers,\n\t\t});\n\n\t\treturn response.data;\n\t}\n\n\t/**\n\t * Make HTTP DELETE request\n\t * Returns unwrapped server response data\n\t */\n\tasync delete<T = any>(url: string, config?: RequestConfig): Promise<T> {\n\t\tconst axiosConfig: AxiosRequestConfig = {\n\t\t\theaders: config?.headers,\n\t\t\t...config,\n\t\t};\n\t\tdelete axiosConfig.headers;\n\n\t\tconst response = await this.axiosInstance.delete<T>(url, {\n\t\t\t...axiosConfig,\n\t\t\theaders: config?.headers,\n\t\t});\n\n\t\treturn response.data;\n\t}\n\n\t/**\n\t * Get the underlying axios instance for advanced usage\n\t */\n\tget axios(): AxiosInstance {\n\t\treturn this.axiosInstance;\n\t}\n\n\t/**\n\t * Create a new client instance with a different baseURL\n\t * Useful for server-side requests or different API endpoints\n\t */\n\twithBaseURL(baseURL: string): this {\n\t\tconst ConfigClass = this.constructor as new (\n\t\t\tconfig: BaseApiClientConfig,\n\t\t) => this;\n\n\t\t// Create a fresh copy of headers to avoid reference issues\n\t\tconst headers = { ...this.axiosInstance.defaults.headers } as Record<\n\t\t\tstring,\n\t\t\tstring\n\t\t>;\n\n\t\treturn new ConfigClass({\n\t\t\tbaseURL,\n\t\t\tgetAuthToken: this.getAuthToken,\n\t\t\tgetRefreshToken: this.getRefreshToken,\n\t\t\tsetAuthToken: this.setAuthToken,\n\t\t\tsetRefreshToken: this.setRefreshToken,\n\t\t\tclearAuthTokens: this.clearAuthTokens,\n\t\t\trefreshTokenUrl: this.refreshTokenUrl,\n\t\t\ttimeout: this.axiosInstance.defaults.timeout,\n\t\t\theaders,\n\t\t});\n\t}\n}\n","/**\n * @softimist/api - React Hooks for API interactions\n *\n * Generic hooks that work with any HttpClient implementation\n */\n'use client';\n\nimport { useQuery, useMutation, type QueryKey, type UseQueryOptions } from '@tanstack/react-query';\nimport { createParser, parseAsInteger, parseAsString, useQueryState } from 'nuqs';\nimport { useState } from 'react';\nimport { toast } from 'sonner';\nimport type {\n\tHttpClient,\n\tPaginationOptions,\n\tServerPaginatedResponse,\n\tServerResponse,\n\tUsePaginatedApiReturn,\n} from './types';\nimport type { Filter } from './filter';\nimport { getQueryClient } from './tanstack-query';\n\n/**\n * Hook for making simple API GET requests\n */\nexport function useApi<T>(\n\thttpClient: HttpClient,\n\turl: string | null,\n\toptions: Omit<UseQueryOptions<ServerResponse<T>>, 'queryKey' | 'queryFn' | 'enabled'> & {\n\t\tqueryKey?: QueryKey;\n\t\tenabled?: boolean;\n\t} = {},\n) {\n\tconst { queryKey, enabled = true, ...restOptions } = options;\n\n\treturn useQuery<ServerResponse<T>>({\n\t\tqueryKey: queryKey || [url],\n\t\tqueryFn: async () => {\n\t\t\tif (!url) throw new Error('URL is required');\n\t\t\treturn httpClient.get<ServerResponse<T>>(url);\n\t\t},\n\t\tenabled: url !== null && enabled,\n\t\t...restOptions,\n\t});\n}\n\n/**\n * Hook for making API mutations (POST, PATCH, PUT, DELETE) with toast notifications\n */\nexport function useApiAction<T>(\n\thttpClient: HttpClient,\n\toptions: {\n\t\taction: () => Promise<ServerResponse<T>>;\n\t\tshowToast?: boolean;\n\t\tinvalidateQueries?: QueryKey[];\n\t\tonSuccess?: (data: T) => void;\n\t\tonError?: (error: Error) => void;\n\t},\n) {\n\tconst { action, showToast = true, invalidateQueries, onSuccess, onError } = options;\n\tconst [isExecuted, setIsExecuted] = useState(false);\n\n\tconst mutation = useMutation({\n\t\tmutationFn: action,\n\n\t\tonSuccess: (res) => {\n\t\t\tonSuccess?.(res.data);\n\t\t\tsetIsExecuted(true);\n\t\t\tif (showToast) {\n\t\t\t\ttoast.success(res.message || 'Success');\n\t\t\t}\n\t\t\tif (invalidateQueries && invalidateQueries.length > 0) {\n\t\t\t\tconst queryClient = getQueryClient();\n\t\t\t\tinvalidateQueries.forEach((queryKey) => {\n\t\t\t\t\tqueryClient.invalidateQueries({ queryKey });\n\t\t\t\t});\n\t\t\t}\n\t\t},\n\t\tonError: (err: Error) => {\n\t\t\tonError?.(err);\n\t\t\tif (showToast) {\n\t\t\t\ttoast.error(err.message || 'An error occurred');\n\t\t\t}\n\t\t},\n\t});\n\n\tconst execute = () => {\n\t\tmutation.mutate();\n\t};\n\n\treturn {\n\t\tisLoading: mutation.isPending,\n\t\terror: mutation.error ?? undefined,\n\t\tdata: mutation.data?.data,\n\t\texecute,\n\t\tisExecuted,\n\t};\n}\n\nconst parseAsFilterArray = createParser<Filter[]>({\n\tparse: (value) => {\n\t\treturn JSON.parse(value);\n\t},\n\tserialize: (value) => {\n\t\treturn JSON.stringify(value);\n\t},\n});\n\nfunction usePaginationState(options: PaginationOptions) {\n\tconst { persist = true, params: defaultParams } = options;\n\tconst defaultPerPage = (defaultParams?.per_page as number) || 20;\n\tconst defaultPage = (defaultParams?.page as number) || 1;\n\tconst [perPageQuery, setPerPageQuery] = useQueryState(\n\t\t'per_page',\n\t\tparseAsInteger.withDefault(defaultPerPage),\n\t);\n\tconst [pageQuery, setPageQuery] = useQueryState('page', parseAsInteger.withDefault(defaultPage));\n\tconst [searchQuery, setSearchQuery] = useQueryState('search', parseAsString.withDefault(''));\n\tconst [filtersQuery, setFiltersQuery] = useQueryState(\n\t\t'filters',\n\t\tparseAsFilterArray.withDefault([]),\n\t);\n\tconst [sortQuery, setSortQuery] = useQueryState('sort', parseAsString.withDefault(''));\n\n\tconst [perPageState, setPerPageState] = useState<number>(defaultPerPage);\n\tconst [pageState, setPageState] = useState<number>(defaultPage);\n\tconst [searchState, setSearchState] = useState<string>('');\n\tconst [filtersState, setFiltersState] = useState<Filter[]>([]);\n\tconst [sortState, setSortState] = useState<string>();\n\n\tconst perPage = persist ? perPageQuery : perPageState;\n\tconst page = persist ? pageQuery : pageState;\n\tconst search = persist ? searchQuery : searchState;\n\tconst filters = persist ? filtersQuery : filtersState;\n\tconst sort = persist ? sortQuery : sortState;\n\n\tconst setPerPage = (value: number | ((prev: number) => number)) => {\n\t\tif (persist) {\n\t\t\tsetPerPageQuery(value);\n\t\t} else {\n\t\t\tsetPerPageState(value);\n\t\t}\n\t};\n\n\tconst setPage = (value: number | ((prev: number) => number)) => {\n\t\tif (persist) {\n\t\t\tsetPageQuery(value);\n\t\t} else {\n\t\t\tsetPageState(value);\n\t\t}\n\t};\n\n\tconst setSearch = (value: string | ((prev: string) => string)) => {\n\t\tif (persist) {\n\t\t\tsetSearchQuery(value);\n\t\t} else {\n\t\t\tsetSearchState(value);\n\t\t}\n\t};\n\n\tconst setFilters = (value: Filter[] | ((prev: Filter[]) => Filter[])) => {\n\t\tif (persist) {\n\t\t\tsetFiltersQuery(value);\n\t\t} else {\n\t\t\tsetFiltersState(value);\n\t\t}\n\t};\n\n\tconst setSort = (value: string | ((prev: string) => string)) => {\n\t\tif (persist) {\n\t\t\tsetSortQuery(value);\n\t\t} else {\n\t\t\tsetSortState(typeof value === 'function' ? value(sortState || '') : value);\n\t\t}\n\t};\n\n\tconst getParams = () => {\n\t\tconst params = new URLSearchParams();\n\t\tif (defaultParams) {\n\t\t\tObject.entries(defaultParams).forEach(([key, value]) => {\n\t\t\t\tif (value !== undefined) {\n\t\t\t\t\tparams.set(key, value.toString());\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t\tif (perPage) params.set('per_page', perPage.toString());\n\t\tif (page) params.set('page', page.toString());\n\t\tif (search) params.set('search', search);\n\t\tif (sort) {\n\t\t\tconst [sortBy, sortDirection] = sort.split(':');\n\t\t\tif (sortBy) params.set('sort_by', sortBy);\n\t\t\tif (sortDirection) params.set('sort_dir', sortDirection);\n\t\t}\n\t\tfilters?.forEach((filter) => {\n\t\t\tif (Array.isArray(filter.value)) {\n\t\t\t\tfilter.value.forEach((v) => {\n\t\t\t\t\tparams.append(filter.key, v.toString());\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tparams.set(filter.key, filter.value.toString());\n\t\t\t}\n\t\t});\n\t\treturn params;\n\t};\n\n\treturn {\n\t\tperPage,\n\t\tpage,\n\t\tsearch,\n\t\tfilters,\n\t\tsort,\n\t\tsetPerPage,\n\t\tsetPage,\n\t\tsetSearch,\n\t\tsetFilters,\n\t\tsetSort,\n\t\tgetParams,\n\t};\n}\n\n/**\n * Hook for making paginated API requests with URL state management\n */\nexport function usePaginatedApi<T>(\n\thttpClient: HttpClient,\n\tpath: string | null,\n\toptions: PaginationOptions = {},\n): UsePaginatedApiReturn<T> {\n\tconst {\n\t\tperPage,\n\t\tpage,\n\t\tsearch,\n\t\tfilters,\n\t\tsort,\n\t\tsetPerPage,\n\t\tsetPage,\n\t\tsetSearch,\n\t\tsetFilters,\n\t\tsetSort,\n\t\tgetParams,\n\t} = usePaginationState(options);\n\n\tconst getUrl = (): string | null => {\n\t\tif (!path) return null;\n\t\tconst params = getParams();\n\t\treturn params.size === 0 ? path : `${path}?${params.toString()}`;\n\t};\n\n\tconst url = getUrl();\n\n\tconst { data, isLoading, error, refetch, isSuccess, isFetching } = useQuery({\n\t\tqueryKey: [path, options, page, perPage, search, filters, sort],\n\t\tqueryFn: async () => {\n\t\t\tif (!url) throw new Error('URL is required');\n\t\t\treturn httpClient.get<ServerPaginatedResponse<T>>(url);\n\t\t},\n\t\tenabled: !!url,\n\t});\n\n\tfunction getBulkActionUrl(\n\t\taction: string,\n\t\tadditionalFilters?: Record<string, string | string[]>,\n\t): string {\n\t\tconst params = getParams();\n\t\tparams.delete('page');\n\t\tparams.delete('per_page');\n\t\tObject.entries(additionalFilters || {}).forEach(([key, value]) => {\n\t\t\tif (value === undefined) {\n\t\t\t\tparams.delete(key);\n\t\t\t} else if (Array.isArray(value)) {\n\t\t\t\tvalue.forEach((v) => {\n\t\t\t\t\tparams.append(key, v);\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tparams.set(key, value);\n\t\t\t}\n\t\t});\n\t\tif (params.size === 0) return `${path}/${action}`;\n\t\treturn `${path}/${action}?${params.toString()}`;\n\t}\n\n\tfunction setFilter(key: string, value: any) {\n\t\tif (value === undefined) {\n\t\t\tremoveFilter(key);\n\t\t\treturn;\n\t\t}\n\t\tconst index = filters.findIndex((filter) => filter.key === key);\n\t\tif (index === -1) {\n\t\t\tsetFilters([...filters, { key, value }]);\n\t\t} else {\n\t\t\tsetFilters([...filters.slice(0, index), { key, value }, ...filters.slice(index + 1)]);\n\t\t}\n\t}\n\n\tfunction removeFilter(key: string) {\n\t\tsetFilters(filters.filter((filter) => filter.key !== key));\n\t}\n\n\tfunction getFilterValue(key: string) {\n\t\treturn filters.find((filter) => filter.key === key)?.value;\n\t}\n\n\tfunction resetFilters() {\n\t\tsetFilters([]);\n\t}\n\n\treturn {\n\t\tmessage: data?.message || '',\n\t\tdata: data?.data || [],\n\t\tpagination: data?.pagination,\n\t\tisLoading,\n\t\tisSuccess,\n\t\tisFetching,\n\t\terror: error as Error | null,\n\t\tmutate: refetch,\n\t\tpage,\n\t\tsetPage,\n\t\tperPage,\n\t\tsetPerPage,\n\t\tsearch,\n\t\tsetSearch,\n\t\tfilters,\n\t\tsetFilters,\n\t\tsetFilter,\n\t\tremoveFilter,\n\t\tgetFilterValue,\n\t\tresetFilters,\n\t\tgetBulkActionUrl,\n\t\tsort,\n\t\tsetSort,\n\t};\n}\n\n/**\n * Mock hook for testing/development\n * Returns a mock paginated response with the provided data\n */\nexport function useMockPaginatedApi<T>(data: T[]): UsePaginatedApiReturn<T> {\n\treturn {\n\t\tdata,\n\t\tpagination: {\n\t\t\ttotal: data.length,\n\t\t\tper_page: 10,\n\t\t\tcurrent_page: 1,\n\t\t\ttotal_pages: Math.ceil(data.length / 10),\n\t\t\tfrom: 1,\n\t\t\tto: data.length,\n\t\t},\n\t\tmessage: 'Data fetched successfully',\n\t\tisLoading: false,\n\t\tisSuccess: true,\n\t\tisFetching: false,\n\t\tmutate: () => {},\n\t\tpage: 1,\n\t\tsetPage: () => {},\n\t\tperPage: 10,\n\t\tsetPerPage: () => {},\n\t\tsearch: '',\n\t\tsetSearch: () => {},\n\t\tfilters: [],\n\t\tsetFilters: () => {},\n\t\tgetFilterValue: () => undefined,\n\t\tresetFilters: () => {},\n\t\tsetFilter: () => {},\n\t\tremoveFilter: () => {},\n\t\tsort: '',\n\t\tsetSort: () => {},\n\t\tgetBulkActionUrl: () => '',\n\t};\n}\n","'use client';\n\nimport { QueryClient, QueryClientProvider } from '@tanstack/react-query';\nimport { ReactNode } from 'react';\n\nexport function makeQueryClient() {\n return new QueryClient({\n defaultOptions: {\n queries: {\n refetchOnWindowFocus: false,\n refetchOnReconnect: false,\n },\n },\n });\n}\n\nlet browserQueryClient: QueryClient | undefined = undefined;\n\nexport function getQueryClient() {\n if (typeof window === 'undefined') {\n return makeQueryClient();\n } else {\n if (!browserQueryClient) browserQueryClient = makeQueryClient();\n return browserQueryClient;\n }\n}\n\n\nexport function QueryProvider({ children }: { children: ReactNode }) {\n const queryClient = getQueryClient();\n\n return <QueryClientProvider client={queryClient}>{children}</QueryClientProvider>;\n}\n","/**\n * @softimist/api - Utility Functions\n * \n * Common utility functions for API error and response handling\n */\n\ntype ApiErrorLike = {\n message?: unknown;\n response?: {\n data?: {\n message?: unknown;\n error?: unknown;\n };\n };\n};\n\n/**\n * Extract error message from various error types\n */\nexport function getErrorMessage(error: unknown): string {\n const err = error as ApiErrorLike | null | undefined;\n \n // Try to get message from API response\n const apiMessage = err?.response?.data?.message;\n if (typeof apiMessage === 'string' && apiMessage.trim() !== '') {\n return apiMessage;\n }\n\n // Try to get error from API response\n const apiError = err?.response?.data?.error;\n if (typeof apiError === 'string' && apiError.trim() !== '') {\n return apiError;\n }\n\n // Try to get message from error object\n const message = err?.message;\n if (typeof message === 'string' && message.trim() !== '') {\n return message;\n }\n\n // Try Error instance message\n if (error instanceof Error && error.message.trim() !== '') {\n return error.message;\n }\n\n return 'Something went wrong';\n}\n\n/**\n * Extract success message from API response\n */\nexport function getSuccessMessage(response: any, defaultMessage?: string): string {\n return response?.data?.message || defaultMessage || 'Success';\n}\n","/**\n * @softimist/api - Shared API Types, Interfaces, and Hooks\n *\n * Main exports for the API package\n */\n\n// Server Response Types (Backend API)\nexport type { ServerResponse, ServerPaginatedResponse, PaginationMeta } from './types';\n\n// Hook Return Types (Client-side React Hooks)\nexport type { UsePaginatedApiReturn } from './types';\n\n// HTTP Client Abstraction\nexport type { HttpClient, HttpResponse, PaginationOptions, UsePaginatedApiHook } from './types';\n\n// Filter Types\nexport type {\n\tFilter,\n\tSelectFilter,\n\tMultiSelectFilter,\n\tDateFilter,\n\tBooleanFilter,\n\tNumberFilter,\n\tRangeFilter,\n\tStringFilter,\n} from './filter';\n\n// Base API Client\nexport { BaseApiClient, type BaseApiClientConfig, type RequestConfig } from './client';\n\n// React Hooks\nexport { useApi, useApiAction, usePaginatedApi, useMockPaginatedApi } from './hooks';\n\n// Utility Functions\nexport { getErrorMessage, getSuccessMessage } from './utils';\n\n// TanStack Query\nexport { QueryProvider, makeQueryClient, getQueryClient } from './tanstack-query';\n\nexport { useInfiniteQuery, useQuery } from '@tanstack/react-query';\n"],"mappings":"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","names":["useQuery"]}
|
|
1
|
+
{"version":3,"sources":["../src/client.ts","../src/hooks.ts","../src/tanstack-query.tsx","../src/utils.ts","../src/index.ts"],"sourcesContent":["/**\n * @softimist/api - Base API Client\n *\n * Base class for API clients that can be extended by module-specific implementations.\n * Uses axios for HTTP requests and provides common functionality like authentication,\n * error handling, and request/response interceptors.\n *\n * All HTTP methods return unwrapped server response data directly (e.g., ServerResponse<T>).\n */\n\nimport axios, { AxiosResponse, type AxiosInstance, type AxiosRequestConfig } from 'axios';\nimport type { HttpClient } from './types';\n\n/**\n * Configuration options for BaseApiClient\n */\nexport interface BaseApiClientConfig {\n\tbaseURL?: string;\n\tgetAuthToken?: () => string | null;\n\tgetRefreshToken?: () => string | null;\n\tsetAuthToken?: (token: string) => void;\n\tsetRefreshToken?: (token: string) => void;\n\tclearAuthTokens?: () => void;\n\trefreshTokenUrl?: string;\n\ttimeout?: number;\n\theaders?: Record<string, string>;\n}\n\n/**\n * Request configuration passed to HTTP methods\n */\nexport interface RequestConfig {\n\theaders?: Record<string, string>;\n\tparams?: Record<string, any>;\n\t[key: string]: any;\n}\n\n/**\n * Base API Client class\n * Provides common HTTP functionality using axios that can be extended by module-specific clients\n *\n * @example\n * ```ts\n * class WebsiteApiClient extends BaseApiClient {\n * async getPages(): Promise<ServerPaginatedResponse<Page>> {\n * return this.get<ServerPaginatedResponse<Page>>('/api/v1/website/pages');\n * }\n * }\n * ```\n */\nexport class BaseApiClient implements HttpClient {\n\tprotected axiosInstance: AxiosInstance;\n\tprotected getAuthToken?: () => string | null;\n\tprotected getRefreshToken?: () => string | null;\n\tprotected setAuthToken?: (token: string) => void;\n\tprotected setRefreshToken?: (token: string) => void;\n\tprotected clearAuthTokens?: () => void;\n\tprotected refreshTokenUrl?: string;\n\tprivate isRefreshing = false;\n\tprivate failedQueue: Array<{\n\t\tresolve: (value?: any) => void;\n\t\treject: (error?: any) => void;\n\t}> = [];\n\n\tconstructor(config: BaseApiClientConfig = {}) {\n\t\tconst defaultHeaders = {\n\t\t\t'Content-Type': 'application/json',\n\t\t\tAccept: 'application/json',\n\t\t\t...config.headers,\n\t\t};\n\n\t\tthis.axiosInstance = axios.create({\n\t\t\tbaseURL: config.baseURL || '',\n\t\t\ttimeout: config.timeout || 30000,\n\t\t\theaders: defaultHeaders,\n\t\t});\n\n\t\tthis.getAuthToken = config.getAuthToken;\n\t\tthis.getRefreshToken = config.getRefreshToken;\n\t\tthis.setAuthToken = config.setAuthToken;\n\t\tthis.setRefreshToken = config.setRefreshToken;\n\t\tthis.clearAuthTokens = config.clearAuthTokens;\n\t\tthis.refreshTokenUrl = config.refreshTokenUrl || `${config.baseURL || ''}/v1/auth/refresh`;\n\n\t\t// Set up request interceptor for authentication\n\t\tthis.axiosInstance.interceptors.request.use(\n\t\t\t(requestConfig) => {\n\t\t\t\tif (this.getAuthToken) {\n\t\t\t\t\tconst token = this.getAuthToken();\n\t\t\t\t\tif (token) {\n\t\t\t\t\t\trequestConfig.headers.Authorization = `Bearer ${token}`;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn requestConfig;\n\t\t\t},\n\t\t\t(error) => {\n\t\t\t\treturn Promise.reject(error);\n\t\t\t},\n\t\t);\n\n\t\t// Set up response interceptor for error handling and token refresh\n\t\tthis.axiosInstance.interceptors.response.use(\n\t\t\t(response) => response,\n\t\t\tasync (error) => {\n\t\t\t\tconst originalRequest = error.config;\n\n\t\t\t\t// Handle 401 errors with token refresh\n\t\t\t\tif (error.response?.status === 401 && !originalRequest._retry && this.getRefreshToken) {\n\t\t\t\t\tif (this.isRefreshing) {\n\t\t\t\t\t\t// If we're already refreshing, queue this request\n\t\t\t\t\t\treturn new Promise((resolve, reject) => {\n\t\t\t\t\t\t\tthis.failedQueue.push({ resolve, reject });\n\t\t\t\t\t\t})\n\t\t\t\t\t\t\t.then((token) => {\n\t\t\t\t\t\t\t\toriginalRequest.headers.Authorization = `Bearer ${token}`;\n\t\t\t\t\t\t\t\treturn this.axiosInstance(originalRequest);\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t.catch((err) => {\n\t\t\t\t\t\t\t\treturn Promise.reject(err);\n\t\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\toriginalRequest._retry = true;\n\t\t\t\t\tthis.isRefreshing = true;\n\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst accessToken = await this.refreshAuthToken();\n\n\t\t\t\t\t\t// Update the original request with new token\n\t\t\t\t\t\toriginalRequest.headers.Authorization = `Bearer ${accessToken}`;\n\n\t\t\t\t\t\t// Process queued requests\n\t\t\t\t\t\tthis.processQueue(null, accessToken);\n\t\t\t\t\t\tthis.isRefreshing = false;\n\n\t\t\t\t\t\t// Retry the original request\n\t\t\t\t\t\treturn this.axiosInstance(originalRequest);\n\t\t\t\t\t} catch (refreshError) {\n\t\t\t\t\t\t// Refresh token is invalid, clear all tokens\n\t\t\t\t\t\tthis.processQueue(refreshError, null);\n\t\t\t\t\t\tthis.isRefreshing = false;\n\t\t\t\t\t\treturn Promise.reject(this.handleError(refreshError));\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn Promise.reject(this.handleError(error));\n\t\t\t},\n\t\t);\n\t}\n\n\t/**\n\t * Process queued requests after token refresh\n\t */\n\tprivate processQueue(error: any, token: string | null = null) {\n\t\tthis.failedQueue.forEach(({ resolve, reject }) => {\n\t\t\tif (error) {\n\t\t\t\treject(error);\n\t\t\t} else {\n\t\t\t\tresolve(token);\n\t\t\t}\n\t\t});\n\t\tthis.failedQueue = [];\n\t}\n\n\t/**\n\t * Refresh authentication token\n\t */\n\tprivate async refreshAuthToken(): Promise<string> {\n\t\tif (!this.getRefreshToken) {\n\t\t\tthrow new Error('No refresh token function provided');\n\t\t}\n\n\t\tconst refreshToken = this.getRefreshToken();\n\t\tif (!refreshToken) {\n\t\t\tif (this.clearAuthTokens) {\n\t\t\t\tthis.clearAuthTokens();\n\t\t\t}\n\t\t\tthrow new Error('No refresh token available');\n\t\t}\n\n\t\ttry {\n\t\t\t// Use a fresh axios instance for refresh token request to avoid circular interceptor issues\n\t\t\tconst response = await axios.post(\n\t\t\t\tthis.refreshTokenUrl!,\n\t\t\t\t{\n\t\t\t\t\trefresh_token: refreshToken,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tbaseURL: '', // Use absolute URL or empty to avoid baseURL duplication\n\t\t\t\t},\n\t\t\t);\n\n\t\t\tconst { access_token, refresh_token } = response.data;\n\n\t\t\tif (this.setAuthToken) {\n\t\t\t\tthis.setAuthToken(access_token);\n\t\t\t}\n\t\t\tif (refresh_token && this.setRefreshToken) {\n\t\t\t\tthis.setRefreshToken(refresh_token);\n\t\t\t}\n\n\t\t\treturn access_token;\n\t\t} catch (error) {\n\t\t\t// Refresh token is invalid, clear all tokens\n\t\t\tif (this.clearAuthTokens) {\n\t\t\t\tthis.clearAuthTokens();\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\t/**\n\t * Handle request errors\n\t */\n\tprotected handleError(error: any): Error {\n\t\tif (error.response) {\n\t\t\t// Server responded with error status\n\t\t\tconst message =\n\t\t\t\terror.response.data?.message ||\n\t\t\t\terror.response.data?.error ||\n\t\t\t\terror.message ||\n\t\t\t\t'An unknown error occurred';\n\t\t\terror.message = message;\n\t\t\treturn error;\n\t\t}\n\t\treturn error;\n\t}\n\n\t/**\n\t * Make HTTP GET request\n\t * Returns unwrapped server response data\n\t */\n\tasync get<T = any>(url: string, config?: RequestConfig): Promise<T> {\n\t\tconst axiosConfig: AxiosRequestConfig = {\n\t\t\tparams: config?.params,\n\t\t\theaders: config?.headers,\n\t\t\t...config,\n\t\t};\n\t\tdelete axiosConfig.params;\n\t\tdelete axiosConfig.headers;\n\n\t\tconst response = await this.axiosInstance.get<T>(url, {\n\t\t\t...axiosConfig,\n\t\t\tparams: config?.params,\n\t\t\theaders: config?.headers,\n\t\t});\n\n\t\treturn response.data;\n\t}\n\n\t/**\n\t * Make HTTP POST request\n\t * Returns unwrapped server response data\n\t */\n\tasync post<T = any>(url: string, data?: any, config?: RequestConfig): Promise<T> {\n\t\tconst axiosConfig: AxiosRequestConfig = {\n\t\t\theaders: config?.headers,\n\t\t\t...config,\n\t\t};\n\t\tdelete axiosConfig.headers;\n\n\t\tconst response = await this.axiosInstance.post<T>(url, data, {\n\t\t\t...axiosConfig,\n\t\t\theaders: config?.headers,\n\t\t});\n\n\t\treturn response.data;\n\t}\n\n\t/**\n\t * Make HTTP PATCH request\n\t * Returns unwrapped server response data\n\t */\n\tasync patch<T = any>(url: string, data?: any, config?: RequestConfig): Promise<T> {\n\t\tconst axiosConfig: AxiosRequestConfig = {\n\t\t\theaders: config?.headers,\n\t\t\t...config,\n\t\t};\n\t\tdelete axiosConfig.headers;\n\n\t\tconst response = await this.axiosInstance.patch<T>(url, data, {\n\t\t\t...axiosConfig,\n\t\t\theaders: config?.headers,\n\t\t});\n\n\t\treturn response.data;\n\t}\n\n\t/**\n\t * Make HTTP PUT request\n\t * Returns unwrapped server response data\n\t */\n\tasync put<T = any>(url: string, data?: any, config?: RequestConfig): Promise<T> {\n\t\tconst axiosConfig: AxiosRequestConfig = {\n\t\t\theaders: config?.headers,\n\t\t\t...config,\n\t\t};\n\t\tdelete axiosConfig.headers;\n\n\t\tconst response = await this.axiosInstance.put<T>(url, data, {\n\t\t\t...axiosConfig,\n\t\t\theaders: config?.headers,\n\t\t});\n\n\t\treturn response.data;\n\t}\n\n\t/**\n\t * Make HTTP DELETE request\n\t * Returns unwrapped server response data\n\t */\n\tasync delete<T = any>(url: string, config?: RequestConfig): Promise<T> {\n\t\tconst axiosConfig: AxiosRequestConfig = {\n\t\t\theaders: config?.headers,\n\t\t\t...config,\n\t\t};\n\t\tdelete axiosConfig.headers;\n\n\t\tconst response = await this.axiosInstance.delete<T>(url, {\n\t\t\t...axiosConfig,\n\t\t\theaders: config?.headers,\n\t\t});\n\n\t\treturn response.data;\n\t}\n\n\tasync export(\n\t\turl: string,\n\t\tconfig?: AxiosRequestConfig & {\n\t\t\tonDownloadProgress?: (event: ProgressEvent) => void;\n\t\t},\n\t): Promise<AxiosResponse<ArrayBuffer>> {\n\t\treturn this.axiosInstance.get(url, {\n\t\t\tresponseType: 'arraybuffer',\n\t\t\t...config,\n\t\t});\n\t}\n\n\t/**\n\t * Get the underlying axios instance for advanced usage\n\t */\n\tget axios(): AxiosInstance {\n\t\treturn this.axiosInstance;\n\t}\n\n\t/**\n\t * Create a new client instance with a different baseURL\n\t * Useful for server-side requests or different API endpoints\n\t */\n\twithBaseURL(baseURL: string): this {\n\t\tconst ConfigClass = this.constructor as new (config: BaseApiClientConfig) => this;\n\n\t\t// Create a fresh copy of headers to avoid reference issues\n\t\tconst headers = { ...this.axiosInstance.defaults.headers } as Record<string, string>;\n\n\t\treturn new ConfigClass({\n\t\t\tbaseURL,\n\t\t\tgetAuthToken: this.getAuthToken,\n\t\t\tgetRefreshToken: this.getRefreshToken,\n\t\t\tsetAuthToken: this.setAuthToken,\n\t\t\tsetRefreshToken: this.setRefreshToken,\n\t\t\tclearAuthTokens: this.clearAuthTokens,\n\t\t\trefreshTokenUrl: this.refreshTokenUrl,\n\t\t\ttimeout: this.axiosInstance.defaults.timeout,\n\t\t\theaders,\n\t\t});\n\t}\n}\n","/**\n * @softimist/api - React Hooks for API interactions\n *\n * Generic hooks that work with any HttpClient implementation\n */\n'use client';\n\nimport { useQuery, useMutation, type QueryKey, type UseQueryOptions } from '@tanstack/react-query';\nimport { createParser, parseAsInteger, parseAsString, useQueryState } from 'nuqs';\nimport { useState } from 'react';\nimport { toast } from 'sonner';\nimport type {\n\tHttpClient,\n\tPaginationOptions,\n\tServerPaginatedResponse,\n\tServerResponse,\n\tUsePaginatedApiReturn,\n} from './types';\nimport type { Filter } from './filter';\nimport { getQueryClient } from './tanstack-query';\n\n/**\n * Hook for making simple API GET requests\n */\nexport function useApi<T>(\n\thttpClient: HttpClient,\n\turl: string | null,\n\toptions: Omit<UseQueryOptions<ServerResponse<T>>, 'queryKey' | 'queryFn' | 'enabled'> & {\n\t\tqueryKey?: QueryKey;\n\t\tenabled?: boolean;\n\t} = {},\n) {\n\tconst { queryKey, enabled = true, ...restOptions } = options;\n\n\treturn useQuery<ServerResponse<T>>({\n\t\tqueryKey: queryKey || [url],\n\t\tqueryFn: async () => {\n\t\t\tif (!url) throw new Error('URL is required');\n\t\t\treturn httpClient.get<ServerResponse<T>>(url);\n\t\t},\n\t\tenabled: url !== null && enabled,\n\t\t...restOptions,\n\t});\n}\n\n/**\n * Hook for making API mutations (POST, PATCH, PUT, DELETE) with toast notifications\n *\n * @template T - The response data type\n * @template TArg - The argument type for the action (defaults to void for backward compatibility)\n */\nexport function useApiAction<T, TArg = void>(\n\toptions: {\n\t\taction: (arg: TArg) => Promise<ServerResponse<T>>;\n\t\tshowToast?: boolean;\n\t\tinvalidateQueries?: QueryKey[];\n\t\tonSuccess?: (data: T) => void;\n\t\tonError?: (error: Error) => void;\n\t},\n) {\n\tconst { action, showToast = true, invalidateQueries, onSuccess, onError } = options;\n\n\tconst mutation = useMutation({\n\t\tmutationFn: action,\n\n\t\tonSuccess: (res) => {\n\t\t\tonSuccess?.(res.data);\n\t\t\tif (showToast) {\n\t\t\t\ttoast.success(res.message || 'Success');\n\t\t\t}\n\t\t\tif (invalidateQueries && invalidateQueries.length > 0) {\n\t\t\t\tconst queryClient = getQueryClient();\n\t\t\t\tinvalidateQueries.forEach((queryKey) => {\n\t\t\t\t\tqueryClient.invalidateQueries({ queryKey });\n\t\t\t\t});\n\t\t\t}\n\t\t},\n\t\tonError: (err: Error) => {\n\t\t\tonError?.(err);\n\t\t\tif (showToast) {\n\t\t\t\ttoast.error(err.message || 'An error occurred');\n\t\t\t}\n\t\t},\n\t});\n\n\treturn {\n /** execute mutation */\n execute: mutation.mutate,\n\n /** async version if needed */\n executeAsync: mutation.mutateAsync,\n\n /** states */\n isLoading: mutation.isPending,\n isSuccess: mutation.isSuccess,\n isError: mutation.isError,\n isExecuted: mutation.status !== 'idle',\n\n /** data & error */\n data: mutation.data?.data,\n error: mutation.error ?? undefined,\n\n /** reset to idle */\n reset: mutation.reset,\n };\n}\n\nconst parseAsFilterArray = createParser<Filter[]>({\n\tparse: (value) => {\n\t\treturn JSON.parse(value);\n\t},\n\tserialize: (value) => {\n\t\treturn JSON.stringify(value);\n\t},\n});\n\nfunction usePaginationState(options: PaginationOptions) {\n\tconst { persist = true, params: defaultParams } = options;\n\tconst defaultPerPage = (defaultParams?.per_page as number) || 20;\n\tconst defaultPage = (defaultParams?.page as number) || 1;\n\tconst [perPageQuery, setPerPageQuery] = useQueryState(\n\t\t'per_page',\n\t\tparseAsInteger.withDefault(defaultPerPage),\n\t);\n\tconst [pageQuery, setPageQuery] = useQueryState('page', parseAsInteger.withDefault(defaultPage));\n\tconst [searchQuery, setSearchQuery] = useQueryState('search', parseAsString.withDefault(''));\n\tconst [filtersQuery, setFiltersQuery] = useQueryState(\n\t\t'filters',\n\t\tparseAsFilterArray.withDefault([]),\n\t);\n\tconst [sortQuery, setSortQuery] = useQueryState('sort', parseAsString.withDefault(''));\n\n\tconst [perPageState, setPerPageState] = useState<number>(defaultPerPage);\n\tconst [pageState, setPageState] = useState<number>(defaultPage);\n\tconst [searchState, setSearchState] = useState<string>('');\n\tconst [filtersState, setFiltersState] = useState<Filter[]>([]);\n\tconst [sortState, setSortState] = useState<string>();\n\n\tconst perPage = persist ? perPageQuery : perPageState;\n\tconst page = persist ? pageQuery : pageState;\n\tconst search = persist ? searchQuery : searchState;\n\tconst filters = persist ? filtersQuery : filtersState;\n\tconst sort = persist ? sortQuery : sortState;\n\n\tconst setPerPage = (value: number | ((prev: number) => number)) => {\n\t\tif (persist) {\n\t\t\tsetPerPageQuery(value);\n\t\t} else {\n\t\t\tsetPerPageState(value);\n\t\t}\n\t};\n\n\tconst setPage = (value: number | ((prev: number) => number)) => {\n\t\tif (persist) {\n\t\t\tsetPageQuery(value);\n\t\t} else {\n\t\t\tsetPageState(value);\n\t\t}\n\t};\n\n\tconst setSearch = (value: string | ((prev: string) => string)) => {\n\t\tif (persist) {\n\t\t\tsetSearchQuery(value);\n\t\t} else {\n\t\t\tsetSearchState(value);\n\t\t}\n\t};\n\n\tconst setFilters = (value: Filter[] | ((prev: Filter[]) => Filter[])) => {\n\t\tif (persist) {\n\t\t\tsetFiltersQuery(value);\n\t\t} else {\n\t\t\tsetFiltersState(value);\n\t\t}\n\t};\n\n\tconst setSort = (value: string | ((prev: string) => string)) => {\n\t\tif (persist) {\n\t\t\tsetSortQuery(value);\n\t\t} else {\n\t\t\tsetSortState(typeof value === 'function' ? value(sortState || '') : value);\n\t\t}\n\t};\n\n\tconst getParams = () => {\n\t\tconst params = new URLSearchParams();\n\t\tif (defaultParams) {\n\t\t\tObject.entries(defaultParams).forEach(([key, value]) => {\n\t\t\t\tif (value !== undefined) {\n\t\t\t\t\tparams.set(key, value.toString());\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t\tif (perPage) params.set('per_page', perPage.toString());\n\t\tif (page) params.set('page', page.toString());\n\t\tif (search) params.set('search', search);\n\t\tif (sort) {\n\t\t\tconst [sortBy, sortDirection] = sort.split(':');\n\t\t\tif (sortBy) params.set('sort_by', sortBy);\n\t\t\tif (sortDirection) params.set('sort_dir', sortDirection);\n\t\t}\n\t\tfilters?.forEach((filter) => {\n\t\t\tif (Array.isArray(filter.value)) {\n\t\t\t\tfilter.value.forEach((v) => {\n\t\t\t\t\tparams.append(filter.key, v.toString());\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tparams.set(filter.key, filter.value.toString());\n\t\t\t}\n\t\t});\n\t\treturn params;\n\t};\n\n\treturn {\n\t\tperPage,\n\t\tpage,\n\t\tsearch,\n\t\tfilters,\n\t\tsort,\n\t\tsetPerPage,\n\t\tsetPage,\n\t\tsetSearch,\n\t\tsetFilters,\n\t\tsetSort,\n\t\tgetParams,\n\t};\n}\n\n/**\n * Hook for making paginated API requests with URL state management\n */\nexport function usePaginatedApi<T>(\n\thttpClient: HttpClient,\n\tpath: string | null,\n\toptions: PaginationOptions = {},\n): UsePaginatedApiReturn<T> {\n\tconst {\n\t\tperPage,\n\t\tpage,\n\t\tsearch,\n\t\tfilters,\n\t\tsort,\n\t\tsetPerPage,\n\t\tsetPage,\n\t\tsetSearch,\n\t\tsetFilters,\n\t\tsetSort,\n\t\tgetParams,\n\t} = usePaginationState(options);\n\n\tconst getUrl = (): string | null => {\n\t\tif (!path) return null;\n\t\tconst params = getParams();\n\t\treturn params.size === 0 ? path : `${path}?${params.toString()}`;\n\t};\n\n\tconst url = getUrl();\n\n\tconst { data, isLoading, error, refetch, isSuccess, isFetching } = useQuery({\n\t\tqueryKey: [path, options, page, perPage, search, filters, sort],\n\t\tqueryFn: async () => {\n\t\t\tif (!url) throw new Error('URL is required');\n\t\t\treturn httpClient.get<ServerPaginatedResponse<T>>(url);\n\t\t},\n\t\tenabled: !!url,\n\t});\n\n\tfunction getBulkActionUrl(\n\t\taction: string,\n\t\tadditionalFilters?: Record<string, string | string[]>,\n\t): string {\n\t\tconst params = getParams();\n\t\tparams.delete('page');\n\t\tparams.delete('per_page');\n\t\tObject.entries(additionalFilters || {}).forEach(([key, value]) => {\n\t\t\tif (value === undefined) {\n\t\t\t\tparams.delete(key);\n\t\t\t} else if (Array.isArray(value)) {\n\t\t\t\tvalue.forEach((v) => {\n\t\t\t\t\tparams.append(key, v);\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tparams.set(key, value);\n\t\t\t}\n\t\t});\n\t\tif (params.size === 0) return `${path}/${action}`;\n\t\treturn `${path}/${action}?${params.toString()}`;\n\t}\n\n\tfunction setFilter(key: string, value: any) {\n\t\tif (value === undefined) {\n\t\t\tremoveFilter(key);\n\t\t\treturn;\n\t\t}\n\t\tconst index = filters.findIndex((filter) => filter.key === key);\n\t\tif (index === -1) {\n\t\t\tsetFilters([...filters, { key, value }]);\n\t\t} else {\n\t\t\tsetFilters([...filters.slice(0, index), { key, value }, ...filters.slice(index + 1)]);\n\t\t}\n\t}\n\n\tfunction removeFilter(key: string) {\n\t\tsetFilters(filters.filter((filter) => filter.key !== key));\n\t}\n\n\tfunction getFilterValue(key: string) {\n\t\treturn filters.find((filter) => filter.key === key)?.value;\n\t}\n\n\tfunction resetFilters() {\n\t\tsetFilters([]);\n\t}\n\n\treturn {\n\t\tmessage: data?.message || '',\n\t\tdata: data?.data || [],\n\t\tpagination: data?.pagination,\n\t\tisLoading,\n\t\tisSuccess,\n\t\tisFetching,\n\t\terror: error as Error | null,\n\t\tmutate: refetch,\n\t\tpage,\n\t\tsetPage,\n\t\tperPage,\n\t\tsetPerPage,\n\t\tsearch,\n\t\tsetSearch,\n\t\tfilters,\n\t\tsetFilters,\n\t\tsetFilter,\n\t\tremoveFilter,\n\t\tgetFilterValue,\n\t\tresetFilters,\n\t\tgetBulkActionUrl,\n\t\tsort,\n\t\tsetSort,\n\t};\n}\n\n/**\n * Mock hook for testing/development\n * Returns a mock paginated response with the provided data\n */\nexport function useMockPaginatedApi<T>(data: T[]): UsePaginatedApiReturn<T> {\n\treturn {\n\t\tdata,\n\t\tpagination: {\n\t\t\ttotal: data.length,\n\t\t\tper_page: 10,\n\t\t\tcurrent_page: 1,\n\t\t\ttotal_pages: Math.ceil(data.length / 10),\n\t\t\tfrom: 1,\n\t\t\tto: data.length,\n\t\t},\n\t\tmessage: 'Data fetched successfully',\n\t\tisLoading: false,\n\t\tisSuccess: true,\n\t\tisFetching: false,\n\t\tmutate: () => {},\n\t\tpage: 1,\n\t\tsetPage: () => {},\n\t\tperPage: 10,\n\t\tsetPerPage: () => {},\n\t\tsearch: '',\n\t\tsetSearch: () => {},\n\t\tfilters: [],\n\t\tsetFilters: () => {},\n\t\tgetFilterValue: () => undefined,\n\t\tresetFilters: () => {},\n\t\tsetFilter: () => {},\n\t\tremoveFilter: () => {},\n\t\tsort: '',\n\t\tsetSort: () => {},\n\t\tgetBulkActionUrl: () => '',\n\t};\n}\n","'use client';\n\nimport { QueryClient, QueryClientProvider } from '@tanstack/react-query';\nimport { ReactNode } from 'react';\n\nexport function makeQueryClient() {\n return new QueryClient({\n defaultOptions: {\n queries: {\n refetchOnWindowFocus: false,\n refetchOnReconnect: false,\n },\n },\n });\n}\n\nlet browserQueryClient: QueryClient | undefined = undefined;\n\nexport function getQueryClient() {\n if (typeof window === 'undefined') {\n return makeQueryClient();\n } else {\n if (!browserQueryClient) browserQueryClient = makeQueryClient();\n return browserQueryClient;\n }\n}\n\n\nexport function QueryProvider({ children }: { children: ReactNode }) {\n const queryClient = getQueryClient();\n\n return <QueryClientProvider client={queryClient}>{children}</QueryClientProvider>;\n}\n","/**\n * @softimist/api - Utility Functions\n * \n * Common utility functions for API error and response handling\n */\n\ntype ApiErrorLike = {\n message?: unknown;\n response?: {\n data?: {\n message?: unknown;\n error?: unknown;\n };\n };\n};\n\n/**\n * Extract error message from various error types\n */\nexport function getErrorMessage(error: unknown): string {\n const err = error as ApiErrorLike | null | undefined;\n \n // Try to get message from API response\n const apiMessage = err?.response?.data?.message;\n if (typeof apiMessage === 'string' && apiMessage.trim() !== '') {\n return apiMessage;\n }\n\n // Try to get error from API response\n const apiError = err?.response?.data?.error;\n if (typeof apiError === 'string' && apiError.trim() !== '') {\n return apiError;\n }\n\n // Try to get message from error object\n const message = err?.message;\n if (typeof message === 'string' && message.trim() !== '') {\n return message;\n }\n\n // Try Error instance message\n if (error instanceof Error && error.message.trim() !== '') {\n return error.message;\n }\n\n return 'Something went wrong';\n}\n\n/**\n * Extract success message from API response\n */\nexport function getSuccessMessage(response: any, defaultMessage?: string): string {\n return response?.data?.message || defaultMessage || 'Success';\n}\n","/**\n * @softimist/api - Shared API Types, Interfaces, and Hooks\n *\n * Main exports for the API package\n */\n\n// Server Response Types (Backend API)\nexport type { ServerResponse, ServerPaginatedResponse, PaginationMeta } from './types';\n\n// Hook Return Types (Client-side React Hooks)\nexport type { UsePaginatedApiReturn } from './types';\n\n// HTTP Client Abstraction\nexport type { HttpClient, HttpResponse, PaginationOptions, UsePaginatedApiHook } from './types';\n\n// Filter Types\nexport type {\n\tFilter,\n\tSelectFilter,\n\tMultiSelectFilter,\n\tDateFilter,\n\tBooleanFilter,\n\tNumberFilter,\n\tRangeFilter,\n\tStringFilter,\n} from './filter';\n\n// Base API Client\nexport { BaseApiClient, type BaseApiClientConfig, type RequestConfig } from './client';\n\n// React Hooks\nexport { useApi, useApiAction, usePaginatedApi, useMockPaginatedApi } from './hooks';\n\n// Utility Functions\nexport { getErrorMessage, getSuccessMessage } from './utils';\n\n// TanStack Query\nexport { QueryProvider, makeQueryClient, getQueryClient } from './tanstack-query';\n\nexport { useInfiniteQuery, useQuery } from '@tanstack/react-query';\n"],"mappings":"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","names":["useQuery"]}
|