@qualisero/openapi-endpoint 0.12.3 → 0.13.2

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.
@@ -1,214 +1,79 @@
1
- import { type ComputedRef, type MaybeRefOrGetter } from 'vue';
2
- import { Operations, type GetPathParameters, type GetResponseData, type QQueryOptions } from './types';
1
+ import { type ComputedRef, type MaybeRefOrGetter, type Ref } from 'vue';
2
+ import { Operations, type ApiPathParams, type ApiPathParamsInput, type ApiResponse, type QQueryOptions } from './types';
3
3
  import { type OpenApiHelpers } from './openapi-helpers';
4
- export type EndpointQueryReturn<Ops extends Operations<Ops>, Op extends keyof Ops> = ReturnType<typeof useEndpointQuery<Ops, Op>> & {
5
- onLoad: (callback: (data: GetResponseData<Ops, Op>) => void) => void;
6
- };
7
4
  /**
8
- * Composable for performing a strictly typed OpenAPI query operation using Vue Query.
9
- * Ensures the operation is a query (GET/HEAD/OPTIONS) at runtime.
10
- * Returns a reactive query object, including helpers for query key, enabled state, and an `onLoad` callback.
5
+ * Return type of `useQuery` (created via `useOpenApi`).
11
6
  *
12
- * @template T OperationId type representing the OpenAPI operation.
13
- * @param operationId The OpenAPI operation ID to query.
14
- * @param pathParams Optional path parameters for the endpoint, can be reactive.
15
- * @param options Optional query options, including:
16
- * - All properties from {@link UseQueryOptions} (from @tanstack/vue-query)
17
- * - `enabled`: Whether the query should automatically run (boolean or reactive).
18
- * - `onLoad`: Callback invoked once when data is loaded (immediately or after fetch).
19
- * - `axiosOptions`: Custom axios request options (e.g., headers, params).
20
- * @throws Error if the operation is not a query operation.
21
- * @returns Query object with strict typing and helpers:
22
- * - `data`: ComputedRef of response data.
23
- * - `isEnabled`: ComputedRef indicating if query is enabled.
24
- * - `queryKey`: ComputedRef of the query key.
25
- * - `onLoad`: Method to register a callback for when data is loaded.
7
+ * Reactive query result with automatic caching, error handling, and helpers.
8
+ *
9
+ * All properties are reactive (ComputedRef) and auto-unwrap in Vue templates.
10
+ *
11
+ * @template Ops - The operations type from your OpenAPI specification
12
+ * @template Op - The operation key from your operations type
13
+ *
14
+ * @example
15
+ * ```typescript
16
+ * const query = api.useQuery('listPets', { queryParams: { limit: 10 } })
17
+ *
18
+ * // Reactive properties
19
+ * if (query.isPending.value) console.log('Loading...')
20
+ * if (query.isError.value) console.log('Error:', query.error.value)
21
+ * if (query.isSuccess.value) console.log('Data:', query.data.value)
22
+ *
23
+ * // Helpers
24
+ * query.refetch() // Manual refetch
25
+ * query.onLoad((data) => console.log('First load:', data))
26
+ * ```
27
+ *
28
+ * @group Types
26
29
  */
