@geekmidas/client 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/README.md +518 -0
  2. package/dist/chunk-CUT6urMc.cjs +30 -0
  3. package/dist/fetcher-DLDD_7Sa.mjs +86 -0
  4. package/dist/fetcher-DLDD_7Sa.mjs.map +1 -0
  5. package/dist/fetcher-KdwHgdAl.cjs +98 -0
  6. package/dist/fetcher-KdwHgdAl.cjs.map +1 -0
  7. package/dist/fetcher.cjs +4 -0
  8. package/dist/fetcher.d.cts +18 -0
  9. package/dist/fetcher.d.mts +18 -0
  10. package/dist/fetcher.mjs +3 -0
  11. package/dist/openapi-hooks.cjs +44 -0
  12. package/dist/openapi-hooks.cjs.map +1 -0
  13. package/dist/openapi-hooks.d.cts +99 -0
  14. package/dist/openapi-hooks.d.mts +99 -0
  15. package/dist/openapi-hooks.mjs +43 -0
  16. package/dist/openapi-hooks.mjs.map +1 -0
  17. package/dist/openapi-types.d.cjs +0 -0
  18. package/dist/openapi-types.d.cts +443 -0
  19. package/dist/openapi-types.d.mts +443 -0
  20. package/dist/openapi.cjs +526 -0
  21. package/dist/openapi.cjs.map +1 -0
  22. package/dist/openapi.mjs +501 -0
  23. package/dist/openapi.mjs.map +1 -0
  24. package/dist/react-query.cjs +147 -0
  25. package/dist/react-query.cjs.map +1 -0
  26. package/dist/react-query.d.cts +77 -0
  27. package/dist/react-query.d.mts +77 -0
  28. package/dist/react-query.mjs +141 -0
  29. package/dist/react-query.mjs.map +1 -0
  30. package/dist/types-csACmD6U.d.cts +68 -0
  31. package/dist/types-tMp85Lt_.d.mts +68 -0
  32. package/dist/types.cjs +0 -0
  33. package/dist/types.d.cts +2 -0
  34. package/dist/types.d.mts +2 -0
  35. package/dist/types.mjs +0 -0
  36. package/package.json +59 -0
  37. package/src/__tests__/fetcher.spec.ts +409 -0
  38. package/src/__tests__/method-restrictions.spec.tsx +227 -0
  39. package/src/__tests__/openapi-hooks.spec.tsx +558 -0
  40. package/src/__tests__/react-query-infinite.spec.tsx +1003 -0
  41. package/src/__tests__/react-query-invalidation.spec.tsx +238 -0
  42. package/src/__tests__/react-query.spec.tsx +582 -0
  43. package/src/__tests__/setup.ts +281 -0
  44. package/src/__tests__/types.spec.ts +134 -0
  45. package/src/__tests__/url-parsing.spec.ts +196 -0
  46. package/src/fetcher.ts +173 -0
  47. package/src/openapi-hooks.ts +193 -0
  48. package/src/openapi-types.d.ts +440 -0
  49. package/src/openapi.json +595 -0
  50. package/src/react-query.ts +341 -0
  51. package/src/types.ts +149 -0
