nuxt-openapi-hyperfetch 0.1.0-alpha.1 → 0.1.4-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 +26 -1
- package/dist/generators/shared/runtime/apiHelpers.d.ts +5 -0
- package/dist/generators/shared/runtime/apiHelpers.js +15 -0
- package/dist/generators/use-async-data/generator.js +1 -1
- package/dist/generators/use-async-data/runtime/useApiAsyncData.js +7 -1
- package/dist/generators/use-async-data/runtime/useApiAsyncDataRaw.js +7 -1
- package/dist/generators/use-async-data/templates.js +2 -2
- package/dist/generators/use-fetch/generator.js +1 -1
- package/dist/generators/use-fetch/runtime/useApiRequest.js +10 -2
- package/dist/generators/use-fetch/templates.js +2 -2
- package/package.json +1 -1
- package/src/generators/shared/runtime/apiHelpers.ts +15 -0
- package/src/generators/use-async-data/generator.ts +1 -1
- package/src/generators/use-async-data/runtime/useApiAsyncData.ts +10 -0
- package/src/generators/use-async-data/runtime/useApiAsyncDataRaw.ts +10 -0
- package/src/generators/use-async-data/templates.ts +2 -2
- package/src/generators/use-fetch/generator.ts +1 -1
- package/src/generators/use-fetch/runtime/useApiRequest.ts +13 -1
- package/src/generators/use-fetch/templates.ts +2 -2
package/README.md
CHANGED
|
@@ -106,7 +106,29 @@ api/
|
|
|
106
106
|
+-- index.ts
|
|
107
107
|
```
|
|
108
108
|
|
|
109
|
-
### 3.
|
|
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)
|
|
@@ -43,7 +43,7 @@ export async function generateUseAsyncDataComposables(inputDir, outputDir, optio
|
|
|
43
43
|
mainSpinner.start('Preparing output directories');
|
|
44
44
|
const composablesDir = path.join(outputDir, 'composables');
|
|
45
45
|
const runtimeDir = path.join(outputDir, 'runtime');
|
|
46
|
-
const sharedRuntimeDir = path.join(outputDir, 'shared', 'runtime');
|
|
46
|
+
const sharedRuntimeDir = path.join(path.dirname(outputDir), 'shared', 'runtime');
|
|
47
47
|
await fs.emptyDir(composablesDir);
|
|
48
48
|
await fs.ensureDir(runtimeDir);
|
|
49
49
|
await fs.ensureDir(sharedRuntimeDir);
|
|
@@ -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
|
|
@@ -97,7 +97,7 @@ function generateImports(method, apiImportPath, isRaw) {
|
|
|
97
97
|
*/
|
|
98
98
|
function generateFunctionBody(method, isRaw, generateOptions) {
|
|
99
99
|
const hasParams = !!method.requestType;
|
|
100
|
-
const paramsArg = hasParams ? `params:
|
|
100
|
+
const paramsArg = hasParams ? `params: ${method.requestType}` : '';
|
|
101
101
|
// Determine the options type based on isRaw
|
|
102
102
|
const optionsType = isRaw
|
|
103
103
|
? `ApiAsyncDataRawOptions<${method.responseType}>`
|
|
@@ -116,7 +116,7 @@ function generateFunctionBody(method, isRaw, generateOptions) {
|
|
|
116
116
|
const description = method.description ? `/**\n * ${method.description}\n */\n` : '';
|
|
117
117
|
// Choose the correct wrapper function
|
|
118
118
|
const wrapperFunction = isRaw ? 'useApiAsyncDataRaw' : 'useApiAsyncData';
|
|
119
|
-
const pInit = hasParams ? `\n const p =
|
|
119
|
+
const pInit = hasParams ? `\n const p = shallowRef(params)` : '';
|
|
120
120
|
return `${description}export const ${composableName} = (${args}) => {${pInit}
|
|
121
121
|
return ${wrapperFunction}${responseTypeGeneric}(${key}, ${url}, ${fetchOptions})
|
|
122
122
|
}`;
|
|
@@ -43,7 +43,7 @@ export async function generateUseFetchComposables(inputDir, outputDir, options)
|
|
|
43
43
|
mainSpinner.start('Preparing output directories');
|
|
44
44
|
const composablesDir = path.join(outputDir, 'composables');
|
|
45
45
|
const runtimeDir = path.join(outputDir, 'runtime');
|
|
46
|
-
const sharedRuntimeDir = path.join(outputDir, 'shared', 'runtime');
|
|
46
|
+
const sharedRuntimeDir = path.join(path.dirname(outputDir), 'shared', 'runtime');
|
|
47
47
|
await fs.emptyDir(composablesDir);
|
|
48
48
|
await fs.ensureDir(runtimeDir);
|
|
49
49
|
await fs.ensureDir(sharedRuntimeDir);
|
|
@@ -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],
|
|
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;
|
|
@@ -86,7 +86,7 @@ function generateImports(method, apiImportPath) {
|
|
|
86
86
|
*/
|
|
87
87
|
function generateFunctionBody(method, options) {
|
|
88
88
|
const hasParams = !!method.requestType;
|
|
89
|
-
const paramsArg = hasParams ? `params:
|
|
89
|
+
const paramsArg = hasParams ? `params: ${method.requestType}` : '';
|
|
90
90
|
const optionsType = `ApiRequestOptions<${method.responseType}>`;
|
|
91
91
|
const optionsArg = `options?: ${optionsType}`;
|
|
92
92
|
const args = hasParams ? `${paramsArg}, ${optionsArg}` : optionsArg;
|
|
@@ -94,7 +94,7 @@ function generateFunctionBody(method, options) {
|
|
|
94
94
|
const url = generateUrl(method);
|
|
95
95
|
const fetchOptions = generateFetchOptions(method, options);
|
|
96
96
|
const description = method.description ? `/**\n * ${method.description}\n */\n` : '';
|
|
97
|
-
const pInit = hasParams ? `\n const p =
|
|
97
|
+
const pInit = hasParams ? `\n const p = shallowRef(params)` : '';
|
|
98
98
|
return `${description}export const ${method.composableName} = (${args}) => {${pInit}
|
|
99
99
|
return useApiRequest${responseTypeGeneric}(${url}, ${fetchOptions})
|
|
100
100
|
}`;
|
package/package.json
CHANGED
|
@@ -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)
|
|
@@ -67,7 +67,7 @@ export async function generateUseAsyncDataComposables(
|
|
|
67
67
|
mainSpinner.start('Preparing output directories');
|
|
68
68
|
const composablesDir = path.join(outputDir, 'composables');
|
|
69
69
|
const runtimeDir = path.join(outputDir, 'runtime');
|
|
70
|
-
const sharedRuntimeDir = path.join(outputDir, 'shared', 'runtime');
|
|
70
|
+
const sharedRuntimeDir = path.join(path.dirname(outputDir), 'shared', 'runtime');
|
|
71
71
|
await fs.emptyDir(composablesDir);
|
|
72
72
|
await fs.ensureDir(runtimeDir);
|
|
73
73
|
await fs.ensureDir(sharedRuntimeDir);
|
|
@@ -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
|
|
|
@@ -135,7 +135,7 @@ function generateFunctionBody(
|
|
|
135
135
|
generateOptions?: GenerateOptions
|
|
136
136
|
): string {
|
|
137
137
|
const hasParams = !!method.requestType;
|
|
138
|
-
const paramsArg = hasParams ? `params:
|
|
138
|
+
const paramsArg = hasParams ? `params: ${method.requestType}` : '';
|
|
139
139
|
|
|
140
140
|
// Determine the options type based on isRaw
|
|
141
141
|
const optionsType = isRaw
|
|
@@ -163,7 +163,7 @@ function generateFunctionBody(
|
|
|
163
163
|
// Choose the correct wrapper function
|
|
164
164
|
const wrapperFunction = isRaw ? 'useApiAsyncDataRaw' : 'useApiAsyncData';
|
|
165
165
|
|
|
166
|
-
const pInit = hasParams ? `\n const p =
|
|
166
|
+
const pInit = hasParams ? `\n const p = shallowRef(params)` : '';
|
|
167
167
|
|
|
168
168
|
return `${description}export const ${composableName} = (${args}) => {${pInit}
|
|
169
169
|
return ${wrapperFunction}${responseTypeGeneric}(${key}, ${url}, ${fetchOptions})
|
|
@@ -62,7 +62,7 @@ export async function generateUseFetchComposables(
|
|
|
62
62
|
mainSpinner.start('Preparing output directories');
|
|
63
63
|
const composablesDir = path.join(outputDir, 'composables');
|
|
64
64
|
const runtimeDir = path.join(outputDir, 'runtime');
|
|
65
|
-
const sharedRuntimeDir = path.join(outputDir, 'shared', 'runtime');
|
|
65
|
+
const sharedRuntimeDir = path.join(path.dirname(outputDir), 'shared', 'runtime');
|
|
66
66
|
await fs.emptyDir(composablesDir);
|
|
67
67
|
await fs.ensureDir(runtimeDir);
|
|
68
68
|
await fs.ensureDir(sharedRuntimeDir);
|
|
@@ -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],
|
|
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;
|
|
@@ -115,7 +115,7 @@ function generateImports(method: MethodInfo, apiImportPath: string): string {
|
|
|
115
115
|
*/
|
|
116
116
|
function generateFunctionBody(method: MethodInfo, options?: GenerateOptions): string {
|
|
117
117
|
const hasParams = !!method.requestType;
|
|
118
|
-
const paramsArg = hasParams ? `params:
|
|
118
|
+
const paramsArg = hasParams ? `params: ${method.requestType}` : '';
|
|
119
119
|
const optionsType = `ApiRequestOptions<${method.responseType}>`;
|
|
120
120
|
const optionsArg = `options?: ${optionsType}`;
|
|
121
121
|
const args = hasParams ? `${paramsArg}, ${optionsArg}` : optionsArg;
|
|
@@ -127,7 +127,7 @@ function generateFunctionBody(method: MethodInfo, options?: GenerateOptions): st
|
|
|
127
127
|
|
|
128
128
|
const description = method.description ? `/**\n * ${method.description}\n */\n` : '';
|
|
129
129
|
|
|
130
|
-
const pInit = hasParams ? `\n const p =
|
|
130
|
+
const pInit = hasParams ? `\n const p = shallowRef(params)` : '';
|
|
131
131
|
|
|
132
132
|
return `${description}export const ${method.composableName} = (${args}) => {${pInit}
|
|
133
133
|
return useApiRequest${responseTypeGeneric}(${url}, ${fetchOptions})
|