27
- export declare function useEndpointQuery<Ops extends Operations<Ops>, Op extends keyof Ops>(operationId: Op, h: OpenApiHelpers<Ops, Op>, pathParamsOrOptions?: MaybeRefOrGetter<GetPathParameters<Ops, Op> | null | undefined> | QQueryOptions<Ops, Op>, optionsOrNull?: QQueryOptions<Ops, Op>): {
28
- data: ComputedRef<GetResponseData<Ops, Op> | undefined>;
29
- isEnabled: ComputedRef<boolean>;
30
- queryKey: ComputedRef<(string | import("./types").GetQueryParameters<Ops, Op>)[]>;
31
- onLoad: (callback: (data: GetResponseData<Ops, Op>) => void) => void;
32
- pathParams: ComputedRef<GetPathParameters<Ops, Op> | null | undefined>;
33
- error: import("vue").Ref<Error, Error>;
34
- isError: import("vue").Ref<true, true>;
35
- isPending: import("vue").Ref<false, false>;
36
- isLoading: import("vue").Ref<false, false>;
37
- isLoadingError: import("vue").Ref<false, false>;
38
- isRefetchError: import("vue").Ref<true, true>;
39
- isSuccess: import("vue").Ref<false, false>;
40
- isPlaceholderData: import("vue").Ref<false, false>;
41
- status: import("vue").Ref<"error", "error">;
42
- dataUpdatedAt: import("vue").Ref<number, number>;
43
- errorUpdatedAt: import("vue").Ref<number, number>;
44
- failureCount: import("vue").Ref<number, number>;
45
- failureReason: import("vue").Ref<Error | null, Error | null>;
46
- errorUpdateCount: import("vue").Ref<number, number>;
47
- isFetched: import("vue").Ref<boolean, boolean>;
48
- isFetchedAfterMount: import("vue").Ref<boolean, boolean>;
49
- isFetching: import("vue").Ref<boolean, boolean>;
50
- isInitialLoading: import("vue").Ref<boolean, boolean>;
51
- isPaused: import("vue").Ref<boolean, boolean>;
52
- isRefetching: import("vue").Ref<boolean, boolean>;
53
- isStale: import("vue").Ref<boolean, boolean>;
54
- refetch: (options?: import("@tanstack/query-core").RefetchOptions) => Promise<import("@tanstack/query-core").QueryObserverResult<GetResponseData<Ops, Op>, Error>>;
55
- fetchStatus: import("vue").Ref<import("@tanstack/query-core").FetchStatus, import("@tanstack/query-core").FetchStatus>;
56
- promise: import("vue").Ref<Promise<GetResponseData<Ops, Op>>, Promise<GetResponseData<Ops, Op>>>;
57
- suspense: () => Promise<import("@tanstack/query-core").QueryObserverResult<GetResponseData<Ops, Op>, Error>>;
58
- } | {
59
- data: ComputedRef<GetResponseData<Ops, Op> | undefined>;
60
- isEnabled: ComputedRef<boolean>;
61
- queryKey: ComputedRef<(string | import("./types").GetQueryParameters<Ops, Op>)[]>;
62
- onLoad: (callback: (data: GetResponseData<Ops, Op>) => void) => void;
63
- pathParams: ComputedRef<GetPathParameters<Ops, Op> | null | undefined>;
64
- error: import("vue").Ref<null, null>;
65
- isError: import("vue").Ref<false, false>;
66
- isPending: import("vue").Ref<false, false>;
67
- isLoading: import("vue").Ref<false, false>;
68
- isLoadingError: import("vue").Ref<false, false>;
69
- isRefetchError: import("vue").Ref<false, false>;
70
- isSuccess: import("vue").Ref<true, true>;
71
- isPlaceholderData: import("vue").Ref<false, false>;
72
- status: import("vue").Ref<"success", "success">;
73
- dataUpdatedAt: import("vue").Ref<number, number>;
74
- errorUpdatedAt: import("vue").Ref<number, number>;
75
- failureCount: import("vue").Ref<number, number>;
76
- failureReason: import("vue").Ref<Error | null, Error | null>;
77
- errorUpdateCount: import("vue").Ref<number, number>;
78
- isFetched: import("vue").Ref<boolean, boolean>;
79
- isFetchedAfterMount: import("vue").Ref<boolean, boolean>;
80
- isFetching: import("vue").Ref<boolean, boolean>;
81
- isInitialLoading: import("vue").Ref<boolean, boolean>;
82
- isPaused: import("vue").Ref<boolean, boolean>;
83
- isRefetching: import("vue").Ref<boolean, boolean>;
84
- isStale: import("vue").Ref<boolean, boolean>;
85
- refetch: (options?: import("@tanstack/query-core").RefetchOptions) => Promise<import("@tanstack/query-core").QueryObserverResult<GetResponseData<Ops, Op>, Error>>;
86
- fetchStatus: import("vue").Ref<import("@tanstack/query-core").FetchStatus, import("@tanstack/query-core").FetchStatus>;
87
- promise: import("vue").Ref<Promise<GetResponseData<Ops, Op>>, Promise<GetResponseData<Ops, Op>>>;
88
- suspense: () => Promise<import("@tanstack/query-core").QueryObserverResult<GetResponseData<Ops, Op>, Error>>;
89
- } | {
90
- data: ComputedRef<GetResponseData<Ops, Op> | undefined>;
30
+ export interface EndpointQueryReturn<Ops extends Operations<Ops>, Op extends keyof Ops> {
31
+ /** The response data (undefined until loaded). */
32
+ data: ComputedRef<ApiResponse<Ops, Op> | undefined>;
33
+ /** The error if the query failed. */
34
+ error: Ref<Error | null>;
35
+ /** True while the query is loading. */
36
+ isPending: Ref<boolean>;
37
+ /** True while loading (same as isPending, for compatibility). */
38
+ isLoading: Ref<boolean>;
39
+ /** True when the query succeeded. */
40
+ isSuccess: Ref<boolean>;
41
+ /** True when the query failed. */
42
+ isError: Ref<boolean>;
43
+ /** Manually trigger a refetch. */
44
+ refetch: () => Promise<void>;
45
+ /** Whether the query is currently enabled. */
91
46
  isEnabled: ComputedRef<boolean>;
92
- queryKey: ComputedRef<(string | import("./types").GetQueryParameters<Ops, Op>)[]>;
93
- onLoad: (callback: (data: GetResponseData<Ops, Op>) => void) => void;
94
- pathParams: ComputedRef<GetPathParameters<Ops, Op> | null | undefined>;
95
- error: import("vue").Ref<Error, Error>;
96
- isError: import("vue").Ref<true, true>;
97
- isPending: import("vue").Ref<false, false>;
98
- isLoading: import("vue").Ref<false, false>;
99
- isLoadingError: import("vue").Ref<true, true>;
100
- isRefetchError: import("vue").Ref<false, false>;
101
- isSuccess: import("vue").Ref<false, false>;
102
- isPlaceholderData: import("vue").Ref<false, false>;
103
- status: import("vue").Ref<"error", "error">;
104
- dataUpdatedAt: import("vue").Ref<number, number>;
105
- errorUpdatedAt: import("vue").Ref<number, number>;
106
- failureCount: import("vue").Ref<number, number>;
107
- failureReason: import("vue").Ref<Error | null, Error | null>;
108
- errorUpdateCount: import("vue").Ref<number, number>;
109
- isFetched: import("vue").Ref<boolean, boolean>;
110
- isFetchedAfterMount: import("vue").Ref<boolean, boolean>;
111
- isFetching: import("vue").Ref<boolean, boolean>;
112
- isInitialLoading: import("vue").Ref<boolean, boolean>;
113
- isPaused: import("vue").Ref<boolean, boolean>;
114
- isRefetching: import("vue").Ref<boolean, boolean>;
115
- isStale: import("vue").Ref<boolean, boolean>;
116
- refetch: (options?: import("@tanstack/query-core").RefetchOptions) => Promise<import("@tanstack/query-core").QueryObserverResult<GetResponseData<Ops, Op>, Error>>;
117
- fetchStatus: import("vue").Ref<import("@tanstack/query-core").FetchStatus, import("@tanstack/query-core").FetchStatus>;
118
- promise: import("vue").Ref<Promise<GetResponseData<Ops, Op>>, Promise<GetResponseData<Ops, Op>>>;
119
- suspense: () => Promise<import("@tanstack/query-core").QueryObserverResult<GetResponseData<Ops, Op>, Error>>;
120
- } | {
121
- data: ComputedRef<GetResponseData<Ops, Op> | undefined>;
122
- isEnabled: ComputedRef<boolean>;
123
- queryKey: ComputedRef<(string | import("./types").GetQueryParameters<Ops, Op>)[]>;
124
- onLoad: (callback: (data: GetResponseData<Ops, Op>) => void) => void;
125
- pathParams: ComputedRef<GetPathParameters<Ops, Op> | null | undefined>;
126
- error: import("vue").Ref<null, null>;
127
- isError: import("vue").Ref<false, false>;
128
- isPending: import("vue").Ref<true, true>;
129
- isLoading: import("vue").Ref<true, true>;
130
- isLoadingError: import("vue").Ref<false, false>;
131
- isRefetchError: import("vue").Ref<false, false>;
132
- isSuccess: import("vue").Ref<false, false>;
133
- isPlaceholderData: import("vue").Ref<false, false>;
134
- status: import("vue").Ref<"pending", "pending">;
135
- dataUpdatedAt: import("vue").Ref<number, number>;
136
- errorUpdatedAt: import("vue").Ref<number, number>;
137
- failureCount: import("vue").Ref<number, number>;
138
- failureReason: import("vue").Ref<Error | null, Error | null>;
139
- errorUpdateCount: import("vue").Ref<number, number>;
140
- isFetched: import("vue").Ref<boolean, boolean>;
141
- isFetchedAfterMount: import("vue").Ref<boolean, boolean>;
142
- isFetching: import("vue").Ref<boolean, boolean>;
143
- isInitialLoading: import("vue").Ref<boolean, boolean>;
144
- isPaused: import("vue").Ref<boolean, boolean>;
145
- isRefetching: import("vue").Ref<boolean, boolean>;
146
- isStale: import("vue").Ref<boolean, boolean>;
147
- refetch: (options?: import("@tanstack/query-core").RefetchOptions) => Promise<import("@tanstack/query-core").QueryObserverResult<GetResponseData<Ops, Op>, Error>>;
148
- fetchStatus: import("vue").Ref<import("@tanstack/query-core").FetchStatus, import("@tanstack/query-core").FetchStatus>;
149
- promise: import("vue").Ref<Promise<GetResponseData<Ops, Op>>, Promise<GetResponseData<Ops, Op>>>;
150
- suspense: () => Promise<import("@tanstack/query-core").QueryObserverResult<GetResponseData<Ops, Op>, Error>>;
151
- } | {
152
- data: ComputedRef<GetResponseData<Ops, Op> | undefined>;
153
- isEnabled: ComputedRef<boolean>;
154
- queryKey: ComputedRef<(string | import("./types").GetQueryParameters<Ops, Op>)[]>;
155
- onLoad: (callback: (data: GetResponseData<Ops, Op>) => void) => void;
156
- pathParams: ComputedRef<GetPathParameters<Ops, Op> | null | undefined>;
157
- error: import("vue").Ref<null, null>;
158
- isError: import("vue").Ref<false, false>;
159
- isPending: import("vue").Ref<true, true>;
160
- isLoadingError: import("vue").Ref<false, false>;
161
- isRefetchError: import("vue").Ref<false, false>;
162
- isSuccess: import("vue").Ref<false, false>;
163
- isPlaceholderData: import("vue").Ref<false, false>;
164
- status: import("vue").Ref<"pending", "pending">;
165
- dataUpdatedAt: import("vue").Ref<number, number>;
166
- errorUpdatedAt: import("vue").Ref<number, number>;
167
- failureCount: import("vue").Ref<number, number>;
168
- failureReason: import("vue").Ref<Error | null, Error | null>;
169
- errorUpdateCount: import("vue").Ref<number, number>;
170
- isFetched: import("vue").Ref<boolean, boolean>;
171
- isFetchedAfterMount: import("vue").Ref<boolean, boolean>;
172
- isFetching: import("vue").Ref<boolean, boolean>;
173
- isLoading: import("vue").Ref<boolean, boolean>;
174
- isInitialLoading: import("vue").Ref<boolean, boolean>;
175
- isPaused: import("vue").Ref<boolean, boolean>;
176
- isRefetching: import("vue").Ref<boolean, boolean>;
177
- isStale: import("vue").Ref<boolean, boolean>;
178
- refetch: (options?: import("@tanstack/query-core").RefetchOptions) => Promise<import("@tanstack/query-core").QueryObserverResult<GetResponseData<Ops, Op>, Error>>;
179
- fetchStatus: import("vue").Ref<import("@tanstack/query-core").FetchStatus, import("@tanstack/query-core").FetchStatus>;
180
- promise: import("vue").Ref<Promise<GetResponseData<Ops, Op>>, Promise<GetResponseData<Ops, Op>>>;
181
- suspense: () => Promise<import("@tanstack/query-core").QueryObserverResult<GetResponseData<Ops, Op>, Error>>;
182
- } | {
183
- data: ComputedRef<GetResponseData<Ops, Op> | undefined>;
184
- isEnabled: ComputedRef<boolean>;
185
- queryKey: ComputedRef<(string | import("./types").GetQueryParameters<Ops, Op>)[]>;
186
- onLoad: (callback: (data: GetResponseData<Ops, Op>) => void) => void;
187
- pathParams: ComputedRef<GetPathParameters<Ops, Op> | null | undefined>;
188
- isError: import("vue").Ref<false, false>;
189
- error: import("vue").Ref<null, null>;
190
- isPending: import("vue").Ref<false, false>;
191
- isLoading: import("vue").Ref<false, false>;
192
- isLoadingError: import("vue").Ref<false, false>;
193
- isRefetchError: import("vue").Ref<false, false>;
194
- isSuccess: import("vue").Ref<true, true>;
195
- isPlaceholderData: import("vue").Ref<true, true>;
196
- status: import("vue").Ref<"success", "success">;
197
- dataUpdatedAt: import("vue").Ref<number, number>;
198
- errorUpdatedAt: import("vue").Ref<number, number>;
199
- failureCount: import("vue").Ref<number, number>;
200
- failureReason: import("vue").Ref<Error | null, Error | null>;
201
- errorUpdateCount: import("vue").Ref<number, number>;
202
- isFetched: import("vue").Ref<boolean, boolean>;
203
- isFetchedAfterMount: import("vue").Ref<boolean, boolean>;
204
- isFetching: import("vue").Ref<boolean, boolean>;
205
- isInitialLoading: import("vue").Ref<boolean, boolean>;
206
- isPaused: import("vue").Ref<boolean, boolean>;
207
- isRefetching: import("vue").Ref<boolean, boolean>;
208
- isStale: import("vue").Ref<boolean, boolean>;
209
- refetch: (options?: import("@tanstack/query-core").RefetchOptions) => Promise<import("@tanstack/query-core").QueryObserverResult<GetResponseData<Ops, Op>, Error>>;
210
- fetchStatus: import("vue").Ref<import("@tanstack/query-core").FetchStatus, import("@tanstack/query-core").FetchStatus>;
211
- promise: import("vue").Ref<Promise<GetResponseData<Ops, Op>>, Promise<GetResponseData<Ops, Op>>>;
212
- suspense: () => Promise<import("@tanstack/query-core").QueryObserverResult<GetResponseData<Ops, Op>, Error>>;
213
- };
47
+ /** The resolved query key for manual cache access. */
48
+ queryKey: ComputedRef<string[] | (string | unknown)[]>;
49
+ /** The resolved path parameters. */
50
+ pathParams: ComputedRef<ApiPathParams<Ops, Op>>;
51
+ /** Register a callback for when data loads successfully for the first time. */
52
+ onLoad: (callback: (data: ApiResponse<Ops, Op>) => void) => void;
53
+ }
54
+ /**
55
+ * Execute a type-safe query (GET/HEAD/OPTIONS) with automatic caching.
56
+ *
57
+ * Ensures the operation is a query at runtime and returns a reactive query object,
58
+ * including helpers for query key, enabled state, and an `onLoad` callback.
59
+ *
60
+ * @template Ops - The operations type from your OpenAPI specification
61
+ * @template Op - The operation key from your operations type
62
+ * @param operationId - The OpenAPI operation ID to query
63
+ * @param h - OpenAPI helpers (internal), provided by useOpenApi
64
+ * @param pathParams - Path parameters (can be reactive). Omit for operations without path params.
65
+ * @param options - Query options (enabled, staleTime, queryParams, etc.)
66
+ * - `enabled`: Whether the query should auto-run (boolean or reactive)
67
+ * - `queryParams`: Query string parameters (operation-specific)
68
+ * - `onLoad`: Callback invoked once when data is loaded
69
+ * - `axiosOptions`: Custom axios request options (headers, params, etc.)
70
+ * - Plus all {@link UseQueryOptions} from @tanstack/vue-query
71
+ * @throws Error if the operation is not a query operation
72
+ * @returns Query object with strict typing and helpers:
73
+ * - `data`: ComputedRef of response data
74
+ * - `isEnabled`: ComputedRef indicating if query is enabled
75
+ * - `queryKey`: ComputedRef of the query key
76
+ * - `onLoad(callback)`: Register a callback for when data is loaded
77
+ */
78
+ export declare function useEndpointQuery<Ops extends Operations<Ops>, Op extends keyof Ops>(operationId: Op, h: OpenApiHelpers<Ops, Op>, pathParams?: MaybeRefOrGetter<ApiPathParamsInput<Ops, Op> | null | undefined>, options?: QQueryOptions<Ops, Op>): EndpointQueryReturn<Ops, Op>;
214
79
  //# sourceMappingURL=openapi-query.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"openapi-query.d.ts","sourceRoot":"","sources":["../src/openapi-query.ts"],"names":[],"mappings":"AAAA,OAAO,EAA4B,KAAK,WAAW,EAAE,KAAK,gBAAgB,EAAE,MAAM,KAAK,CAAA;AAEvF,OAAO,EAAE,UAAU,EAAE,KAAK,iBAAiB,EAAE,KAAK,eAAe,EAAE,KAAK,aAAa,EAAE,MAAM,SAAS,CAAA;AAGtG,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,mBAAmB,CAAA;AAEvD,MAAM,MAAM,mBAAmB,CAAC,GAAG,SAAS,UAAU,CAAC,GAAG,CAAC,EAAE,EAAE,SAAS,MAAM,GAAG,IAAI,UAAU,CAC7F,OAAO,gBAAgB,CAAC,GAAG,EAAE,EAAE,CAAC,CACjC,GAAG;IACF,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,eAAe,CAAC,GAAG,EAAE,EAAE,CAAC,KAAK,IAAI,KAAK,IAAI,CAAA;CACrE,CAAA;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,SAAS,UAAU,CAAC,GAAG,CAAC,EAAE,EAAE,SAAS,MAAM,GAAG,EAChF,WAAW,EAAE,EAAE,EACf,CAAC,EAAE,cAAc,CAAC,GAAG,EAAE,EAAE,CAAC,EAC1B,mBAAmB,CAAC,EAAE,gBAAgB,CAAC,iBAAiB,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,IAAI,GAAG,SAAS,CAAC,GAAG,aAAa,CAAC,GAAG,EAAE,EAAE,CAAC,EAC9G,aAAa,CAAC,EAAE,aAAa,CAAC,GAAG,EAAE,EAAE,CAAC;UAgIhB,WAAW,CAAC,eAAe,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,SAAS,CAAC;;;uBAN7C,CAAC,IAAI,EAAE,eAAe,CAAC,GAAG,EAAE,EAAE,CAAC,KAAK,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;UAM5C,WAAW,CAAC,eAAe,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,SAAS,CAAC;;;uBAN7C,CAAC,IAAI,EAAE,eAAe,CAAC,GAAG,EAAE,EAAE,CAAC,KAAK,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;UAM5C,WAAW,CAAC,eAAe,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,SAAS,CAAC;;;uBAN7C,CAAC,IAAI,EAAE,eAAe,CAAC,GAAG,EAAE,EAAE,CAAC,KAAK,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;UAM5C,WAAW,CAAC,eAAe,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,SAAS,CAAC;;;uBAN7C,CAAC,IAAI,EAAE,eAAe,CAAC,GAAG,EAAE,EAAE,CAAC,KAAK,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;UAM5C,WAAW,CAAC,eAAe,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,SAAS,CAAC;;;uBAN7C,CAAC,IAAI,EAAE,eAAe,CAAC,GAAG,EAAE,EAAE,CAAC,KAAK,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;UAM5C,WAAW,CAAC,eAAe,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,SAAS,CAAC;;;uBAN7C,CAAC,IAAI,EAAE,eAAe,CAAC,GAAG,EAAE,EAAE,CAAC,KAAK,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;EAYnE"}