@@ -0,0 +1,147 @@
1
+ const require_chunk = require('./chunk-CUT6urMc.cjs');
2
+ const require_fetcher = require('./fetcher-KdwHgdAl.cjs');
3
+ const __tanstack_react_query = require_chunk.__toESM(require("@tanstack/react-query"));
4
+ const react = require_chunk.__toESM(require("react"));
5
+
6
+ //#region src/react-query.ts
7
+ var TypedQueryClient = class {
8
+ fetcher;
9
+ queryClient;
10
+ constructor(options = {}) {
11
+ this.fetcher = require_fetcher.createTypedFetcher(options);
12
+ this.queryClient = options.queryClient;
13
+ }
14
+ useQuery(endpoint, config, options) {
15
+ const queryKey = this.buildQueryKey(endpoint, config);
16
+ const memoizedOptions = (0, react.useMemo)(() => ({
17
+ queryKey,
18
+ queryFn: () => this.fetcher(endpoint, config),
19
+ ...options
20
+ }), [
21
+ queryKey.join(","),
22
+ endpoint,
23
+ JSON.stringify(config),
24
+ JSON.stringify(options)
25
+ ]);
26
+ return (0, __tanstack_react_query.useQuery)(memoizedOptions);
27
+ }
28
+ useMutation(endpoint, options) {
29
+ const memoizedOptions = (0, react.useMemo)(() => ({
30
+ mutationFn: (config) => this.fetcher(endpoint, config),
31
+ ...options
32
+ }), [endpoint, JSON.stringify(options)]);
33
+ return (0, __tanstack_react_query.useMutation)(memoizedOptions);
34
+ }
35
+ useInfiniteQuery(endpoint, options, config) {
36
+ const queryKey = this.buildQueryKey(endpoint, config);
37
+ const memoizedOptions = (0, react.useMemo)(() => ({
38
+ queryKey,
39
+ queryFn: ({ pageParam }) => {
40
+ let mergedConfig = config;
41
+ if (pageParam !== void 0 && config) {
42
+ const pageQuery = typeof pageParam === "object" ? pageParam : { page: pageParam };
43
+ mergedConfig = {
44
+ ...config,
45
+ query: {
46
+ ...config.query,
47
+ ...pageQuery
48
+ }
49
+ };
50
+ } else if (pageParam !== void 0 && !config) {
51
+ const pageQuery = typeof pageParam === "object" ? pageParam : { page: pageParam };
52
+ mergedConfig = { query: pageQuery };
53
+ }
54
+ return this.fetcher(endpoint, mergedConfig);
55
+ },
56
+ ...options
57
+ }), [
58
+ queryKey.join(","),
59
+ endpoint,
60
+ JSON.stringify(config),
61
+ JSON.stringify(options)
62
+ ]);
63
+ return (0, __tanstack_react_query.useInfiniteQuery)(memoizedOptions);
64
+ }
65
+ buildQueryKey(endpoint, config) {
66
+ const key = [endpoint];
67
+ if (config && "params" in config && config.params) key.push({ params: config.params });
68
+ if (config && "query" in config && config.query) key.push({ query: config.query });
69
+ return key;
70
+ }
71
+ /**
72
+ * Invalidate queries for a specific endpoint with optional config
73
+ * @param endpoint - The endpoint to invalidate (e.g., 'GET /users')
74
+ * @param config - Optional params/query to match specific queries
75
+ * @returns Promise that resolves when invalidation is complete
76
+ */
77
+ invalidateQueries(endpoint, config) {
78
+ const queryClient = this.getQueryClient();
79
+ const queryKey = this.buildQueryKey(endpoint, config);
80
+ return queryClient.invalidateQueries({
81
+ queryKey,
82
+ exact: !!config
83
+ });
84
+ }
85
+ /**
86
+ * Invalidate all queries in the cache
87
+ * @returns Promise that resolves when invalidation is complete
88
+ */
89
+ invalidateAllQueries() {
90
+ const queryClient = this.getQueryClient();
91
+ return queryClient.invalidateQueries();
92
+ }
93
+ /**
94
+ * Get the underlying QueryClient instance
95
+ * @returns The QueryClient instance
96
+ */
97
+ getQueryClient() {
98
+ if (this.queryClient) return this.queryClient;
99
+ throw new Error("No QueryClient set, please provide a QueryClient via the queryClient option or ensure you are within a QueryClientProvider");
100
+ }
101
+ /**
102
+ * Set the QueryClient instance
103
+ * @param queryClient - The QueryClient instance to use
104
+ */
105
+ setQueryClient(queryClient) {
106
+ this.queryClient = queryClient;
107
+ }
108
+ };
109
+ function createTypedQueryClient(options) {
110
+ return new TypedQueryClient(options);
111
+ }
112
+ function useTypedQuery(client, endpoint, config, options) {
113
+ return client.useQuery(endpoint, config, options);
114
+ }
115
+ function useTypedMutation(client, endpoint, options) {
116
+ return client.useMutation(endpoint, options);
117
+ }
118
+ function useTypedInfiniteQuery(client, endpoint, options, config) {
119
+ return client.useInfiniteQuery(endpoint, options, config);
120
+ }
121
+ /**
122
+ * Hook to invalidate queries using the current QueryClient from context
123
+ */
124
+ function useTypedInvalidateQueries(client) {
125
+ const queryClient = (0, __tanstack_react_query.useQueryClient)();
126
+ return {
127
+ invalidateQueries: (endpoint, config) => {
128
+ const queryKey = client.buildQueryKey(endpoint, config);
129
+ return queryClient.invalidateQueries({
130
+ queryKey,
131
+ exact: !!config
132
+ });
133
+ },
134
+ invalidateAllQueries: () => {
135
+ return queryClient.invalidateQueries();
136
+ }
137
+ };
138
+ }
139
+
140
+ //#endregion
141
+ exports.TypedQueryClient = TypedQueryClient;
142
+ exports.createTypedQueryClient = createTypedQueryClient;
143
+ exports.useTypedInfiniteQuery = useTypedInfiniteQuery;
144
+ exports.useTypedInvalidateQueries = useTypedInvalidateQueries;
145
+ exports.useTypedMutation = useTypedMutation;
146
+ exports.useTypedQuery = useTypedQuery;
147
+ //# sourceMappingURL=react-query.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"react-query.cjs","names":["options: TypedQueryClientOptions","endpoint: T","config?: FilteredRequestConfig<Paths, T>","options?: Omit<\n UseQueryOptions<ExtractEndpointResponse<Paths, T>, Response>,\n 'queryKey' | 'queryFn'\n >","options?: Omit<\n UseMutationOptions<\n ExtractEndpointResponse<Paths, T>,\n Response,\n FilteredRequestConfig<Paths, T>\n >,\n 'mutationFn'\n >","config: FilteredRequestConfig<Paths, T>","options: Omit<\n UseInfiniteQueryOptions<\n TPageData,\n Response,\n { pages: TPageData[]; pageParams: TPageParam[] },\n unknown[],\n TPageParam\n >,\n 'queryKey' | 'queryFn' | 'getNextPageParam' | 'initialPageParam'\n > & {\n getNextPageParam: (\n lastPage: TPageData,\n allPages: TPageData[],\n lastPageParam: TPageParam,\n allPageParams: TPageParam[],\n ) => TPageParam | undefined;\n initialPageParam: TPageParam;\n }","key: unknown[]","queryClient: QueryClient","options?: TypedQueryClientOptions","client: TypedQueryClient<Paths>","options?: Omit<\n UseQueryOptions<ExtractEndpointResponse<Paths, T>, Response>,\n 'queryKey' | 'queryFn'\n >","options?: Omit<\n UseMutationOptions<\n ExtractEndpointResponse<Paths, T>,\n Response,\n FilteredRequestConfig<Paths, T>\n >,\n 'mutationFn'\n >","options: Omit<\n UseInfiniteQueryOptions<\n TPageData,\n Response,\n { pages: TPageData[]; pageParams: TPageParam[] },\n unknown[],\n TPageParam\n >,\n 'queryKey' | 'queryFn' | 'getNextPageParam' | 'initialPageParam'\n > & {\n getNextPageParam: (\n lastPage: TPageData,\n allPages: TPageData[],\n lastPageParam: TPageParam,\n allPageParams: TPageParam[],\n ) => TPageParam | undefined;\n initialPageParam: TPageParam;\n }"],"sources":["../src/react-query.ts"],"sourcesContent":["import type {\n QueryClient,\n QueryFunctionContext,\n UseInfiniteQueryOptions,\n UseMutationOptions,\n UseQueryOptions,\n} from '@tanstack/react-query';\nimport {\n useInfiniteQuery,\n useMutation,\n useQuery,\n useQueryClient,\n} from '@tanstack/react-query';\nimport { useMemo } from 'react';\nimport { createTypedFetcher } from './fetcher';\nimport type {\n ExtractEndpointResponse,\n FetcherOptions,\n FilteredRequestConfig,\n MutationEndpoint,\n QueryEndpoint,\n TypedEndpoint,\n} from './types';\n\nexport interface TypedQueryClientOptions extends FetcherOptions {\n queryClient?: QueryClient;\n}\n\nexport class TypedQueryClient<Paths> {\n private fetcher: ReturnType<typeof createTypedFetcher<Paths>>;\n private queryClient?: QueryClient;\n\n constructor(options: TypedQueryClientOptions = {}) {\n this.fetcher = createTypedFetcher<Paths>(options);\n this.queryClient = options.queryClient;\n }\n\n useQuery<T extends QueryEndpoint<Paths>>(\n endpoint: T,\n config?: FilteredRequestConfig<Paths, T>,\n options?: Omit<\n UseQueryOptions<ExtractEndpointResponse<Paths, T>, Response>,\n 'queryKey' | 'queryFn'\n >,\n ) {\n const queryKey = this.buildQueryKey(endpoint, config);\n\n // Memoize the combined options to prevent unnecessary re-renders\n const memoizedOptions = useMemo(\n () => ({\n queryKey,\n queryFn: () => this.fetcher(endpoint, config),\n ...options,\n }),\n // Dependencies: queryKey, endpoint, config, and options\n // Note: We stringify config and options to ensure stable references\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [\n queryKey.join(','),\n endpoint,\n JSON.stringify(config),\n JSON.stringify(options),\n ],\n );\n\n return useQuery<ExtractEndpointResponse<Paths, T>, Response>(\n memoizedOptions,\n );\n }\n\n useMutation<T extends MutationEndpoint<Paths>>(\n endpoint: T,\n options?: Omit<\n UseMutationOptions<\n ExtractEndpointResponse<Paths, T>,\n Response,\n FilteredRequestConfig<Paths, T>\n >,\n 'mutationFn'\n >,\n ) {\n // Memoize the combined options to prevent unnecessary re-renders\n const memoizedOptions = useMemo(\n () => ({\n mutationFn: (config: FilteredRequestConfig<Paths, T>) =>\n this.fetcher(endpoint, config),\n ...options,\n }),\n // Dependencies: endpoint and options\n // Note: We stringify options to ensure stable reference\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [endpoint, JSON.stringify(options)],\n );\n\n return useMutation<\n ExtractEndpointResponse<Paths, T>,\n Response,\n FilteredRequestConfig<Paths, T>\n >(memoizedOptions);\n }\n\n useInfiniteQuery<\n T extends QueryEndpoint<Paths>,\n TPageData = ExtractEndpointResponse<Paths, T>,\n TPageParam = unknown,\n >(\n endpoint: T,\n options: Omit<\n UseInfiniteQueryOptions<\n TPageData,\n Response,\n { pages: TPageData[]; pageParams: TPageParam[] },\n unknown[],\n TPageParam\n >,\n 'queryKey' | 'queryFn' | 'getNextPageParam' | 'initialPageParam'\n > & {\n getNextPageParam: (\n lastPage: TPageData,\n allPages: TPageData[],\n lastPageParam: TPageParam,\n allPageParams: TPageParam[],\n ) => TPageParam | undefined;\n initialPageParam: TPageParam;\n },\n config?: FilteredRequestConfig<Paths, T>,\n ) {\n const queryKey = this.buildQueryKey(endpoint, config);\n\n // Memoize the combined options to prevent unnecessary re-renders\n const memoizedOptions = useMemo(\n () => ({\n queryKey,\n queryFn: ({\n pageParam,\n }: QueryFunctionContext<unknown[], TPageParam>) => {\n let mergedConfig = config;\n if (pageParam !== undefined && config) {\n // If pageParam is an object, spread it into query\n const pageQuery =\n typeof pageParam === 'object' ? pageParam : { page: pageParam };\n mergedConfig = {\n ...config,\n query: { ...(config as any).query, ...pageQuery },\n } as any;\n } else if (pageParam !== undefined && !config) {\n // If pageParam is an object, use it directly, otherwise wrap in page property\n const pageQuery =\n typeof pageParam === 'object' ? pageParam : { page: pageParam };\n mergedConfig = { query: pageQuery } as any;\n }\n return this.fetcher(endpoint, mergedConfig) as Promise<TPageData>;\n },\n ...options,\n }),\n // Dependencies: queryKey, endpoint, config, and options\n // Note: We stringify config and options to ensure stable references\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [\n queryKey.join(','),\n endpoint,\n JSON.stringify(config),\n JSON.stringify(options),\n ],\n );\n\n return useInfiniteQuery<\n TPageData,\n Response,\n { pages: TPageData[]; pageParams: TPageParam[] },\n unknown[],\n TPageParam\n >(memoizedOptions);\n }\n\n buildQueryKey<T extends TypedEndpoint<Paths>>(\n endpoint: T,\n config?: FilteredRequestConfig<Paths, T>,\n ): unknown[] {\n const key: unknown[] = [endpoint];\n\n if (config && 'params' in config && config.params) {\n key.push({ params: config.params });\n }\n\n if (config && 'query' in config && config.query) {\n key.push({ query: config.query });\n }\n\n return key;\n }\n\n /**\n * Invalidate queries for a specific endpoint with optional config\n * @param endpoint - The endpoint to invalidate (e.g., 'GET /users')\n * @param config - Optional params/query to match specific queries\n * @returns Promise that resolves when invalidation is complete\n */\n invalidateQueries<T extends QueryEndpoint<Paths>>(\n endpoint: T,\n config?: FilteredRequestConfig<Paths, T>,\n ): Promise<void> {\n const queryClient = this.getQueryClient();\n const queryKey = this.buildQueryKey(endpoint, config);\n\n return queryClient.invalidateQueries({\n queryKey,\n exact: !!config, // Use exact matching if config is provided\n });\n }\n\n /**\n * Invalidate all queries in the cache\n * @returns Promise that resolves when invalidation is complete\n */\n invalidateAllQueries(): Promise<void> {\n const queryClient = this.getQueryClient();\n return queryClient.invalidateQueries();\n }\n\n /**\n * Get the underlying QueryClient instance\n * @returns The QueryClient instance\n */\n getQueryClient(): QueryClient {\n if (this.queryClient) {\n return this.queryClient;\n }\n\n // If no query client was provided, try to get it from context\n // This will throw if used outside of QueryClientProvider\n throw new Error(\n 'No QueryClient set, please provide a QueryClient via the queryClient option or ensure you are within a QueryClientProvider',\n );\n }\n\n /**\n * Set the QueryClient instance\n * @param queryClient - The QueryClient instance to use\n */\n setQueryClient(queryClient: QueryClient): void {\n this.queryClient = queryClient;\n }\n}\n\nexport function createTypedQueryClient<Paths>(\n options?: TypedQueryClientOptions,\n) {\n return new TypedQueryClient<Paths>(options);\n}\n\n// Hook exports for convenience\nexport function useTypedQuery<Paths, T extends QueryEndpoint<Paths>>(\n client: TypedQueryClient<Paths>,\n endpoint: T,\n config?: FilteredRequestConfig<Paths, T>,\n options?: Omit<\n UseQueryOptions<ExtractEndpointResponse<Paths, T>, Response>,\n 'queryKey' | 'queryFn'\n >,\n) {\n return client.useQuery(endpoint, config, options);\n}\n\nexport function useTypedMutation<Paths, T extends MutationEndpoint<Paths>>(\n client: TypedQueryClient<Paths>,\n endpoint: T,\n options?: Omit<\n UseMutationOptions<\n ExtractEndpointResponse<Paths, T>,\n Response,\n FilteredRequestConfig<Paths, T>\n >,\n 'mutationFn'\n >,\n) {\n return client.useMutation(endpoint, options);\n}\n\nexport function useTypedInfiniteQuery<\n Paths,\n T extends QueryEndpoint<Paths>,\n TPageData = ExtractEndpointResponse<Paths, T>,\n TPageParam = unknown,\n>(\n client: TypedQueryClient<Paths>,\n endpoint: T,\n options: Omit<\n UseInfiniteQueryOptions<\n TPageData,\n Response,\n { pages: TPageData[]; pageParams: TPageParam[] },\n unknown[],\n TPageParam\n >,\n 'queryKey' | 'queryFn' | 'getNextPageParam' | 'initialPageParam'\n > & {\n getNextPageParam: (\n lastPage: TPageData,\n allPages: TPageData[],\n lastPageParam: TPageParam,\n allPageParams: TPageParam[],\n ) => TPageParam | undefined;\n initialPageParam: TPageParam;\n },\n config?: FilteredRequestConfig<Paths, T>,\n) {\n return client.useInfiniteQuery(endpoint, options, config);\n}\n\n/**\n * Hook to invalidate queries using the current QueryClient from context\n */\nexport function useTypedInvalidateQueries<Paths>(\n client: TypedQueryClient<Paths>,\n) {\n const queryClient = useQueryClient();\n\n return {\n /**\n * Invalidate queries for a specific endpoint\n */\n invalidateQueries: <T extends QueryEndpoint<Paths>>(\n endpoint: T,\n config?: FilteredRequestConfig<Paths, T>,\n ) => {\n const queryKey = client.buildQueryKey(endpoint, config);\n return queryClient.invalidateQueries({\n queryKey,\n exact: !!config,\n });\n },\n\n /**\n * Invalidate all queries\n */\n invalidateAllQueries: () => {\n return queryClient.invalidateQueries();\n },\n };\n}\n"],"mappings":"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"}
@@ -0,0 +1,77 @@
1
+ import { ExtractEndpointResponse, FetcherOptions, FilteredRequestConfig, MutationEndpoint, QueryEndpoint, TypedEndpoint } from "./types-csACmD6U.cjs";
2
+ import * as _tanstack_react_query0 from "@tanstack/react-query";
3
+ import { QueryClient, UseInfiniteQueryOptions, UseMutationOptions, UseQueryOptions } from "@tanstack/react-query";
4
+
5
+ //#region src/react-query.d.ts
6
+ interface TypedQueryClientOptions extends FetcherOptions {
7
+ queryClient?: QueryClient;
8
+ }
9
+ declare class TypedQueryClient<Paths> {
10
+ private fetcher;
11
+ private queryClient?;
12
+ constructor(options?: TypedQueryClientOptions);
13
+ useQuery<T extends QueryEndpoint<Paths>>(endpoint: T, config?: FilteredRequestConfig<Paths, T>, options?: Omit<UseQueryOptions<ExtractEndpointResponse<Paths, T>, Response>, 'queryKey' | 'queryFn'>): _tanstack_react_query0.UseQueryResult<_tanstack_react_query0.NoInfer<ExtractEndpointResponse<Paths, T>>, Response>;
14
+ useMutation<T extends MutationEndpoint<Paths>>(endpoint: T, options?: Omit<UseMutationOptions<ExtractEndpointResponse<Paths, T>, Response, FilteredRequestConfig<Paths, T>>, 'mutationFn'>): _tanstack_react_query0.UseMutationResult<ExtractEndpointResponse<Paths, T>, Response, FilteredRequestConfig<Paths, T>, unknown>;
15
+ useInfiniteQuery<T extends QueryEndpoint<Paths>, TPageData = ExtractEndpointResponse<Paths, T>, TPageParam = unknown>(endpoint: T, options: Omit<UseInfiniteQueryOptions<TPageData, Response, {
16
+ pages: TPageData[];
17
+ pageParams: TPageParam[];
18
+ }, unknown[], TPageParam>, 'queryKey' | 'queryFn' | 'getNextPageParam' | 'initialPageParam'> & {
19
+ getNextPageParam: (lastPage: TPageData, allPages: TPageData[], lastPageParam: TPageParam, allPageParams: TPageParam[]) => TPageParam | undefined;
20
+ initialPageParam: TPageParam;
21
+ }, config?: FilteredRequestConfig<Paths, T>): _tanstack_react_query0.UseInfiniteQueryResult<{
22
+ pages: TPageData[];
23
+ pageParams: TPageParam[];
24
+ }, Response>;
25
+ buildQueryKey<T extends TypedEndpoint<Paths>>(endpoint: T, config?: FilteredRequestConfig<Paths, T>): unknown[];
26
+ /**
27
+ * Invalidate queries for a specific endpoint with optional config
28
+ * @param endpoint - The endpoint to invalidate (e.g., 'GET /users')
29
+ * @param config - Optional params/query to match specific queries
30
+ * @returns Promise that resolves when invalidation is complete
31
+ */
32
+ invalidateQueries<T extends QueryEndpoint<Paths>>(endpoint: T, config?: FilteredRequestConfig<Paths, T>): Promise<void>;
33
+ /**
34
+ * Invalidate all queries in the cache
35
+ * @returns Promise that resolves when invalidation is complete
36
+ */
37
+ invalidateAllQueries(): Promise<void>;
38
+ /**
39
+ * Get the underlying QueryClient instance
40
+ * @returns The QueryClient instance
41
+ */
42
+ getQueryClient(): QueryClient;
43
+ /**
44
+ * Set the QueryClient instance
45
+ * @param queryClient - The QueryClient instance to use
46
+ */
47
+ setQueryClient(queryClient: QueryClient): void;
48
+ }
49
+ declare function createTypedQueryClient<Paths>(options?: TypedQueryClientOptions): TypedQueryClient<Paths>;
50
+ declare function useTypedQuery<Paths, T extends QueryEndpoint<Paths>>(client: TypedQueryClient<Paths>, endpoint: T, config?: FilteredRequestConfig<Paths, T>, options?: Omit<UseQueryOptions<ExtractEndpointResponse<Paths, T>, Response>, 'queryKey' | 'queryFn'>): _tanstack_react_query0.UseQueryResult<_tanstack_react_query0.NoInfer<ExtractEndpointResponse<Paths, T>>, Response>;
51
+ declare function useTypedMutation<Paths, T extends MutationEndpoint<Paths>>(client: TypedQueryClient<Paths>, endpoint: T, options?: Omit<UseMutationOptions<ExtractEndpointResponse<Paths, T>, Response, FilteredRequestConfig<Paths, T>>, 'mutationFn'>): _tanstack_react_query0.UseMutationResult<ExtractEndpointResponse<Paths, T>, Response, FilteredRequestConfig<Paths, T>, unknown>;
52
+ declare function useTypedInfiniteQuery<Paths, T extends QueryEndpoint<Paths>, TPageData = ExtractEndpointResponse<Paths, T>, TPageParam = unknown>(client: TypedQueryClient<Paths>, endpoint: T, options: Omit<UseInfiniteQueryOptions<TPageData, Response, {
53
+ pages: TPageData[];
54
+ pageParams: TPageParam[];
55
+ }, unknown[], TPageParam>, 'queryKey' | 'queryFn' | 'getNextPageParam' | 'initialPageParam'> & {
56
+ getNextPageParam: (lastPage: TPageData, allPages: TPageData[], lastPageParam: TPageParam, allPageParams: TPageParam[]) => TPageParam | undefined;
57
+ initialPageParam: TPageParam;
58
+ }, config?: FilteredRequestConfig<Paths, T>): _tanstack_react_query0.UseInfiniteQueryResult<{
59
+ pages: TPageData[];
60
+ pageParams: TPageParam[];
61
+ }, Response>;
62
+ /**
63
+ * Hook to invalidate queries using the current QueryClient from context
64
+ */
65
+ declare function useTypedInvalidateQueries<Paths>(client: TypedQueryClient<Paths>): {
66
+ /**
67
+ * Invalidate queries for a specific endpoint
68
+ */
69
+ invalidateQueries: <T extends QueryEndpoint<Paths>>(endpoint: T, config?: FilteredRequestConfig<Paths, T>) => Promise<void>;
70
+ /**
71
+ * Invalidate all queries
72
+ */
73
+ invalidateAllQueries: () => Promise<void>;
74
+ };
75
+ //#endregion
76
+ export { TypedQueryClient, TypedQueryClientOptions, createTypedQueryClient, useTypedInfiniteQuery, useTypedInvalidateQueries, useTypedMutation, useTypedQuery };
77
+ //# sourceMappingURL=react-query.d.cts.map
@@ -0,0 +1,77 @@
1
+ import { ExtractEndpointResponse, FetcherOptions, FilteredRequestConfig, MutationEndpoint, QueryEndpoint, TypedEndpoint } from "./types-tMp85Lt_.mjs";
2
+ import * as _tanstack_react_query3 from "@tanstack/react-query";
3
+ import { QueryClient, UseInfiniteQueryOptions, UseMutationOptions, UseQueryOptions } from "@tanstack/react-query";
4
+
5
+ //#region src/react-query.d.ts
6
+ interface TypedQueryClientOptions extends FetcherOptions {
7
+ queryClient?: QueryClient;
8
+ }
9
+ declare class TypedQueryClient<Paths> {
10
+ private fetcher;
11
+ private queryClient?;
12
+ constructor(options?: TypedQueryClientOptions);
13
+ useQuery<T extends QueryEndpoint<Paths>>(endpoint: T, config?: FilteredRequestConfig<Paths, T>, options?: Omit<UseQueryOptions<ExtractEndpointResponse<Paths, T>, Response>, 'queryKey' | 'queryFn'>): _tanstack_react_query3.UseQueryResult<_tanstack_react_query3.NoInfer<ExtractEndpointResponse<Paths, T>>, Response>;
14
+ useMutation<T extends MutationEndpoint<Paths>>(endpoint: T, options?: Omit<UseMutationOptions<ExtractEndpointResponse<Paths, T>, Response, FilteredRequestConfig<Paths, T>>, 'mutationFn'>): _tanstack_react_query3.UseMutationResult<ExtractEndpointResponse<Paths, T>, Response, FilteredRequestConfig<Paths, T>, unknown>;
15
+ useInfiniteQuery<T extends QueryEndpoint<Paths>, TPageData = ExtractEndpointResponse<Paths, T>, TPageParam = unknown>(endpoint: T, options: Omit<UseInfiniteQueryOptions<TPageData, Response, {
16
+ pages: TPageData[];
17
+ pageParams: TPageParam[];
18
+ }, unknown[], TPageParam>, 'queryKey' | 'queryFn' | 'getNextPageParam' | 'initialPageParam'> & {
19
+ getNextPageParam: (lastPage: TPageData, allPages: TPageData[], lastPageParam: TPageParam, allPageParams: TPageParam[]) => TPageParam | undefined;
20
+ initialPageParam: TPageParam;
21
+ }, config?: FilteredRequestConfig<Paths, T>): _tanstack_react_query3.UseInfiniteQueryResult<{
22
+ pages: TPageData[];
23
+ pageParams: TPageParam[];
24
+ }, Response>;
25
+ buildQueryKey<T extends TypedEndpoint<Paths>>(endpoint: T, config?: FilteredRequestConfig<Paths, T>): unknown[];
26
+ /**
27
+ * Invalidate queries for a specific endpoint with optional config
28
+ * @param endpoint - The endpoint to invalidate (e.g., 'GET /users')
29
+ * @param config - Optional params/query to match specific queries
30
+ * @returns Promise that resolves when invalidation is complete
31
+ */
32
+ invalidateQueries<T extends QueryEndpoint<Paths>>(endpoint: T, config?: FilteredRequestConfig<Paths, T>): Promise<void>;
33
+ /**
34
+ * Invalidate all queries in the cache
35
+ * @returns Promise that resolves when invalidation is complete
36
+ */
37
+ invalidateAllQueries(): Promise<void>;
38
+ /**
39
+ * Get the underlying QueryClient instance
40
+ * @returns The QueryClient instance
41
+ */
42
+ getQueryClient(): QueryClient;
43
+ /**
44
+ * Set the QueryClient instance
45
+ * @param queryClient - The QueryClient instance to use
46
+ */
47
+ setQueryClient(queryClient: QueryClient): void;
48
+ }
49
+ declare function createTypedQueryClient<Paths>(options?: TypedQueryClientOptions): TypedQueryClient<Paths>;
50
+ declare function useTypedQuery<Paths, T extends QueryEndpoint<Paths>>(client: TypedQueryClient<Paths>, endpoint: T, config?: FilteredRequestConfig<Paths, T>, options?: Omit<UseQueryOptions<ExtractEndpointResponse<Paths, T>, Response>, 'queryKey' | 'queryFn'>): _tanstack_react_query3.UseQueryResult<_tanstack_react_query3.NoInfer<ExtractEndpointResponse<Paths, T>>, Response>;
51
+ declare function useTypedMutation<Paths, T extends MutationEndpoint<Paths>>(client: TypedQueryClient<Paths>, endpoint: T, options?: Omit<UseMutationOptions<ExtractEndpointResponse<Paths, T>, Response, FilteredRequestConfig<Paths, T>>, 'mutationFn'>): _tanstack_react_query3.UseMutationResult<ExtractEndpointResponse<Paths, T>, Response, FilteredRequestConfig<Paths, T>, unknown>;
52
+ declare function useTypedInfiniteQuery<Paths, T extends QueryEndpoint<Paths>, TPageData = ExtractEndpointResponse<Paths, T>, TPageParam = unknown>(client: TypedQueryClient<Paths>, endpoint: T, options: Omit<UseInfiniteQueryOptions<TPageData, Response, {
53
+ pages: TPageData[];
54
+ pageParams: TPageParam[];
55
+ }, unknown[], TPageParam>, 'queryKey' | 'queryFn' | 'getNextPageParam' | 'initialPageParam'> & {
56
+ getNextPageParam: (lastPage: TPageData, allPages: TPageData[], lastPageParam: TPageParam, allPageParams: TPageParam[]) => TPageParam | undefined;
57
+ initialPageParam: TPageParam;
58
+ }, config?: FilteredRequestConfig<Paths, T>): _tanstack_react_query3.UseInfiniteQueryResult<{
59
+ pages: TPageData[];
60
+ pageParams: TPageParam[];
61
+ }, Response>;
62
+ /**
63
+ * Hook to invalidate queries using the current QueryClient from context
64
+ */
65
+ declare function useTypedInvalidateQueries<Paths>(client: TypedQueryClient<Paths>): {
66
+ /**
67
+ * Invalidate queries for a specific endpoint
68
+ */
69
+ invalidateQueries: <T extends QueryEndpoint<Paths>>(endpoint: T, config?: FilteredRequestConfig<Paths, T>) => Promise<void>;
70
+ /**
71
+ * Invalidate all queries
72
+ */
73
+ invalidateAllQueries: () => Promise<void>;
74
+ };
75
+ //#endregion
76
+ export { TypedQueryClient, TypedQueryClientOptions, createTypedQueryClient, useTypedInfiniteQuery, useTypedInvalidateQueries, useTypedMutation, useTypedQuery };
77
+ //# sourceMappingURL=react-query.d.mts.map
@@ -0,0 +1,141 @@
1
+ import { createTypedFetcher } from "./fetcher-DLDD_7Sa.mjs";
2
+ import { useInfiniteQuery, useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
3
+ import { useMemo } from "react";
4
+
5
+ //#region src/react-query.ts
6
+ var TypedQueryClient = class {
7
+ fetcher;
8
+ queryClient;
9
+ constructor(options = {}) {
10
+ this.fetcher = createTypedFetcher(options);
11
+ this.queryClient = options.queryClient;
12
+ }
13
+ useQuery(endpoint, config, options) {
14
+ const queryKey = this.buildQueryKey(endpoint, config);
15
+ const memoizedOptions = useMemo(() => ({
16
+ queryKey,
17
+ queryFn: () => this.fetcher(endpoint, config),
18
+ ...options
19
+ }), [
20
+ queryKey.join(","),
21
+ endpoint,
22
+ JSON.stringify(config),
23
+ JSON.stringify(options)
24
+ ]);
25
+ return useQuery(memoizedOptions);
26
+ }
27
+ useMutation(endpoint, options) {
28
+ const memoizedOptions = useMemo(() => ({
29
+ mutationFn: (config) => this.fetcher(endpoint, config),
30
+ ...options
31
+ }), [endpoint, JSON.stringify(options)]);
32
+ return useMutation(memoizedOptions);
33
+ }
34
+ useInfiniteQuery(endpoint, options, config) {
35
+ const queryKey = this.buildQueryKey(endpoint, config);
36
+ const memoizedOptions = useMemo(() => ({
37
+ queryKey,
38
+ queryFn: ({ pageParam }) => {
39
+ let mergedConfig = config;
40
+ if (pageParam !== void 0 && config) {
41
+ const pageQuery = typeof pageParam === "object" ? pageParam : { page: pageParam };
42
+ mergedConfig = {
43
+ ...config,
44
+ query: {
45
+ ...config.query,
46
+ ...pageQuery
47
+ }
48
+ };
49
+ } else if (pageParam !== void 0 && !config) {
50
+ const pageQuery = typeof pageParam === "object" ? pageParam : { page: pageParam };
51
+ mergedConfig = { query: pageQuery };
52
+ }
53
+ return this.fetcher(endpoint, mergedConfig);
54
+ },
55
+ ...options
56
+ }), [
57
+ queryKey.join(","),
58
+ endpoint,
59
+ JSON.stringify(config),
60
+ JSON.stringify(options)
61
+ ]);
62
+ return useInfiniteQuery(memoizedOptions);
63
+ }
64
+ buildQueryKey(endpoint, config) {
65
+ const key = [endpoint];
66
+ if (config && "params" in config && config.params) key.push({ params: config.params });
67
+ if (config && "query" in config && config.query) key.push({ query: config.query });
68
+ return key;
69
+ }
70
+ /**
71
+ * Invalidate queries for a specific endpoint with optional config
72
+ * @param endpoint - The endpoint to invalidate (e.g., 'GET /users')
73
+ * @param config - Optional params/query to match specific queries
74
+ * @returns Promise that resolves when invalidation is complete
75
+ */
76
+ invalidateQueries(endpoint, config) {
77
+ const queryClient = this.getQueryClient();
78
+ const queryKey = this.buildQueryKey(endpoint, config);
79
+ return queryClient.invalidateQueries({
80
+ queryKey,
81
+ exact: !!config
82
+ });
83
+ }
84
+ /**
85
+ * Invalidate all queries in the cache
86
+ * @returns Promise that resolves when invalidation is complete
87
+ */
88
+ invalidateAllQueries() {
89
+ const queryClient = this.getQueryClient();
90
+ return queryClient.invalidateQueries();
91
+ }
92
+ /**
93
+ * Get the underlying QueryClient instance
94
+ * @returns The QueryClient instance
95
+ */
96
+ getQueryClient() {
97
+ if (this.queryClient) return this.queryClient;
98
+ throw new Error("No QueryClient set, please provide a QueryClient via the queryClient option or ensure you are within a QueryClientProvider");
99
+ }
100
+ /**
101
+ * Set the QueryClient instance
102
+ * @param queryClient - The QueryClient instance to use
103
+ */
104
+ setQueryClient(queryClient) {
105
+ this.queryClient = queryClient;
106
+ }
107
+ };
108
+ function createTypedQueryClient(options) {
109
+ return new TypedQueryClient(options);
110
+ }
111
+ function useTypedQuery(client, endpoint, config, options) {
112
+ return client.useQuery(endpoint, config, options);
113
+ }
114
+ function useTypedMutation(client, endpoint, options) {
115
+ return client.useMutation(endpoint, options);
116
+ }
117
+ function useTypedInfiniteQuery(client, endpoint, options, config) {
118
+ return client.useInfiniteQuery(endpoint, options, config);
119
+ }
120
+ /**
121
+ * Hook to invalidate queries using the current QueryClient from context
122
+ */
123
+ function useTypedInvalidateQueries(client) {
124
+ const queryClient = useQueryClient();
125
+ return {
126
+ invalidateQueries: (endpoint, config) => {
127
+ const queryKey = client.buildQueryKey(endpoint, config);
128
+ return queryClient.invalidateQueries({
129
+ queryKey,
130
+ exact: !!config
131
+ });
132
+ },
133
+ invalidateAllQueries: () => {
134
+ return queryClient.invalidateQueries();
135
+ }
136
+ };
137
+ }
138
+
139
+ //#endregion
140
+ export { TypedQueryClient, createTypedQueryClient, useTypedInfiniteQuery, useTypedInvalidateQueries, useTypedMutation, useTypedQuery };
141
+ //# sourceMappingURL=react-query.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"react-query.mjs","names":["options: TypedQueryClientOptions","endpoint: T","config?: FilteredRequestConfig<Paths, T>","options?: Omit<\n UseQueryOptions<ExtractEndpointResponse<Paths, T>, Response>,\n 'queryKey' | 'queryFn'\n >","options?: Omit<\n UseMutationOptions<\n ExtractEndpointResponse<Paths, T>,\n Response,\n FilteredRequestConfig<Paths, T>\n >,\n 'mutationFn'\n >","config: FilteredRequestConfig<Paths, T>","options: Omit<\n UseInfiniteQueryOptions<\n TPageData,\n Response,\n { pages: TPageData[]; pageParams: TPageParam[] },\n unknown[],\n TPageParam\n >,\n 'queryKey' | 'queryFn' | 'getNextPageParam' | 'initialPageParam'\n > & {\n getNextPageParam: (\n lastPage: TPageData,\n allPages: TPageData[],\n lastPageParam: TPageParam,\n allPageParams: TPageParam[],\n ) => TPageParam | undefined;\n initialPageParam: TPageParam;\n }","key: unknown[]","queryClient: QueryClient","options?: TypedQueryClientOptions","client: TypedQueryClient<Paths>","options?: Omit<\n UseQueryOptions<ExtractEndpointResponse<Paths, T>, Response>,\n 'queryKey' | 'queryFn'\n >","options?: Omit<\n UseMutationOptions<\n ExtractEndpointResponse<Paths, T>,\n Response,\n FilteredRequestConfig<Paths, T>\n >,\n 'mutationFn'\n >","options: Omit<\n UseInfiniteQueryOptions<\n TPageData,\n Response,\n { pages: TPageData[]; pageParams: TPageParam[] },\n unknown[],\n TPageParam\n >,\n 'queryKey' | 'queryFn' | 'getNextPageParam' | 'initialPageParam'\n > & {\n getNextPageParam: (\n lastPage: TPageData,\n allPages: TPageData[],\n lastPageParam: TPageParam,\n allPageParams: TPageParam[],\n ) => TPageParam | undefined;\n initialPageParam: TPageParam;\n }"],"sources":["../src/react-query.ts"],"sourcesContent":["import type {\n QueryClient,\n QueryFunctionContext,\n UseInfiniteQueryOptions,\n UseMutationOptions,\n UseQueryOptions,\n} from '@tanstack/react-query';\nimport {\n useInfiniteQuery,\n useMutation,\n useQuery,\n useQueryClient,\n} from '@tanstack/react-query';\nimport { useMemo } from 'react';\nimport { createTypedFetcher } from './fetcher';\nimport type {\n ExtractEndpointResponse,\n FetcherOptions,\n FilteredRequestConfig,\n MutationEndpoint,\n QueryEndpoint,\n TypedEndpoint,\n} from './types';\n\nexport interface TypedQueryClientOptions extends FetcherOptions {\n queryClient?: QueryClient;\n}\n\nexport class TypedQueryClient<Paths> {\n private fetcher: ReturnType<typeof createTypedFetcher<Paths>>;\n private queryClient?: QueryClient;\n\n constructor(options: TypedQueryClientOptions = {}) {\n this.fetcher = createTypedFetcher<Paths>(options);\n this.queryClient = options.queryClient;\n }\n\n useQuery<T extends QueryEndpoint<Paths>>(\n endpoint: T,\n config?: FilteredRequestConfig<Paths, T>,\n options?: Omit<\n UseQueryOptions<ExtractEndpointResponse<Paths, T>, Response>,\n 'queryKey' | 'queryFn'\n >,\n ) {\n const queryKey = this.buildQueryKey(endpoint, config);\n\n // Memoize the combined options to prevent unnecessary re-renders\n const memoizedOptions = useMemo(\n () => ({\n queryKey,\n queryFn: () => this.fetcher(endpoint, config),\n ...options,\n }),\n // Dependencies: queryKey, endpoint, config, and options\n // Note: We stringify config and options to ensure stable references\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [\n queryKey.join(','),\n endpoint,\n JSON.stringify(config),\n JSON.stringify(options),\n ],\n );\n\n return useQuery<ExtractEndpointResponse<Paths, T>, Response>(\n memoizedOptions,\n );\n }\n\n useMutation<T extends MutationEndpoint<Paths>>(\n endpoint: T,\n options?: Omit<\n UseMutationOptions<\n ExtractEndpointResponse<Paths, T>,\n Response,\n FilteredRequestConfig<Paths, T>\n >,\n 'mutationFn'\n >,\n ) {\n // Memoize the combined options to prevent unnecessary re-renders\n const memoizedOptions = useMemo(\n () => ({\n mutationFn: (config: FilteredRequestConfig<Paths, T>) =>\n this.fetcher(endpoint, config),\n ...options,\n }),\n // Dependencies: endpoint and options\n // Note: We stringify options to ensure stable reference\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [endpoint, JSON.stringify(options)],\n );\n\n return useMutation<\n ExtractEndpointResponse<Paths, T>,\n Response,\n FilteredRequestConfig<Paths, T>\n >(memoizedOptions);\n }\n\n useInfiniteQuery<\n T extends QueryEndpoint<Paths>,\n TPageData = ExtractEndpointResponse<Paths, T>,\n TPageParam = unknown,\n >(\n endpoint: T,\n options: Omit<\n UseInfiniteQueryOptions<\n TPageData,\n Response,\n { pages: TPageData[]; pageParams: TPageParam[] },\n unknown[],\n TPageParam\n >,\n 'queryKey' | 'queryFn' | 'getNextPageParam' | 'initialPageParam'\n > & {\n getNextPageParam: (\n lastPage: TPageData,\n allPages: TPageData[],\n lastPageParam: TPageParam,\n allPageParams: TPageParam[],\n ) => TPageParam | undefined;\n initialPageParam: TPageParam;\n },\n config?: FilteredRequestConfig<Paths, T>,\n ) {\n const queryKey = this.buildQueryKey(endpoint, config);\n\n // Memoize the combined options to prevent unnecessary re-renders\n const memoizedOptions = useMemo(\n () => ({\n queryKey,\n queryFn: ({\n pageParam,\n }: QueryFunctionContext<unknown[], TPageParam>) => {\n let mergedConfig = config;\n if (pageParam !== undefined && config) {\n // If pageParam is an object, spread it into query\n const pageQuery =\n typeof pageParam === 'object' ? pageParam : { page: pageParam };\n mergedConfig = {\n ...config,\n query: { ...(config as any).query, ...pageQuery },\n } as any;\n } else if (pageParam !== undefined && !config) {\n // If pageParam is an object, use it directly, otherwise wrap in page property\n const pageQuery =\n typeof pageParam === 'object' ? pageParam : { page: pageParam };\n mergedConfig = { query: pageQuery } as any;\n }\n return this.fetcher(endpoint, mergedConfig) as Promise<TPageData>;\n },\n ...options,\n }),\n // Dependencies: queryKey, endpoint, config, and options\n // Note: We stringify config and options to ensure stable references\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [\n queryKey.join(','),\n endpoint,\n JSON.stringify(config),\n JSON.stringify(options),\n ],\n );\n\n return useInfiniteQuery<\n TPageData,\n Response,\n { pages: TPageData[]; pageParams: TPageParam[] },\n unknown[],\n TPageParam\n >(memoizedOptions);\n }\n\n buildQueryKey<T extends TypedEndpoint<Paths>>(\n endpoint: T,\n config?: FilteredRequestConfig<Paths, T>,\n ): unknown[] {\n const key: unknown[] = [endpoint];\n\n if (config && 'params' in config && config.params) {\n key.push({ params: config.params });\n }\n\n if (config && 'query' in config && config.query) {\n key.push({ query: config.query });\n }\n\n return key;\n }\n\n /**\n * Invalidate queries for a specific endpoint with optional config\n * @param endpoint - The endpoint to invalidate (e.g., 'GET /users')\n * @param config - Optional params/query to match specific queries\n * @returns Promise that resolves when invalidation is complete\n */\n invalidateQueries<T extends QueryEndpoint<Paths>>(\n endpoint: T,\n config?: FilteredRequestConfig<Paths, T>,\n ): Promise<void> {\n const queryClient = this.getQueryClient();\n const queryKey = this.buildQueryKey(endpoint, config);\n\n return queryClient.invalidateQueries({\n queryKey,\n exact: !!config, // Use exact matching if config is provided\n });\n }\n\n /**\n * Invalidate all queries in the cache\n * @returns Promise that resolves when invalidation is complete\n */\n invalidateAllQueries(): Promise<void> {\n const queryClient = this.getQueryClient();\n return queryClient.invalidateQueries();\n }\n\n /**\n * Get the underlying QueryClient instance\n * @returns The QueryClient instance\n */\n getQueryClient(): QueryClient {\n if (this.queryClient) {\n return this.queryClient;\n }\n\n // If no query client was provided, try to get it from context\n // This will throw if used outside of QueryClientProvider\n throw new Error(\n 'No QueryClient set, please provide a QueryClient via the queryClient option or ensure you are within a QueryClientProvider',\n );\n }\n\n /**\n * Set the QueryClient instance\n * @param queryClient - The QueryClient instance to use\n */\n setQueryClient(queryClient: QueryClient): void {\n this.queryClient = queryClient;\n }\n}\n\nexport function createTypedQueryClient<Paths>(\n options?: TypedQueryClientOptions,\n) {\n return new TypedQueryClient<Paths>(options);\n}\n\n// Hook exports for convenience\nexport function useTypedQuery<Paths, T extends QueryEndpoint<Paths>>(\n client: TypedQueryClient<Paths>,\n endpoint: T,\n config?: FilteredRequestConfig<Paths, T>,\n options?: Omit<\n UseQueryOptions<ExtractEndpointResponse<Paths, T>, Response>,\n 'queryKey' | 'queryFn'\n >,\n) {\n return client.useQuery(endpoint, config, options);\n}\n\nexport function useTypedMutation<Paths, T extends MutationEndpoint<Paths>>(\n client: TypedQueryClient<Paths>,\n endpoint: T,\n options?: Omit<\n UseMutationOptions<\n ExtractEndpointResponse<Paths, T>,\n Response,\n FilteredRequestConfig<Paths, T>\n >,\n 'mutationFn'\n >,\n) {\n return client.useMutation(endpoint, options);\n}\n\nexport function useTypedInfiniteQuery<\n Paths,\n T extends QueryEndpoint<Paths>,\n TPageData = ExtractEndpointResponse<Paths, T>,\n TPageParam = unknown,\n>(\n client: TypedQueryClient<Paths>,\n endpoint: T,\n options: Omit<\n UseInfiniteQueryOptions<\n TPageData,\n Response,\n { pages: TPageData[]; pageParams: TPageParam[] },\n unknown[],\n TPageParam\n >,\n 'queryKey' | 'queryFn' | 'getNextPageParam' | 'initialPageParam'\n > & {\n getNextPageParam: (\n lastPage: TPageData,\n allPages: TPageData[],\n lastPageParam: TPageParam,\n allPageParams: TPageParam[],\n ) => TPageParam | undefined;\n initialPageParam: TPageParam;\n },\n config?: FilteredRequestConfig<Paths, T>,\n) {\n return client.useInfiniteQuery(endpoint, options, config);\n}\n\n/**\n * Hook to invalidate queries using the current QueryClient from context\n */\nexport function useTypedInvalidateQueries<Paths>(\n client: TypedQueryClient<Paths>,\n) {\n const queryClient = useQueryClient();\n\n return {\n /**\n * Invalidate queries for a specific endpoint\n */\n invalidateQueries: <T extends QueryEndpoint<Paths>>(\n endpoint: T,\n config?: FilteredRequestConfig<Paths, T>,\n ) => {\n const queryKey = client.buildQueryKey(endpoint, config);\n return queryClient.invalidateQueries({\n queryKey,\n exact: !!config,\n });\n },\n\n /**\n * Invalidate all queries\n */\n invalidateAllQueries: () => {\n return queryClient.invalidateQueries();\n },\n };\n}\n"],"mappings":"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"}
@@ -0,0 +1,68 @@
1
+ //#region src/types.d.ts
2
+ type OpenAPIRoutes<Paths> = keyof Paths;
3
+ type ExtractMethod<Paths, Route extends OpenAPIRoutes<Paths>> = keyof Paths[Route];
4
+ type ExtractPathParams<Paths, Route extends OpenAPIRoutes<Paths>> = Paths[Route] extends {
5
+ parameters?: {
6
+ path?: infer P;
7
+ };
8
+ } ? P : never;
9
+ type ExtractQueryParams<Paths, Route extends OpenAPIRoutes<Paths>, Method extends ExtractMethod<Paths, Route>> = Paths[Route][Method] extends {
10
+ parameters?: {
11
+ query?: infer Q;
12
+ };
13
+ } ? Q : never;
14
+ type ExtractRequestBody<Paths, Route extends OpenAPIRoutes<Paths>, Method extends ExtractMethod<Paths, Route>> = Paths[Route][Method] extends {
15
+ requestBody?: {
16
+ content?: {
17
+ 'application/json'?: infer B;
18
+ };
19
+ };
20
+ } ? B : never;
21
+ type ExtractResponse<Paths, Route extends OpenAPIRoutes<Paths>, Method extends ExtractMethod<Paths, Route>> = Paths[Route][Method] extends {
22
+ responses?: {
23
+ 200?: {
24
+ content?: {
25
+ 'application/json'?: infer R;
26
+ };
27
+ };
28
+ };
29
+ } ? R : Paths[Route][Method] extends {
30
+ responses?: {
31
+ 201?: {
32
+ content?: {
33
+ 'application/json'?: infer R;
34
+ };
35
+ };
36
+ };
37
+ } ? R : never;
38
+ type RequestConfig<Paths, Route extends OpenAPIRoutes<Paths>, Method extends ExtractMethod<Paths, Route>> = {
39
+ params?: ExtractPathParams<Paths, Route>;
40
+ query?: ExtractQueryParams<Paths, Route, Method>;
41
+ body?: ExtractRequestBody<Paths, Route, Method>;
42
+ headers?: Record<string, string>;
43
+ };
44
+ type EndpointString = `${Uppercase<string>} ${string}`;
45
+ type FilterNeverMethods<T> = { [K in keyof T as T[K] extends never | undefined ? never : K]: T[K] extends undefined ? never : T[K] };
46
+ type ValidEndpoint<Paths> = { [Route in keyof Paths]: { [Method in keyof FilterNeverMethods<Paths[Route]>]: `${Uppercase<string & Method>} ${string & Route}` }[keyof FilterNeverMethods<Paths[Route]>] }[keyof Paths];
47
+ type TypedEndpoint<Paths> = ValidEndpoint<Paths> extends infer E ? E extends string ? E : never : never;
48
+ type FilterEndpointByMethod<Paths, Method extends string> = ValidEndpoint<Paths> extends infer E ? E extends `${Method} ${string}` ? E : never : never;
49
+ type QueryEndpoint<Paths> = FilterEndpointByMethod<Paths, 'GET'>;
50
+ type MutationEndpoint<Paths> = FilterEndpointByMethod<Paths, 'POST'> | FilterEndpointByMethod<Paths, 'PATCH'> | FilterEndpointByMethod<Paths, 'PUT'> | FilterEndpointByMethod<Paths, 'DELETE'>;
51
+ type ParseEndpoint<T extends EndpointString> = T extends `${infer Method} ${infer Route}` ? {
52
+ method: Lowercase<Method>;
53
+ route: Route;
54
+ } : never;
55
+ type ExtractEndpointResponse<Paths, T extends EndpointString> = T extends `${infer Method} ${infer Route}` ? Route extends OpenAPIRoutes<Paths> ? Lowercase<Method> extends ExtractMethod<Paths, Route> ? ExtractResponse<Paths, Route, Lowercase<Method>> : never : never : never;
56
+ type ExtractEndpointConfig<Paths, T extends EndpointString> = T extends `${infer Method} ${infer Route}` ? Route extends OpenAPIRoutes<Paths> ? Lowercase<Method> extends ExtractMethod<Paths, Route> ? RequestConfig<Paths, Route, Lowercase<Method>> : never : never : never;
57
+ type FilteredRequestConfig<Paths, T extends EndpointString> = { [K in keyof ExtractEndpointConfig<Paths, T> as ExtractEndpointConfig<Paths, T>[K] extends never | undefined ? never : K]: ExtractEndpointConfig<Paths, T>[K] };
58
+ interface FetcherOptions {
59
+ baseURL?: string;
60
+ headers?: Record<string, string>;
61
+ onRequest?: (config: RequestInit) => RequestInit | Promise<RequestInit>;
62
+ onResponse?: (response: Response) => Response | Promise<Response>;
63
+ onError?: (error: Error) => void | Promise<void>;
64
+ fetch?: typeof fetch;
65
+ }
66
+ //#endregion
67
+ export { EndpointString, ExtractEndpointConfig, ExtractEndpointResponse, ExtractMethod, ExtractPathParams, ExtractQueryParams, ExtractRequestBody, ExtractResponse, FetcherOptions, FilterEndpointByMethod, FilteredRequestConfig, MutationEndpoint, OpenAPIRoutes, ParseEndpoint, QueryEndpoint, RequestConfig, TypedEndpoint, ValidEndpoint };
68
+ //# sourceMappingURL=types-csACmD6U.d.cts.map
@@ -0,0 +1,68 @@
1
+ //#region src/types.d.ts
2
+ type OpenAPIRoutes<Paths> = keyof Paths;
3
+ type ExtractMethod<Paths, Route extends OpenAPIRoutes<Paths>> = keyof Paths[Route];
4
+ type ExtractPathParams<Paths, Route extends OpenAPIRoutes<Paths>> = Paths[Route] extends {
5
+ parameters?: {
6
+ path?: infer P;
7
+ };
8
+ } ? P : never;
9
+ type ExtractQueryParams<Paths, Route extends OpenAPIRoutes<Paths>, Method extends ExtractMethod<Paths, Route>> = Paths[Route][Method] extends {
10
+ parameters?: {
11
+ query?: infer Q;
12
+ };
13
+ } ? Q : never;
14
+ type ExtractRequestBody<Paths, Route extends OpenAPIRoutes<Paths>, Method extends ExtractMethod<Paths, Route>> = Paths[Route][Method] extends {
15
+ requestBody?: {
16
+ content?: {
17
+ 'application/json'?: infer B;
18
+ };
19
+ };
20
+ } ? B : never;
21
+ type ExtractResponse<Paths, Route extends OpenAPIRoutes<Paths>, Method extends ExtractMethod<Paths, Route>> = Paths[Route][Method] extends {
22
+ responses?: {
23
+ 200?: {
24
+ content?: {
25
+ 'application/json'?: infer R;
26
+ };
27
+ };
28
+ };
29
+ } ? R : Paths[Route][Method] extends {
30
+ responses?: {
31
+ 201?: {
32
+ content?: {
33
+ 'application/json'?: infer R;
34
+ };
35
+ };
36
+ };
37
+ } ? R : never;
38
+ type RequestConfig<Paths, Route extends OpenAPIRoutes<Paths>, Method extends ExtractMethod<Paths, Route>> = {
39
+ params?: ExtractPathParams<Paths, Route>;
40
+ query?: ExtractQueryParams<Paths, Route, Method>;
41
+ body?: ExtractRequestBody<Paths, Route, Method>;
42
+ headers?: Record<string, string>;
43
+ };
44
+ type EndpointString = `${Uppercase<string>} ${string}`;
45
+ type FilterNeverMethods<T> = { [K in keyof T as T[K] extends never | undefined ? never : K]: T[K] extends undefined ? never : T[K] };
46
+ type ValidEndpoint<Paths> = { [Route in keyof Paths]: { [Method in keyof FilterNeverMethods<Paths[Route]>]: `${Uppercase<string & Method>} ${string & Route}` }[keyof FilterNeverMethods<Paths[Route]>] }[keyof Paths];
47
+ type TypedEndpoint<Paths> = ValidEndpoint<Paths> extends infer E ? E extends string ? E : never : never;
48
+ type FilterEndpointByMethod<Paths, Method extends string> = ValidEndpoint<Paths> extends infer E ? E extends `${Method} ${string}` ? E : never : never;
49
+ type QueryEndpoint<Paths> = FilterEndpointByMethod<Paths, 'GET'>;
50
+ type MutationEndpoint<Paths> = FilterEndpointByMethod<Paths, 'POST'> | FilterEndpointByMethod<Paths, 'PATCH'> | FilterEndpointByMethod<Paths, 'PUT'> | FilterEndpointByMethod<Paths, 'DELETE'>;
51
+ type ParseEndpoint<T extends EndpointString> = T extends `${infer Method} ${infer Route}` ? {
52
+ method: Lowercase<Method>;
53
+ route: Route;
54
+ } : never;
55
+ type ExtractEndpointResponse<Paths, T extends EndpointString> = T extends `${infer Method} ${infer Route}` ? Route extends OpenAPIRoutes<Paths> ? Lowercase<Method> extends ExtractMethod<Paths, Route> ? ExtractResponse<Paths, Route, Lowercase<Method>> : never : never : never;
56
+ type ExtractEndpointConfig<Paths, T extends EndpointString> = T extends `${infer Method} ${infer Route}` ? Route extends OpenAPIRoutes<Paths> ? Lowercase<Method> extends ExtractMethod<Paths, Route> ? RequestConfig<Paths, Route, Lowercase<Method>> : never : never : never;
57
+ type FilteredRequestConfig<Paths, T extends EndpointString> = { [K in keyof ExtractEndpointConfig<Paths, T> as ExtractEndpointConfig<Paths, T>[K] extends never | undefined ? never : K]: ExtractEndpointConfig<Paths, T>[K] };
58
+ interface FetcherOptions {
59
+ baseURL?: string;
60
+ headers?: Record<string, string>;
61
+ onRequest?: (config: RequestInit) => RequestInit | Promise<RequestInit>;
62
+ onResponse?: (response: Response) => Response | Promise<Response>;
63
+ onError?: (error: Error) => void | Promise<void>;
64
+ fetch?: typeof fetch;
65
+ }
66
+ //#endregion
67
+ export { EndpointString, ExtractEndpointConfig, ExtractEndpointResponse, ExtractMethod, ExtractPathParams, ExtractQueryParams, ExtractRequestBody, ExtractResponse, FetcherOptions, FilterEndpointByMethod, FilteredRequestConfig, MutationEndpoint, OpenAPIRoutes, ParseEndpoint, QueryEndpoint, RequestConfig, TypedEndpoint, ValidEndpoint };
68
+ //# sourceMappingURL=types-tMp85Lt_.d.mts.map
package/dist/types.cjs ADDED
File without changes