nuxt-openapi-hyperfetch 0.1.2-alpha.1 → 0.1.5-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/README.md CHANGED
@@ -106,7 +106,29 @@ api/
106
106
  +-- index.ts
107
107
  ```
108
108
 
109
- ### 3. Use in your Nuxt app
109
+ ### 3. Configure the API base URL
110
+
111
+ Add to `nuxt.config.ts`:
112
+
113
+ ```typescript
114
+ export default defineNuxtConfig({
115
+ runtimeConfig: {
116
+ public: {
117
+ apiBaseUrl: process.env.NUXT_PUBLIC_API_BASE_URL || 'https://api.example.com'
118
+ }
119
+ }
120
+ })
121
+ ```
122
+
123
+ And in `.env`:
124
+
125
+ ```env
126
+ NUXT_PUBLIC_API_BASE_URL=https://api.example.com
127
+ ```
128
+
129
+ All generated `useFetch` and `useAsyncData` composables will automatically use this as `baseURL`. You can still override it per-composable via `options.baseURL`.
130
+
131
+ ### 4. Use in your Nuxt app
110
132
 
111
133
  ```vue
112
134
  <script setup lang="ts">
@@ -152,12 +174,15 @@ And add it to `nuxt.config.ts`:
152
174
  ```typescript
153
175
  export default defineNuxtConfig({
154
176
  runtimeConfig: {
177
+ // Private — server-side only (never exposed to the browser)
155
178
  apiBaseUrl: process.env.API_BASE_URL || '',
156
179
  apiSecret: process.env.API_SECRET || '',
157
180
  },
158
181
  });
159
182
  ```
160
183
 
