nuxt-openapi-hyperfetch 0.1.6-alpha.1 → 0.1.7-alpha.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.
package/dist/cli/logo.js CHANGED
@@ -1,11 +1,11 @@
1
1
  import gradient from 'gradient-string';
2
2
  const NUXT_LOGO = `███╗ ██╗██╗ ██╗██╗ ██╗████████╗
3
3
  ████╗ ██║██║ ██║╚██╗██╔╝╚══██╔══╝
4
- ██╔██╗ ██║██║ ██║ ╚███╔╝ ██║
5
- ██║╚██╗██║██║ ██║ ██╔██╗ ██║
6
- ██║ ╚████║╚██████╔╝██╔╝ ██╗ ██║
4
+ ██╔██╗ ██║██║ ██║ ╚███╔╝ ██║
5
+ ██║╚██╗██║██║ ██║ ██╔██╗ ██║
6
+ ██║ ╚████║╚██████╔╝██╔╝ ██╗ ██║
7
7
  ╚═╝ ╚═══╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝`;
8
- const SUBTITLE = ' Swagger OpenAPI Generator v1.0';
8
+ const SUBTITLE = 'Nuxt OpenAPI Generator - useFetch, useAsyncData & Nuxt server';
9
9
  /**
10
10
  * Display the Nuxt logo with gradient colors
11
11
  * - Green gradient for Nuxt logo (official Nuxt color #00DC82)
@@ -119,6 +119,23 @@ export interface ApiRequestOptions<T = any> {
119
119
  * pick: ['person.name', 'person.email', 'status']
120
120
  */
121
121
  pick?: ReadonlyArray<string>;
122
+ /**
123
+ * Custom cache key for useAsyncData. If provided, used as-is instead of the auto-generated key.
124
+ * Useful for manual cache control or sharing cache between components.
125
+ */
126
+ cacheKey?: string;
127
+ /** Base URL prepended to every request URL. Overrides runtimeConfig.public.apiBaseUrl. */
128
+ baseURL?: string;
129
+ /** HTTP method (GET, POST, PUT, PATCH, DELETE, etc.) */
130
+ method?: string;
131
+ /** Request body */
132
+ body?: any;
133
+ /** Request headers */
134
+ headers?: Record<string, string> | HeadersInit;
135
+ /** URL query parameters */
136
+ query?: Record<string, any>;
137
+ /** Alias for query */
138
+ params?: Record<string, any>;
122
139
  }
123
140
  /**
124
141
  * Helper function to apply request modifications from onRequest interceptor
@@ -9,9 +9,9 @@ import { getGlobalHeaders, getGlobalBaseUrl, applyPick, mergeCallbacks, } from '
9
9
  * - Watch pattern for reactive parameters
10
10
  */
11
11
  export function useApiAsyncData(key, url, options) {
12
- const { method = 'GET', body, headers = {}, params, transform, pick, onRequest, onSuccess, onError, onFinish, skipGlobalCallbacks, immediate = true, lazy = false, server = true, dedupe = 'cancel', watch: watchOption = true, ...restOptions } = options || {};
12
+ const { method = 'GET', body, headers = {}, params, baseURL, cacheKey, transform, pick, onRequest, onSuccess, onError, onFinish, skipGlobalCallbacks, immediate = true, lazy = false, server = true, dedupe = 'cancel', watch: watchOption = true, ...restOptions } = options || {};
13
13
  // Resolve base URL once at setup time (not inside fetchFn to avoid warning on every request)
14
- const resolvedBaseURL = restOptions.baseURL || getGlobalBaseUrl();
14
+ const resolvedBaseURL = baseURL || getGlobalBaseUrl();
15
15
  if (!resolvedBaseURL) {
16
16
  console.warn('[nuxt-openapi-hyperfetch] No baseURL configured. Set runtimeConfig.public.apiBaseUrl in nuxt.config.ts or pass baseURL in options.');
17
17
  }
@@ -30,6 +30,18 @@ export function useApiAsyncData(key, url, options) {
30
30
  : []
31
31
  : []),
32
32
  ];
33
+ // Build a reactive cache key: composableName + resolved URL + serialized query params
34
+ // This ensures distinct params produce distinct keys — preventing cache collisions
35
+ const computedKey = () => {
36
+ if (cacheKey)
37
+ return cacheKey;
38
+ const resolvedUrl = typeof url === 'function' ? url() : url;
39
+ const resolvedParams = toValue(params);
40
+ const paramsSuffix = resolvedParams && typeof resolvedParams === 'object' && Object.keys(resolvedParams).length > 0
41
+ ? '-' + JSON.stringify(resolvedParams)
42
+ : '';
43
+ return `${key}-${resolvedUrl}${paramsSuffix}`;
44
+ };
33
45
  // Fetch function for useAsyncData
