UNPKG

@danstackme/apity

Version:

Type-safe API client generator for React applications with file-based routing and runtime validation

1 lines 10.1 kB
{"version":3,"sources":["../../src/context.tsx","../../src/utils.ts","../../src/useFetch.ts","../../src/useMutate.ts","../../src/createApi.ts"],"names":["createContext","useContext","QueryClient","jsx","QueryClientProvider","useQuery","useMutation","axios"],"mappings":"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","file":"index.cjs","sourcesContent":["import { QueryClient, QueryClientProvider } from \"@tanstack/react-query\";\nimport { AxiosInstance } from \"axios\";\nimport { createContext, useContext } from \"react\";\nimport type { ApiContext as ApiContextType } from \"./types\";\n\ninterface ApiContextValue {\n client: AxiosInstance;\n queryClient: ApiContextType[\"queryClient\"];\n config: ApiContextType[\"config\"];\n}\n\nconst ApiContext = createContext<ApiContextValue | null>(null);\n\nexport function useApiContext(): ApiContextValue {\n const context = useContext(ApiContext);\n if (!context) {\n throw new Error(\"useApiContext must be used within an ApiProvider\");\n }\n return context;\n}\n\ninterface ApiProviderProps {\n children: React.ReactNode;\n api: ApiContextType;\n}\n\nexport function ApiProvider({ children, api }: ApiProviderProps) {\n const queryClient = api.queryClient ?? new QueryClient();\n\n const value: ApiContextValue = {\n client: api.client,\n queryClient,\n config: api.config,\n };\n\n return (\n <QueryClientProvider client={queryClient}>\n <ApiContext.Provider value={value}>{children}</ApiContext.Provider>\n </QueryClientProvider>\n );\n}\n","export function getParamName(path: string): string {\n const match = path.match(/\\[([^\\]]+)\\]/);\n return match ? match[1] : \"\";\n}\n\nexport function interpolatePath(\n path: string,\n params: Record<string, string>\n): string {\n return path.replace(/\\[([^\\]]+)\\]/g, (_, key) => {\n if (!params[key]) {\n throw new Error(`Missing path parameter: ${key}`);\n }\n return params[key];\n });\n}\n","import { useQuery } from \"@tanstack/react-query\";\nimport { useApiContext } from \"./context\";\nimport { UseFetchOptionsType, FetchPath } from \"./types\";\n\nimport { getParamName, interpolatePath } from \"./utils\";\n\nexport function useFetch<TPath extends FetchPath>(\n options: UseFetchOptionsType<TPath>\n) {\n const { path, params, query, enabled = true, ...queryOptions } = options;\n const { client, config } = useApiContext();\n\n if (path.includes(\"[\") && (!params || Object.keys(params).length === 0)) {\n throw new Error(`Missing path parameter: ${getParamName(path)}`);\n }\n\n const url = interpolatePath(path, params || {});\n\n return useQuery({\n ...queryOptions,\n queryKey: [path, params, query],\n queryFn: async () => {\n const response = await client.get(url, {\n baseURL: config.baseUrl,\n params: query,\n });\n return response.data;\n },\n enabled,\n });\n}\n","import { useMutation } from \"@tanstack/react-query\";\nimport { useApiContext } from \"./context\";\nimport type {\n AvailableMutateMethods,\n MutateBodyFor,\n MutatePath,\n MutateResponseFor,\n UseMutateOptionsType,\n} from \"./types\";\n\nimport { getParamName, interpolatePath } from \"./utils\";\n\nexport function useMutate<\n TPath extends MutatePath,\n TMethod extends AvailableMutateMethods<TPath>,\n>(options: UseMutateOptionsType<TPath, TMethod>) {\n const { path, params, method, ...mutationOptions } = options;\n const { client, config } = useApiContext();\n\n if (path.includes(\"[\") && (!params || Object.keys(params).length === 0)) {\n throw new Error(`Missing path parameter: ${getParamName(path)}`);\n }\n\n const url = interpolatePath(path, params || {});\n\n return useMutation({\n ...mutationOptions,\n mutationFn: async (\n data?: MutateBodyFor<TPath, TMethod>\n ): Promise<MutateResponseFor<TPath, TMethod>> => {\n const response = await client.request({\n method,\n url,\n baseURL: config.baseUrl,\n data,\n });\n return response.data;\n },\n });\n}\n","import { QueryClient } from \"@tanstack/react-query\";\nimport axios from \"axios\";\nimport {\n ApiConfig,\n ApiContext,\n FetchEndpoint,\n HttpMethod,\n MutateEndpoint,\n} from \"./types\";\nimport { z } from \"zod\";\nexport function createApiEndpoint<\n TMethod extends HttpMethod,\n TResponse = unknown,\n TBody = unknown,\n TQuery = unknown,\n>(config: {\n method: TMethod;\n response?: z.ZodType<TResponse>;\n body?: z.ZodType<TBody>;\n query?: z.ZodType<TQuery>;\n}): TMethod extends \"GET\"\n ? FetchEndpoint<TResponse, TBody, TQuery>\n : TMethod extends Exclude<HttpMethod, \"GET\">\n ? MutateEndpoint<TMethod, TResponse, TBody, TQuery>\n : never {\n return {\n ...config,\n method: config.method,\n response: config.response,\n body: config.body,\n query: config.query,\n } as TMethod extends \"GET\"\n ? FetchEndpoint<TResponse, TBody, TQuery>\n : TMethod extends Exclude<HttpMethod, \"GET\">\n ? MutateEndpoint<TMethod, TResponse, TBody, TQuery>\n : never;\n}\n\nexport function createApi(config: ApiConfig): ApiContext {\n const queryClient = config.queryClient || new QueryClient();\n const client = config.client || axios.create();\n\n // Configure client\n client.defaults.baseURL = config.baseUrl;\n\n // Set headers directly on the client's headers object\n if (config.headers) {\n Object.assign(client.defaults.headers, config.headers);\n }\n\n // Initialize middleware array\n const middlewareFns: ((config: any) => any)[] = [];\n\n // Add middleware functions to array if they exist\n if (config.middleware) {\n if (config.middleware.before) {\n middlewareFns.push(config.middleware.before);\n client.interceptors.request.use(config.middleware.before);\n }\n if (config.middleware.after) {\n middlewareFns.push(config.middleware.after);\n client.interceptors.response.use(config.middleware.after);\n }\n if (config.middleware.onError) {\n middlewareFns.push(config.middleware.onError);\n client.interceptors.response.use(undefined, config.middleware.onError);\n }\n }\n\n return {\n client,\n queryClient,\n config,\n middleware: middlewareFns,\n fetchEndpoints: config.fetchEndpoints,\n mutateEndpoints: config.mutateEndpoints,\n };\n}\n"]}