nuxt-openapi-hyperfetch 0.3.0-beta → 0.3.1-beta

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.
@@ -136,17 +136,18 @@ function generateFunctionBody(
136
136
  ): string {
137
137
  const hasParams = !!method.requestType;
138
138
  const paramsArg = hasParams ? `params: ${method.requestType}` : '';
139
+ const responseType = method.responseType !== 'void' ? method.responseType : 'void';
139
140
 
140
141
  // Determine the options type based on isRaw
141
142
  const optionsType = isRaw
142
- ? `ApiAsyncDataRawOptions<${method.responseType}>`
143
- : `ApiAsyncDataOptions<${method.responseType}>`;
144
- const optionsArg = `options?: ${optionsType}`;
143
+ ? `ApiAsyncDataRawOptions<${responseType}, DataT, PickT>`
144
+ : `ApiAsyncDataOptions<${responseType}, DataT, PickT>`;
145
+ const optionsDefaultType = isRaw
146
+ ? `ApiAsyncDataRawOptions<${responseType}, DataT, PickT>`
147
+ : `ApiAsyncDataOptions<${responseType}, DataT, PickT>`;
148
+ const optionsArg = `options?: Options`;
145
149
  const args = hasParams ? `${paramsArg}, ${optionsArg}` : optionsArg;
146
150
 
147
- // Determine the response type generic
148
- const responseTypeGeneric = method.responseType !== 'void' ? `<${method.responseType}>` : '';
149
-
150
151
  // Generate unique key for useAsyncData
151
152
  const composableName =
152
153
  isRaw && method.rawMethodName
@@ -162,6 +163,12 @@ function generateFunctionBody(
162
163
 
163
164
  // Choose the correct wrapper function
164
165
  const wrapperFunction = isRaw ? 'useApiAsyncDataRaw' : 'useApiAsyncData';
166
+ const wrapperCall = isRaw
167
+ ? `${wrapperFunction}<${responseType}, DataT, PickT, Options>`
168
+ : `${wrapperFunction}<${responseType}, Options>`;
169
+ const returnType = isRaw
170
+ ? `ReturnType<typeof ${wrapperFunction}<${responseType}, DataT, PickT, Options>>`
171
+ : `ReturnType<typeof ${wrapperFunction}<${responseType}, Options>>`;
165
172
 
166
173
  const pInit = hasParams ? `\n const p = shallowRef(params)` : '';
167
174
 
@@ -169,11 +176,19 @@ function generateFunctionBody(
169
176
  ? ` const _hasKey = typeof args[0] === 'string'\n const params = _hasKey ? args[1] : args[0]\n const options = _hasKey ? { cacheKey: args[0], ...args[2] } : args[1]`
170
177
  : ` const _hasKey = typeof args[0] === 'string'\n const options = _hasKey ? { cacheKey: args[0], ...args[1] } : args[0]`;
171
178
 
172
- return `${description}export function ${composableName}(key: string, ${args})
173
- export function ${composableName}(${args})
179
+ return `${description}export function ${composableName}<
180
+ DataT = ${responseType},
181
+ PickT extends ReadonlyArray<string> | undefined = undefined,
182
+ Options extends ${optionsType} = ${optionsDefaultType}
183
+ >(key: string, ${args}): ${returnType}
184
+ export function ${composableName}<
185
+ DataT = ${responseType},
186
+ PickT extends ReadonlyArray<string> | undefined = undefined,
187
+ Options extends ${optionsType} = ${optionsDefaultType}
188
+ >(${args}): ${returnType}
174
189
  export function ${composableName}(...args: any[]) {
175
190
  ${argsExtraction}${pInit}
176
- return ${wrapperFunction}${responseTypeGeneric}(${key}, ${url}, ${fetchOptions})
191
+ return ${wrapperCall}(${key}, ${url}, ${fetchOptions})
177
192
  }`;
178
193
  }
179
194
 
@@ -37,12 +37,39 @@ type MaybeTransformed<T, Options> = Options extends { transform: (...args: any)
37
37
  ? any // With nested paths, type inference is complex, so we use any
38
38
  : T;
39
39
 
40
+ type PickInput = ReadonlyArray<string> | undefined;
41
+
42
+ type HasNestedPath<K extends ReadonlyArray<string>> =
43
+ Extract<K[number], `${string}.${string}`> extends never ? false : true;
44
+
45
+ type PickedData<T, K extends PickInput> = K extends ReadonlyArray<string>
46
+ ? HasNestedPath<K> extends true
47
+ ? any
48
+ : Pick<T, Extract<K[number], keyof T>>
49
+ : T;
50
+
51
+ type InferPick<Options> = Options extends { pick: infer K extends ReadonlyArray<string> }
52
+ ? K
53
+ : undefined;
54
+
55
+ type InferData<T, Options> = Options extends { transform: (...args: any) => infer R }
56
+ ? R
57
+ : PickedData<T, InferPick<Options>>;
58
+
40
59
  /**
41
60
  * Options for useFetch API requests with lifecycle callbacks.
42
61
  * Extends all native Nuxt useFetch options plus our custom callbacks, transform, and pick.
43
62
  * Native options like baseURL, method, body, headers, query, lazy, server, immediate, etc. are all available.
44
63
  */
45
- export type ApiRequestOptions<T = any> = BaseApiRequestOptions<T> & Omit<UseFetchOptions<T>, 'transform' | 'pick'>;
64
+ export type ApiRequestOptions<
65
+ T = any,
66
+ DataT = T,
67
+ PickT extends PickInput = undefined,
68
+ > = Omit<BaseApiRequestOptions<T>, 'transform' | 'pick'> &
69
+ Omit<UseFetchOptions<T, DataT>, 'transform' | 'pick'> & {
70
+ pick?: PickT;
71
+ transform?: (data: PickedData<T, PickT>) => DataT;
72
+ };
46
73
 
47
74
  /**
48
75
  * Enhanced useFetch wrapper with lifecycle callbacks and request interception
@@ -80,7 +107,10 @@ export type ApiRequestOptions<T = any> = BaseApiRequestOptions<T> & Omit<UseFetc
80
107
  * });
81
108
  * ```
82
109
  */
83
- export function useApiRequest<T = any, Options extends ApiRequestOptions<T> = ApiRequestOptions<T>>(
110
+ export function useApiRequest<
111
+ T = any,
112
+ Options extends ApiRequestOptions<T, any, any> = ApiRequestOptions<T>,
113
+ >(
84
114
  url: string | (() => string),
85
115
  options?: Options
86
116
  ) {
@@ -224,10 +254,10 @@ export function useApiRequest<T = any, Options extends ApiRequestOptions<T> = Ap
224
254
  }
225
255
 
226
256
  // Make the actual request using Nuxt's useFetch
227
- const result = useFetch<T>(url, modifiedOptions);
257
+ const result = useFetch<T>(url, modifiedOptions as UseFetchOptions<T, InferData<T, Options>>);
228
258
 
229
259
  // Create a ref for transformed data
230
- type TransformedType = MaybeTransformed<T, Options>;
260
+ type TransformedType = InferData<T, Options>;
231
261
  const transformedData = ref<TransformedType | null>(null);
232
262
 
233
263
  // Track if callbacks have been executed to avoid duplicates
@@ -116,12 +116,11 @@ function generateImports(method: MethodInfo, apiImportPath: string): string {
116
116
  function generateFunctionBody(method: MethodInfo, options?: GenerateOptions): string {
117
117
  const hasParams = !!method.requestType;
118
118
  const paramsArg = hasParams ? `params: ${method.requestType}` : '';
119
- const optionsType = `ApiRequestOptions<${method.responseType}>`;
120
- const optionsArg = `options?: ${optionsType}`;
119
+ const responseType = method.responseType !== 'void' ? method.responseType : 'void';
120
+ const optionsType = `ApiRequestOptions<${responseType}, DataT, PickT>`;
121
+ const optionsArg = `options?: Options`;
121
122
  const args = hasParams ? `${paramsArg}, ${optionsArg}` : optionsArg;
122
123
 
123
- const responseTypeGeneric = method.responseType !== 'void' ? `<${method.responseType}>` : '';
124
-
125
124
  const url = generateUrl(method);
126
125
  const fetchOptions = generateFetchOptions(method, options);
127
126
 
@@ -129,8 +128,12 @@ function generateFunctionBody(method: MethodInfo, options?: GenerateOptions): st
129
128
 
130
129
  const pInit = hasParams ? `\n const p = shallowRef(params)` : '';
131
130
 
132
- return `${description}export const ${method.composableName} = (${args}) => {${pInit}
133
- return useApiRequest${responseTypeGeneric}(${url}, ${fetchOptions})
131
+ return `${description}export const ${method.composableName} = <
132
+ DataT = ${responseType},
133
+ PickT extends ReadonlyArray<string> | undefined = undefined,
134
+ Options extends ${optionsType} = ApiRequestOptions<${responseType}, DataT, PickT>
135
+ >(${args}) => {${pInit}
136
+ return useApiRequest<${responseType}, Options>(${url}, ${fetchOptions})
134
137
  }`;
135
138
  }
136
139