1
+ {"version":3,"file":"openapi-query.d.ts","sourceRoot":"","sources":["../src/openapi-query.ts"],"names":[],"mappings":"AAAA,OAAO,EAA4B,KAAK,WAAW,EAAE,KAAK,gBAAgB,EAAE,KAAK,GAAG,EAAE,MAAM,KAAK,CAAA;AAEjG,OAAO,EAAE,UAAU,EAAE,KAAK,aAAa,EAAE,KAAK,kBAAkB,EAAE,KAAK,WAAW,EAAE,KAAK,aAAa,EAAE,MAAM,SAAS,CAAA;AAGvH,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,mBAAmB,CAAA;AAEvD;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,MAAM,WAAW,mBAAmB,CAAC,GAAG,SAAS,UAAU,CAAC,GAAG,CAAC,EAAE,EAAE,SAAS,MAAM,GAAG;IACpF,kDAAkD;IAClD,IAAI,EAAE,WAAW,CAAC,WAAW,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,SAAS,CAAC,CAAA;IAEnD,qCAAqC;IACrC,KAAK,EAAE,GAAG,CAAC,KAAK,GAAG,IAAI,CAAC,CAAA;IAExB,uCAAuC;IACvC,SAAS,EAAE,GAAG,CAAC,OAAO,CAAC,CAAA;IAEvB,iEAAiE;IACjE,SAAS,EAAE,GAAG,CAAC,OAAO,CAAC,CAAA;IAEvB,qCAAqC;IACrC,SAAS,EAAE,GAAG,CAAC,OAAO,CAAC,CAAA;IAEvB,kCAAkC;IAClC,OAAO,EAAE,GAAG,CAAC,OAAO,CAAC,CAAA;IAErB,kCAAkC;IAClC,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;IAE5B,8CAA8C;IAC9C,SAAS,EAAE,WAAW,CAAC,OAAO,CAAC,CAAA;IAE/B,sDAAsD;IACtD,QAAQ,EAAE,WAAW,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,GAAG,OAAO,CAAC,EAAE,CAAC,CAAA;IAEtD,oCAAoC;IACpC,UAAU,EAAE,WAAW,CAAC,aAAa,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,CAAA;IAE/C,+EAA+E;IAC/E,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,WAAW,CAAC,GAAG,EAAE,EAAE,CAAC,KAAK,IAAI,KAAK,IAAI,CAAA;CACjE;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,SAAS,UAAU,CAAC,GAAG,CAAC,EAAE,EAAE,SAAS,MAAM,GAAG,EAChF,WAAW,EAAE,EAAE,EACf,CAAC,EAAE,cAAc,CAAC,GAAG,EAAE,EAAE,CAAC,EAC1B,UAAU,CAAC,EAAE,gBAAgB,CAAC,kBAAkB,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,IAAI,GAAG,SAAS,CAAC,EAC7E,OAAO,CAAC,EAAE,aAAa,CAAC,GAAG,EAAE,EAAE,CAAC,GA+HhB,mBAAmB,CAAC,GAAG,EAAE,EAAE,CAAC,CAC7C"}
@@ -1,64 +1,50 @@
1
1
  import { computed, watch, toValue } from 'vue';