184
+ > **Note:** `runtimeConfig.apiBaseUrl` (private) is only for **Server Routes**. For `useFetch`/`useAsyncData` composables use `runtimeConfig.public.apiBaseUrl` instead — see the [Quick Start](#-quick-start) section above.
185
+
161
186
  Then use standard `useFetch` against your Nuxt routes:
162
187
 
163
188
  ```typescript
@@ -141,6 +141,11 @@ export declare function getGlobalHeaders(): Record<string, string>;
141
141
  * Uses Nuxt plugin provide: plugins/api-callbacks.ts with $getGlobalApiCallbacks
142
142
  */
143
143
  export declare function getGlobalCallbacks(): GlobalCallbacksConfig;
144
+ /**
145
+ * Helper function to get the global base URL from runtimeConfig.public.apiBaseUrl
146
+ * Returns the configured URL or undefined if not set or not in a Nuxt context.
147
+ */
148
+ export declare function getGlobalBaseUrl(): string | undefined;
144
149
  /**
145
150
  * Check if a global callback should be applied to a specific request
146
151
  * Implements Opción 1 (skipGlobalCallbacks) and Opción 3 (pattern matching)
@@ -121,6 +121,21 @@ export function getGlobalCallbacks() {
121
121
  }
122
122
  return {};
123
123
  }
124
+ /**
125
+ * Helper function to get the global base URL from runtimeConfig.public.apiBaseUrl
126
+ * Returns the configured URL or undefined if not set or not in a Nuxt context.
127
+ */
128
+ export function getGlobalBaseUrl() {
129
+ try {
130
+ const runtimeConfig = useRuntimeConfig();
131
+ const url = runtimeConfig?.public?.apiBaseUrl;
132
+ return url || undefined;
133
+ }
134
+ catch {
135
+ // useRuntimeConfig not available outside Nuxt context, that's OK
136
+ return undefined;
137
+ }
138
+ }
124
139
  /**
125
140
  * Check if a global callback should be applied to a specific request
126
141
  * Implements Opción 1 (skipGlobalCallbacks) and Opción 3 (pattern matching)
@@ -1,4 +1,4 @@
1
- import { getGlobalHeaders, applyPick, mergeCallbacks, } from '../../shared/runtime/apiHelpers.js';
1
+ import { getGlobalHeaders, getGlobalBaseUrl, applyPick, mergeCallbacks, } from '../../shared/runtime/apiHelpers.js';
2
2
  /**
3
3
  * Generic wrapper for API calls using Nuxt's useAsyncData
4
4
  * Supports:
@@ -10,6 +10,11 @@ import { getGlobalHeaders, applyPick, mergeCallbacks, } from '../../shared/runti
10
10
  */
11
11
  export function useApiAsyncData(key, url, options) {
12
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 || {};
13
+ // Resolve base URL once at setup time (not inside fetchFn to avoid warning on every request)
14
+ const resolvedBaseURL = restOptions.baseURL || getGlobalBaseUrl();
15
+ if (!resolvedBaseURL) {
16
+ console.warn('[nuxt-openapi-hyperfetch] No baseURL configured. Set runtimeConfig.public.apiBaseUrl in nuxt.config.ts or pass baseURL in options.');
17
+ }
13
18
  // Create reactive watch sources — use refs/computeds directly so Vue can track them
14
19
  // watchOption: false disables auto-refresh entirely
15
20
  const watchSources = watchOption === false
@@ -72,6 +77,7 @@ export function useApiAsyncData(key, url, options) {
72
77
  headers: modifiedContext.headers,
73
78
  body: toValue(modifiedContext.body),
74
79
  params: toValue(modifiedContext.params),
80
+ ...(resolvedBaseURL ? { baseURL: resolvedBaseURL } : {}),
75
81
  ...restOptions,
76
82
  });
77
83
  // Apply pick if provided
@@ -1,4 +1,4 @@
1
- import { getGlobalHeaders, applyPick, mergeCallbacks, } from '../../shared/runtime/apiHelpers.js';
1
+ import { getGlobalHeaders, getGlobalBaseUrl, applyPick, mergeCallbacks, } from '../../shared/runtime/apiHelpers.js';
2
2
  /**
3
3
  * Generic wrapper for API calls using Nuxt's useAsyncData - RAW VERSION
4
4
  * Returns full response with headers and status information
@@ -13,6 +13,11 @@ import { getGlobalHeaders, applyPick, mergeCallbacks, } from '../../shared/runti
13
13
  */
14
14
  export function useApiAsyncDataRaw(key, url, options) {
15
15
  const { method = 'GET', body, headers = {}, params, transform, pick, onRequest, onSuccess, onError, onFinish, skipGlobalCallbacks, immediate = true, lazy = false, server = true, dedupe = 'cancel', ...restOptions } = options || {};
16
+ // Resolve base URL once at setup time (not inside fetchFn to avoid warning on every request)
17
+ const resolvedBaseURL = restOptions.baseURL || getGlobalBaseUrl();
18
+ if (!resolvedBaseURL) {
19
+ console.warn('[nuxt-openapi-hyperfetch] No baseURL configured. Set runtimeConfig.public.apiBaseUrl in nuxt.config.ts or pass baseURL in options.');
20
+ }
16
21
  // Create reactive watch sources for callbacks
17
22
  const watchSources = [
18
23
  ...(typeof url === 'function' ? [url] : []),
@@ -66,6 +71,7 @@ export function useApiAsyncDataRaw(key, url, options) {
66
71
  headers: modifiedContext.headers,
67
72
  body: modifiedContext.body,
68
73
  params: modifiedContext.params,
74
+ ...(resolvedBaseURL ? { baseURL: resolvedBaseURL } : {}),
69
75
  ...restOptions,
70
76
  });
71
77
  // Extract data from response
@@ -4,7 +4,7 @@
4
4
  * It requires Nuxt 3 to be installed in the target project
5
5
  */
6
6
  import { watch } from 'vue';
7
- import { getGlobalHeaders, applyPick, applyRequestModifications, mergeCallbacks, } from '../../shared/runtime/apiHelpers.js';
7
+ import { getGlobalHeaders, getGlobalBaseUrl, applyPick, applyRequestModifications, mergeCallbacks, } from '../../shared/runtime/apiHelpers.js';
8
8
  /**
9
9
  * Enhanced useFetch wrapper with lifecycle callbacks and request interception
10
10
  *
@@ -63,6 +63,13 @@ export function useApiRequest(url, options) {
63
63
  ...modifiedOptions.headers, // User headers override global headers
64
64
  };
65
65
  }
66
+ // Apply global base URL from runtimeConfig.public.apiBaseUrl (if not already set per-composable)
67
+ if (!modifiedOptions.baseURL) {
68
+ modifiedOptions.baseURL = getGlobalBaseUrl();
69
+ }
70
+ if (!modifiedOptions.baseURL) {
71
+ console.warn('[nuxt-openapi-hyperfetch] No baseURL configured. Set runtimeConfig.public.apiBaseUrl in nuxt.config.ts or pass baseURL in options.');
72
+ }
66
73
  // Execute merged onRequest interceptor and apply modifications
67
74
  if (mergedCallbacks.onRequest) {
68
75
  try {
@@ -95,7 +102,8 @@ export function useApiRequest(url, options) {
95
102
  let successExecuted = false;
96
103
  let errorExecuted = false;
97
104
  // Watch for changes in data, error, and pending states
98
- watch(() => [result.data.value, result.error.value, result.pending.value], async ([data, error, pending], [prevData, prevError, prevPending]) => {
105
+ watch(() => [result.data.value, result.error.value, result.pending.value], async ([data, error, pending], prev) => {
106
+ const [prevData, prevError, prevPending] = prev ?? [undefined, undefined, undefined];
99
107
  // Apply transformations when data arrives
100
108
  if (data && data !== prevData) {
101
109
  let processedData = data;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nuxt-openapi-hyperfetch",
3
- "version": "0.1.2-alpha.1",
3
+ "version": "0.1.5-alpha.1",
4
4
  "description": "Nuxt useFetch, useAsyncData and Nuxt server OpenAPI generator",
5
5
  "type": "module",
6
6
  "author": "",
@@ -280,6 +280,21 @@ export function getGlobalCallbacks(): GlobalCallbacksConfig {
280
280
  return {};
281
281
  }
282
282
 
283
+ /**
284
+ * Helper function to get the global base URL from runtimeConfig.public.apiBaseUrl
285
+ * Returns the configured URL or undefined if not set or not in a Nuxt context.
286
+ */
287
+ export function getGlobalBaseUrl(): string | undefined {
288
+ try {
289
+ const runtimeConfig = useRuntimeConfig();
290
+ const url = runtimeConfig?.public?.apiBaseUrl as string | undefined;
291
+ return url || undefined;
292
+ } catch {
293
+ // useRuntimeConfig not available outside Nuxt context, that's OK
294
+ return undefined;
295
+ }
296
+ }
297
+
283
298
  /**
284
299
  * Check if a global callback should be applied to a specific request
285
300
  * Implements Opción 1 (skipGlobalCallbacks) and Opción 3 (pattern matching)
@@ -6,6 +6,7 @@
6
6
  import { watch } from 'vue';
7
7
  import {
8
8
  getGlobalHeaders,
9
+ getGlobalBaseUrl,
9
10
  applyPick,
10
11
  applyRequestModifications,
11
12
  mergeCallbacks,
@@ -93,6 +94,14 @@ export function useApiAsyncData<T>(
93
94
  ...restOptions
94
95
  } = options || {};
95
96
 
97
+ // Resolve base URL once at setup time (not inside fetchFn to avoid warning on every request)
98
+ const resolvedBaseURL = restOptions.baseURL || getGlobalBaseUrl();
99
+ if (!resolvedBaseURL) {
100
+ console.warn(
101
+ '[nuxt-openapi-hyperfetch] No baseURL configured. Set runtimeConfig.public.apiBaseUrl in nuxt.config.ts or pass baseURL in options.'
102
+ );
103
+ }
104
+
96
105
  // Create reactive watch sources — use refs/computeds directly so Vue can track them
97
106
  // watchOption: false disables auto-refresh entirely
98
107
  const watchSources =
@@ -166,6 +175,7 @@ export function useApiAsyncData<T>(
166
175
  headers: modifiedContext.headers,
167
176
  body: toValue(modifiedContext.body),
168
177
  params: toValue(modifiedContext.params),
178
+ ...(resolvedBaseURL ? { baseURL: resolvedBaseURL } : {}),
169
179
  ...restOptions,
170
180
  });
171
181
 
@@ -8,6 +8,7 @@
8
8
  import { watch } from 'vue';
9
9
  import {
10
10
  getGlobalHeaders,
11
+ getGlobalBaseUrl,
11
12
  applyPick,
12
13
  applyRequestModifications,
13
14
  mergeCallbacks,
@@ -107,6 +108,14 @@ export function useApiAsyncDataRaw<T>(
107
108
  ...restOptions
108
109
  } = options || {};
109
110
 
111
+ // Resolve base URL once at setup time (not inside fetchFn to avoid warning on every request)
112
+ const resolvedBaseURL = restOptions.baseURL || getGlobalBaseUrl();
113
+ if (!resolvedBaseURL) {
114
+ console.warn(
115
+ '[nuxt-openapi-hyperfetch] No baseURL configured. Set runtimeConfig.public.apiBaseUrl in nuxt.config.ts or pass baseURL in options.'
116
+ );
117
+ }
118
+
110
119
  // Create reactive watch sources for callbacks
111
120
  const watchSources = [
112
121
  ...(typeof url === 'function' ? [url] : []),
@@ -170,6 +179,7 @@ export function useApiAsyncDataRaw<T>(
170
179
  headers: modifiedContext.headers,
171
180
  body: modifiedContext.body,
172
181
  params: modifiedContext.params,
182
+ ...(resolvedBaseURL ? { baseURL: resolvedBaseURL } : {}),
173
183
  ...restOptions,
174
184
  });
175
185
 
@@ -6,6 +6,7 @@
6
6
  import { watch } from 'vue';
7
7
  import {
8
8
  getGlobalHeaders,
9
+ getGlobalBaseUrl,
9
10
  applyPick,
10
11
  applyRequestModifications,
11
12
  mergeCallbacks,
@@ -114,6 +115,16 @@ export function useApiRequest<T = any, Options extends ApiRequestOptions<T> = Ap
114
115
  };
115
116
  }
116
117
 
118
+ // Apply global base URL from runtimeConfig.public.apiBaseUrl (if not already set per-composable)
119
+ if (!modifiedOptions.baseURL) {
120
+ modifiedOptions.baseURL = getGlobalBaseUrl();
121
+ }
122
+ if (!modifiedOptions.baseURL) {
123
+ console.warn(
124
+ '[nuxt-openapi-hyperfetch] No baseURL configured. Set runtimeConfig.public.apiBaseUrl in nuxt.config.ts or pass baseURL in options.'
125
+ );
126
+ }
127
+
117
128
  // Execute merged onRequest interceptor and apply modifications
118
129
  if (mergedCallbacks.onRequest) {
119
130
  try {
@@ -154,7 +165,8 @@ export function useApiRequest<T = any, Options extends ApiRequestOptions<T> = Ap
154
165
  // Watch for changes in data, error, and pending states
155
166
  watch(
156
167
  () => [result.data.value, result.error.value, result.pending.value] as const,
157
- async ([data, error, pending], [prevData, prevError, prevPending]) => {
168
+ async ([data, error, pending], prev) => {
169
+ const [prevData, prevError, prevPending] = prev ?? [undefined, undefined, undefined];
158
170
  // Apply transformations when data arrives
159
171
  if (data && data !== prevData) {
160
172
  let processedData: any = data;