34
46
  const fetchFn = async () => {
35
47
  // Get URL value for merging callbacks
@@ -116,13 +128,13 @@ export function useApiAsyncData(key, url, options) {
116
128
  }
117
129
  }
118
130
  };
119
- // Use Nuxt's useAsyncData
120
- const result = useAsyncData(key, fetchFn, {
131
+ // Use Nuxt's useAsyncData with a computed key for proper cache isolation per params
132
+ const result = useAsyncData(computedKey, fetchFn, {
121
133
  immediate,
122
134
  lazy,
123
135
  server,
124
136
  dedupe,
125
- watch: watchSources.length > 0 ? watchSources : undefined,
137
+ watch: watchOption === false ? [] : watchSources,
126
138
  });
127
139
  return result;
128
140
  }
@@ -12,9 +12,9 @@ import { getGlobalHeaders, getGlobalBaseUrl, applyPick, mergeCallbacks, } from '
12
12
  * - Watch pattern for reactive parameters
13
13
  */
14
14
  export function useApiAsyncDataRaw(key, url, options) {
15
- const { method = 'GET', body, headers = {}, params, transform, pick, onRequest, onSuccess, onError, onFinish, skipGlobalCallbacks, immediate = true, lazy = false, server = true, dedupe = 'cancel', ...restOptions } = options || {};
15
+ const { method = 'GET', body, headers = {}, params, baseURL, cacheKey, transform, pick, onRequest, onSuccess, onError, onFinish, skipGlobalCallbacks, immediate = true, lazy = false, server = true, dedupe = 'cancel', ...restOptions } = options || {};
16
16
  // Resolve base URL once at setup time (not inside fetchFn to avoid warning on every request)
17
- const resolvedBaseURL = restOptions.baseURL || getGlobalBaseUrl();
17
+ const resolvedBaseURL = baseURL || getGlobalBaseUrl();
18
18
  if (!resolvedBaseURL) {
19
19
  console.warn('[nuxt-openapi-hyperfetch] No baseURL configured. Set runtimeConfig.public.apiBaseUrl in nuxt.config.ts or pass baseURL in options.');
20
20
  }
@@ -24,6 +24,18 @@ export function useApiAsyncDataRaw(key, url, options) {
24
24
  ...(body && typeof body === 'object' ? [() => body] : []),
25
25
  ...(params && typeof params === 'object' ? [() => params] : []),
26
26
  ];
27
+ // Build a reactive cache key: composableName + resolved URL + serialized query params
28
+ // This ensures distinct params produce distinct keys — preventing cache collisions
29
+ const computedKey = () => {
30
+ if (cacheKey)
31
+ return cacheKey;
32
+ const resolvedUrl = typeof url === 'function' ? url() : url;
33
+ const resolvedParams = toValue(params);
34
+ const paramsSuffix = resolvedParams && typeof resolvedParams === 'object' && Object.keys(resolvedParams).length > 0
35
+ ? '-' + JSON.stringify(resolvedParams)
36
+ : '';
37
+ return `${key}-${resolvedUrl}${paramsSuffix}`;
38
+ };
27
39
  // Fetch function for useAsyncData
28
40
  const fetchFn = async () => {
29
41
  // Get URL value for merging callbacks
@@ -120,8 +132,8 @@ export function useApiAsyncDataRaw(key, url, options) {
120
132
  }
121
133
  }
122
134
  };
123
- // Use Nuxt's useAsyncData
124
- const result = useAsyncData(key, fetchFn, {
135
+ // Use Nuxt's useAsyncData with a computed key for proper cache isolation per params
136
+ const result = useAsyncData(computedKey, fetchFn, {
125
137
  immediate,
126
138
  lazy,
127
139
  server,
@@ -117,7 +117,13 @@ function generateFunctionBody(method, isRaw, generateOptions) {
117
117
  // Choose the correct wrapper function
118
118
  const wrapperFunction = isRaw ? 'useApiAsyncDataRaw' : 'useApiAsyncData';
119
119
  const pInit = hasParams ? `\n const p = shallowRef(params)` : '';
120
- return `${description}export const ${composableName} = (${args}) => {${pInit}
120
+ const argsExtraction = hasParams
121
+ ? ` 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]`
122
+ : ` const _hasKey = typeof args[0] === 'string'\n const options = _hasKey ? { cacheKey: args[0], ...args[1] } : args[0]`;
123
+ return `${description}export function ${composableName}(key: string, ${args})
124
+ export function ${composableName}(${args})
125
+ export function ${composableName}(...args: any[]) {
126
+ ${argsExtraction}${pInit}
121
127
  return ${wrapperFunction}${responseTypeGeneric}(${key}, ${url}, ${fetchOptions})
122
128
  }`;
123
129
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nuxt-openapi-hyperfetch",
3
- "version": "0.1.6-alpha.1",
3
+ "version": "0.1.7-alpha.1",
4
4
  "description": "Nuxt useFetch, useAsyncData and Nuxt server OpenAPI generator",
5
5
  "type": "module",
6
6
  "author": "",
package/src/cli/logo.ts CHANGED
@@ -2,12 +2,12 @@ import gradient from 'gradient-string';
2
2
 
3
3
  const NUXT_LOGO = `███╗ ██╗██╗ ██╗██╗ ██╗████████╗
4
4
  ████╗ ██║██║ ██║╚██╗██╔╝╚══██╔══╝
5
- ██╔██╗ ██║██║ ██║ ╚███╔╝ ██║
6
- ██║╚██╗██║██║ ██║ ██╔██╗ ██║
7
- ██║ ╚████║╚██████╔╝██╔╝ ██╗ ██║
5
+ ██╔██╗ ██║██║ ██║ ╚███╔╝ ██║
6
+ ██║╚██╗██║██║ ██║ ██╔██╗ ██║
7
+ ██║ ╚████║╚██████╔╝██╔╝ ██╗ ██║
8
8
  ╚═╝ ╚═══╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝`;
9
9
 
10
- const SUBTITLE = ' Swagger OpenAPI Generator v1.0';
10
+ const SUBTITLE = 'Nuxt OpenAPI Generator - useFetch, useAsyncData & Nuxt server';
11
11
 
12
12
  /**
13
13
  * Display the Nuxt logo with gradient colors
@@ -148,6 +148,32 @@ export interface ApiRequestOptions<T = any> {
148
148
  * pick: ['person.name', 'person.email', 'status']
149
149
  */
150
150
  pick?: ReadonlyArray<string>;
151
+
152
+ /**
153
+ * Custom cache key for useAsyncData. If provided, used as-is instead of the auto-generated key.
154
+ * Useful for manual cache control or sharing cache between components.
155
+ */
156
+ cacheKey?: string;
157
+
158
+ // --- Common fetch options (available in all composables) ---
159
+
160
+ /** Base URL prepended to every request URL. Overrides runtimeConfig.public.apiBaseUrl. */
161
+ baseURL?: string;
162
+
163
+ /** HTTP method (GET, POST, PUT, PATCH, DELETE, etc.) */
164
+ method?: string;
165
+
166
+ /** Request body */
167
+ body?: any;
168
+
169
+ /** Request headers */
170
+ headers?: Record<string, string> | HeadersInit;
171
+
172
+ /** URL query parameters */
173
+ query?: Record<string, any>;
174
+
175
+ /** Alias for query */
176
+ params?: Record<string, any>;
151
177
  }
152
178
 
153
179
  /**
@@ -63,6 +63,8 @@ export function useApiAsyncData<T>(
63
63
  body,
64
64
  headers = {},
65
65
  params,
66
+ baseURL,
67
+ cacheKey,
66
68
  transform,
67
69
  pick,
68
70
  onRequest,
@@ -79,7 +81,7 @@ export function useApiAsyncData<T>(
79
81
  } = options || {};
80
82
 
81
83
  // Resolve base URL once at setup time (not inside fetchFn to avoid warning on every request)
82
- const resolvedBaseURL = restOptions.baseURL || getGlobalBaseUrl();
84
+ const resolvedBaseURL = baseURL || getGlobalBaseUrl();
83
85
  if (!resolvedBaseURL) {
84
86
  console.warn(
85
87
  '[nuxt-openapi-hyperfetch] No baseURL configured. Set runtimeConfig.public.apiBaseUrl in nuxt.config.ts or pass baseURL in options.'
@@ -103,6 +105,19 @@ export function useApiAsyncData<T>(
103
105
  : []),
104
106
  ];
105
107
 
108
+ // Build a reactive cache key: composableName + resolved URL + serialized query params
109
+ // This ensures distinct params produce distinct keys — preventing cache collisions
110
+ const computedKey = () => {
111
+ if (cacheKey) return cacheKey;
112
+ const resolvedUrl = typeof url === 'function' ? url() : url;
113
+ const resolvedParams = toValue(params);
114
+ const paramsSuffix =
115
+ resolvedParams && typeof resolvedParams === 'object' && Object.keys(resolvedParams).length > 0
116
+ ? '-' + JSON.stringify(resolvedParams)
117
+ : '';
118
+ return `${key}-${resolvedUrl}${paramsSuffix}`;
119
+ };
120
+
106
121
  // Fetch function for useAsyncData
107
122
  const fetchFn = async () => {
108
123
  // Get URL value for merging callbacks
@@ -201,13 +216,13 @@ export function useApiAsyncData<T>(
201
216
  }
202
217
  };
203
218
 
204
- // Use Nuxt's useAsyncData
205
- const result = useAsyncData<MaybeTransformed<T, ApiAsyncDataOptions<T>>>(key, fetchFn, {
219
+ // Use Nuxt's useAsyncData with a computed key for proper cache isolation per params
220
+ const result = useAsyncData<MaybeTransformed<T, ApiAsyncDataOptions<T>>>(computedKey, fetchFn, {
206
221
  immediate,
207
222
  lazy,
208
223
  server,
209
224
  dedupe,
210
- watch: watchSources.length > 0 ? watchSources : undefined,
225
+ watch: watchOption === false ? [] : watchSources,
211
226
  });
212
227
 
213
228
  return result;
@@ -78,6 +78,8 @@ export function useApiAsyncDataRaw<T>(
78
78
  body,
79
79
  headers = {},
80
80
  params,
81
+ baseURL,
82
+ cacheKey,
81
83
  transform,
82
84
  pick,
83
85
  onRequest,
@@ -93,7 +95,7 @@ export function useApiAsyncDataRaw<T>(
93
95
  } = options || {};
94
96
 
95
97
  // Resolve base URL once at setup time (not inside fetchFn to avoid warning on every request)
96
- const resolvedBaseURL = restOptions.baseURL || getGlobalBaseUrl();
98
+ const resolvedBaseURL = baseURL || getGlobalBaseUrl();
97
99
  if (!resolvedBaseURL) {
98
100
  console.warn(
99
101
  '[nuxt-openapi-hyperfetch] No baseURL configured. Set runtimeConfig.public.apiBaseUrl in nuxt.config.ts or pass baseURL in options.'
@@ -107,6 +109,19 @@ export function useApiAsyncDataRaw<T>(
107
109
  ...(params && typeof params === 'object' ? [() => params] : []),
108
110
  ];
109
111
 
112
+ // Build a reactive cache key: composableName + resolved URL + serialized query params
113
+ // This ensures distinct params produce distinct keys — preventing cache collisions
114
+ const computedKey = () => {
115
+ if (cacheKey) return cacheKey;
116
+ const resolvedUrl = typeof url === 'function' ? url() : url;
117
+ const resolvedParams = toValue(params);
118
+ const paramsSuffix =
119
+ resolvedParams && typeof resolvedParams === 'object' && Object.keys(resolvedParams).length > 0
120
+ ? '-' + JSON.stringify(resolvedParams)
121
+ : '';
122
+ return `${key}-${resolvedUrl}${paramsSuffix}`;
123
+ };
124
+
110
125
  // Fetch function for useAsyncData
111
126
  const fetchFn = async (): Promise<RawResponse<T>> => {
112
127
  // Get URL value for merging callbacks
@@ -217,8 +232,8 @@ export function useApiAsyncDataRaw<T>(
217
232
  }
218
233
  };
219
234
 
220
- // Use Nuxt's useAsyncData
221
- const result = useAsyncData<MaybeTransformedRaw<T, ApiAsyncDataRawOptions<T>>>(key, fetchFn, {
235
+ // Use Nuxt's useAsyncData with a computed key for proper cache isolation per params
236
+ const result = useAsyncData<MaybeTransformedRaw<T, ApiAsyncDataRawOptions<T>>>(computedKey, fetchFn, {
222
237
  immediate,
223
238
  lazy,
224
239
  server,
@@ -165,7 +165,14 @@ function generateFunctionBody(
165
165
 
166
166
  const pInit = hasParams ? `\n const p = shallowRef(params)` : '';
167
167
 
168
- return `${description}export const ${composableName} = (${args}) => {${pInit}
168
+ const argsExtraction = hasParams
169
+ ? ` 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
+ : ` const _hasKey = typeof args[0] === 'string'\n const options = _hasKey ? { cacheKey: args[0], ...args[1] } : args[0]`;
171
+
172
+ return `${description}export function ${composableName}(key: string, ${args})
173
+ export function ${composableName}(${args})
174
+ export function ${composableName}(...args: any[]) {
175
+ ${argsExtraction}${pInit}
169
176
  return ${wrapperFunction}${responseTypeGeneric}(${key}, ${url}, ${fetchOptions})
170
177
  }`;
171
178
  }