2
2
  import { useQuery } from '@tanstack/vue-query';
3
- import { resolvePath, generateQueryKey, isPathResolved, getParamsOptionsFrom } from './openapi-utils.js';
3
+ import { normalizeParamsOptions, useResolvedOperation } from './openapi-utils.js';
4
4
  import { isAxiosError } from 'axios';
5
5
  /**
6
- * Composable for performing a strictly typed OpenAPI query operation using Vue Query.
7
- * Ensures the operation is a query (GET/HEAD/OPTIONS) at runtime.
8
- * Returns a reactive query object, including helpers for query key, enabled state, and an `onLoad` callback.
6
+ * Execute a type-safe query (GET/HEAD/OPTIONS) with automatic caching.
9
7
  *
10
- * @template T OperationId type representing the OpenAPI operation.
11
- * @param operationId The OpenAPI operation ID to query.
12
- * @param pathParams Optional path parameters for the endpoint, can be reactive.
13
- * @param options Optional query options, including:
14
- * - All properties from {@link UseQueryOptions} (from @tanstack/vue-query)
15
- * - `enabled`: Whether the query should automatically run (boolean or reactive).
16
- * - `onLoad`: Callback invoked once when data is loaded (immediately or after fetch).
17
- * - `axiosOptions`: Custom axios request options (e.g., headers, params).
18
- * @throws Error if the operation is not a query operation.
8
+ * Ensures the operation is a query at runtime and returns a reactive query object,
9
+ * including helpers for query key, enabled state, and an `onLoad` callback.
10
+ *
11
+ * @template Ops - The operations type from your OpenAPI specification
12
+ * @template Op - The operation key from your operations type
13
+ * @param operationId - The OpenAPI operation ID to query
14
+ * @param h - OpenAPI helpers (internal), provided by useOpenApi
15
+ * @param pathParams - Path parameters (can be reactive). Omit for operations without path params.
16
+ * @param options - Query options (enabled, staleTime, queryParams, etc.)
17
+ * - `enabled`: Whether the query should auto-run (boolean or reactive)
18
+ * - `queryParams`: Query string parameters (operation-specific)
19
+ * - `onLoad`: Callback invoked once when data is loaded
20
+ * - `axiosOptions`: Custom axios request options (headers, params, etc.)
21
+ * - Plus all {@link UseQueryOptions} from @tanstack/vue-query
22
+ * @throws Error if the operation is not a query operation
19
23
  * @returns Query object with strict typing and helpers:
20
- * - `data`: ComputedRef of response data.
21
- * - `isEnabled`: ComputedRef indicating if query is enabled.
22
- * - `queryKey`: ComputedRef of the query key.
23
- * - `onLoad`: Method to register a callback for when data is loaded.
24
+ * - `data`: ComputedRef of response data
25
+ * - `isEnabled`: ComputedRef indicating if query is enabled
26
+ * - `queryKey`: ComputedRef of the query key
27
+ * - `onLoad(callback)`: Register a callback for when data is loaded
24
28
  */
25
- export function useEndpointQuery(operationId, h, pathParamsOrOptions, optionsOrNull) {
29
+ export function useEndpointQuery(operationId, h, pathParams, options) {
26
30
  // Runtime check to ensure this is actually a query operation
27
31
  if (!h.isQueryOperation(operationId)) {
28
- throw new Error(`Operation ${String(operationId)} is not a query operation (GET/HEAD/OPTIONS)`);
32
+ const { method } = h.getOperationInfo(operationId);
33
+ throw new Error(`Operation '${String(operationId)}' uses method ${method} and cannot be used with useQuery(). ` +
34
+ `Use useMutation() for POST/PUT/PATCH/DELETE operations.`);
29
35
  }
30
36
  const { path, method } = h.getOperationInfo(operationId);
31
- const { pathParams, options } = getParamsOptionsFrom(path, pathParamsOrOptions, optionsOrNull);
32
- const { enabled: enabledInit, onLoad: onLoadInit, axiosOptions, errorHandler, queryParams, ...useQueryOptions } = options;
33
- // Make path parameters reactive by ensuring toValue is called inside computed
34
- // This ensures that when pathParams is a function, it gets called within the computed
35
- // so Vue can track dependencies of variables referenced inside the function
36
- const allPathParams = computed(() => {
37
- const result = toValue(pathParams);
38
- return result;
39
- });
40
- const resolvedPath = computed(() => resolvePath(path, allPathParams.value));
41
- // Make query parameters reactive
42
- const allQueryParams = computed(() => {
43
- const result = toValue(queryParams);
44
- return result;
45
- });
46
- // Include query params in the query key so changes trigger refetch
47
- const queryKey = computed(() => {
48
- const baseKey = generateQueryKey(resolvedPath.value);
49
- const qParams = allQueryParams.value;
50
- if (qParams && Object.keys(qParams).length > 0) {
51
- return [...baseKey, qParams];
52
- }
53
- return baseKey;
54
- });
37
+ const { pathParams: resolvedPathParamsInput, options: resolvedOptions } = normalizeParamsOptions(pathParams, options);
38
+ const { enabled: enabledInit, onLoad: onLoadInit, axiosOptions, errorHandler, queryParams, ...useQueryOptions } = resolvedOptions;
39
+ // Use the consolidated operation resolver
40
+ const { resolvedPath, queryKey, isResolved, queryParams: resolvedQueryParams, pathParams: resolvedPathParams, } = useResolvedOperation(path, resolvedPathParamsInput, queryParams);
55
41
  // Check if path is fully resolved for enabling the query
56
42
  const isEnabled = computed(() => {
57
43
  const baseEnabled = enabledInit !== undefined ? toValue(enabledInit) : true;
58
- return baseEnabled && isPathResolved(resolvedPath.value);
44
+ return baseEnabled && isResolved.value;
59
45
  });
60
- const query = useQuery({
61
- queryKey,
46
+ const queryOptions = {
47
+ queryKey: queryKey,
62
48
  queryFn: async () => {
63
49
  try {
64
50
  const response = await h.axios({
@@ -67,7 +53,7 @@ export function useEndpointQuery(operationId, h, pathParamsOrOptions, optionsOrN
67
53
  ...axiosOptions,
68
54
  params: {
69
55
  ...(axiosOptions?.params || {}),
70
- ...(allQueryParams.value || {}),
56
+ ...(resolvedQueryParams.value || {}),
71
57
  },
72
58
  });
73
59
  return response.data;
@@ -99,40 +85,49 @@ export function useEndpointQuery(operationId, h, pathParamsOrOptions, optionsOrN
99
85
  return _failureCount < 3;
100
86
  },
101
87
  ...useQueryOptions,
102
- }, h.queryClient);
103
- // onLoad callback is called once, as soon as data is available (immediately or when loading finishes)
104
- // Shared onLoad handler setup
105
- const setupOnLoadHandler = (callback) => {
106
- // If data is already available, call immediately
88
+ };
89
+ const query = useQuery(queryOptions, h.queryClient);
90
+ // onLoad callback management using a Set for efficient tracking
91
+ const onLoadCallbacks = new Set();
92
+ // Add initial callback from options if provided
93
+ if (onLoadInit) {
94
+ onLoadCallbacks.add(onLoadInit);
95
+ }
96
+ // Single watch instance to handle all callbacks - stop after first successful data
97
+ if (query.data.value !== undefined) {
98
+ // Data already available - call all callbacks immediately
99
+ onLoadCallbacks.forEach((cb) => cb(query.data.value));
100
+ onLoadCallbacks.clear();
101
+ }
102
+ else {
103
+ // Watch for data to become available - stop after first successful load
104
+ const stopWatch = watch(query.data, (newData) => {
105
+ if (newData !== undefined && onLoadCallbacks.size > 0) {
106
+ // Call all pending callbacks
107
+ onLoadCallbacks.forEach((cb) => cb(newData));
108
+ onLoadCallbacks.clear();
109
+ stopWatch(); // Stop watching after first successful load
110
+ }
111
+ });
112
+ }
113
+ // Public onLoad method to register additional callbacks
114
+ const onLoad = (callback) => {
107
115
  if (query.data.value !== undefined) {
116
+ // Data already available - call immediately
108
117
  callback(query.data.value);
109
118
  }
110
119
  else {
111
- // Watch for data to become available
112
- let hasLoaded = false;
113
- const stopWatch = watch(query.data, (newData) => {
114
- if (newData !== undefined && !hasLoaded) {
115
- hasLoaded = true;
116
- callback(newData);
117
- stopWatch(); // Stop watching after first load
118
- }
119
- });
120
+ // Add to pending callbacks
121
+ onLoadCallbacks.add(callback);
120
122
  }
121
123
  };
122
- // Handle onLoad callback from options
123
- if (onLoadInit) {
124
- setupOnLoadHandler(onLoadInit);
125
- }
126
- // Create onLoad method
127
- const onLoad = (callback) => {
128
- setupOnLoadHandler(callback);
129
- };
124
+ // Return object spread with data wrapped as ComputedRef for Vue template unwrapping
130
125
  return {
131
126
  ...query,
132
- data: query.data,
127
+ data: computed(() => query.data.value),
133
128
  isEnabled,
134
129
  queryKey,
135
130
  onLoad,
136
- pathParams: allPathParams,
131
+ pathParams: resolvedPathParams,
137
132
  };
138
133
  }
@@ -1,10 +1,36 @@
1
- import { type MaybeRefOrGetter } from 'vue';
2
- import { type GetPathParameters, type QMutationOptions, type QQueryOptions, Operations } from './types';
1
+ import { type ComputedRef, type MaybeRefOrGetter } from 'vue';
3
2
  export declare function resolvePath(path: string, pathParams?: MaybeRefOrGetter<Record<string, string | number | undefined> | null | undefined>): string;
4
3
  export declare function isPathResolved(path: string): boolean;
5
4
  export declare function generateQueryKey(resolvedPath: string): string[];
6
- export declare function getParamsOptionsFrom<Ops extends Operations<Ops>, Op extends keyof Ops, Options extends QMutationOptions<Ops, Op> | QQueryOptions<Ops, Op>>(path: string, pathParamsOrOptions?: MaybeRefOrGetter<GetPathParameters<Ops, Op> | null | undefined> | Options, optionsOrNull?: Options): {
7
- pathParams: MaybeRefOrGetter<GetPathParameters<Ops, Op> | null | undefined>;
5
+ /**
6
+ * Return type for useResolvedOperation composable
7
+ */
8
+ export interface ResolvedOperation<PathParams, QueryParams> {
9
+ /** Computed path parameters (resolved from reactive source) */
10
+ pathParams: ComputedRef<PathParams>;
11
+ /** Computed resolved path with parameters substituted */
12
+ resolvedPath: ComputedRef<string>;
13
+ /** Computed query parameters (resolved from reactive source) */
14
+ queryParams: ComputedRef<QueryParams>;
15
+ /** Computed query key for TanStack Query */
16
+ queryKey: ComputedRef<string[] | (string | QueryParams)[]>;
17
+ /** Whether the path is fully resolved (all params provided) */
18
+ isResolved: ComputedRef<boolean>;
19
+ }
20
+ /**
21
+ * Composable for resolving operation paths and parameters.
22
+ * Consolidates the common pattern of computing resolved paths, query keys, and parameters.
23
+ *
24
+ * @param path - The OpenAPI path template (e.g., '/pets/{petId}')
25
+ * @param pathParams - Reactive path parameters
26
+ * @param queryParams - Optional reactive query parameters
27
+ * @param extraPathParams - Optional ref for additional path params (used by mutations)
28
+ */
29
+ export declare function useResolvedOperation<PathParams extends Record<string, string | number | undefined> = Record<string, never>, QueryParams extends Record<string, unknown> = Record<string, never>>(path: string, pathParams: MaybeRefOrGetter<PathParams | null | undefined>, queryParams?: MaybeRefOrGetter<QueryParams | null | undefined>, extraPathParams?: {
30
+ value: Partial<PathParams>;
31
+ }): ResolvedOperation<PathParams, QueryParams>;
32
+ export declare function normalizeParamsOptions<PathParams extends Record<string, unknown>, Options>(pathParams?: MaybeRefOrGetter<PathParams | null | undefined>, options?: Options): {
33
+ pathParams: MaybeRefOrGetter<PathParams | null | undefined>;
8
34
  options: Options;
9
35
  };
10
36
  //# sourceMappingURL=openapi-utils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"openapi-utils.d.ts","sourceRoot":"","sources":["../src/openapi-utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAW,KAAK,gBAAgB,EAAE,MAAM,KAAK,CAAA;AACpD,OAAO,EAAE,KAAK,iBAAiB,EAAE,KAAK,gBAAgB,EAAE,KAAK,aAAa,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AA2BvG,wBAAgB,WAAW,CACzB,IAAI,EAAE,MAAM,EACZ,UAAU,CAAC,EAAE,gBAAgB,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC,GAAG,IAAI,GAAG,SAAS,CAAC,GAC5F,MAAM,CAaR;AAcD,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEpD;AAGD,wBAAgB,gBAAgB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,EAAE,CAE/D;AAED,wBAAgB,oBAAoB,CAClC,GAAG,SAAS,UAAU,CAAC,GAAG,CAAC,EAC3B,EAAE,SAAS,MAAM,GAAG,EACpB,OAAO,SAAS,gBAAgB,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,aAAa,CAAC,GAAG,EAAE,EAAE,CAAC,EAElE,IAAI,EAAE,MAAM,EACZ,mBAAmB,CAAC,EAAE,gBAAgB,CAAC,iBAAiB,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,IAAI,GAAG,SAAS,CAAC,GAAG,OAAO,EAC/F,aAAa,CAAC,EAAE,OAAO,GACtB;IACD,UAAU,EAAE,gBAAgB,CAAC,iBAAiB,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,IAAI,GAAG,SAAS,CAAC,CAAA;IAC3E,OAAO,EAAE,OAAO,CAAA;CACjB,CA+BA"}
1
+ {"version":3,"file":"openapi-utils.d.ts","sourceRoot":"","sources":["../src/openapi-utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqB,KAAK,WAAW,EAAE,KAAK,gBAAgB,EAAE,MAAM,KAAK,CAAA;AAGhF,wBAAgB,WAAW,CACzB,IAAI,EAAE,MAAM,EACZ,UAAU,CAAC,EAAE,gBAAgB,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC,GAAG,IAAI,GAAG,SAAS,CAAC,GAC5F,MAAM,CAaR;AAGD,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEpD;AAGD,wBAAgB,gBAAgB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,EAAE,CAE/D;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB,CAAC,UAAU,EAAE,WAAW;IACxD,+DAA+D;IAC/D,UAAU,EAAE,WAAW,CAAC,UAAU,CAAC,CAAA;IACnC,yDAAyD;IACzD,YAAY,EAAE,WAAW,CAAC,MAAM,CAAC,CAAA;IACjC,gEAAgE;IAChE,WAAW,EAAE,WAAW,CAAC,WAAW,CAAC,CAAA;IACrC,4CAA4C;IAC5C,QAAQ,EAAE,WAAW,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,GAAG,WAAW,CAAC,EAAE,CAAC,CAAA;IAC1D,+DAA+D;IAC/D,UAAU,EAAE,WAAW,CAAC,OAAO,CAAC,CAAA;CACjC;AAED;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAClC,UAAU,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,EACtF,WAAW,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,EAEnE,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,gBAAgB,CAAC,UAAU,GAAG,IAAI,GAAG,SAAS,CAAC,EAC3D,WAAW,CAAC,EAAE,gBAAgB,CAAC,WAAW,GAAG,IAAI,GAAG,SAAS,CAAC,EAC9D,eAAe,CAAC,EAAE;IAAE,KAAK,EAAE,OAAO,CAAC,UAAU,CAAC,CAAA;CAAE,GAC/C,iBAAiB,CAAC,UAAU,EAAE,WAAW,CAAC,CAuC5C;AAED,wBAAgB,sBAAsB,CAAC,UAAU,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,EACxF,UAAU,CAAC,EAAE,gBAAgB,CAAC,UAAU,GAAG,IAAI,GAAG,SAAS,CAAC,EAC5D,OAAO,CAAC,EAAE,OAAO,GAChB;IACD,UAAU,EAAE,gBAAgB,CAAC,UAAU,GAAG,IAAI,GAAG,SAAS,CAAC,CAAA;IAC3D,OAAO,EAAE,OAAO,CAAA;CACjB,CAKA"}