nuxt-openapi-hyperfetch 0.3.6-beta → 0.3.8-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.
- package/dist/generators/components/connector-generator/templates.js +9 -1
- package/dist/generators/shared/runtime/useDetailConnector.d.ts +1 -1
- package/dist/generators/shared/runtime/useDetailConnector.js +19 -10
- package/dist/index.js +1 -1
- package/dist/module/index.js +1 -1
- package/package.json +1 -1
- package/src/generators/components/connector-generator/templates.ts +14 -1
- package/src/generators/shared/runtime/useDetailConnector.ts +18 -13
- package/src/index.ts +1 -1
- package/src/module/index.ts +1 -1
|
@@ -38,6 +38,11 @@ function buildImports(resource, composablesRelDir, sdkRelDir, runtimeRelDir) {
|
|
|
38
38
|
// zod
|
|
39
39
|
lines.push(`import { z } from 'zod';`);
|
|
40
40
|
lines.push('');
|
|
41
|
+
// Vue — computed needed for the detail connector wrapper
|
|
42
|
+
if (resource.detailEndpoint) {
|
|
43
|
+
lines.push(`import { computed } from 'vue';`);
|
|
44
|
+
lines.push('');
|
|
45
|
+
}
|
|
41
46
|
// connector-types — structural interfaces for return types
|
|
42
47
|
const connectorTypeImports = ['ListConnectorReturn'];
|
|
43
48
|
if (resource.detailEndpoint) {
|
|
@@ -238,7 +243,10 @@ function buildFunctionBody(resource) {
|
|
|
238
243
|
}
|
|
239
244
|
if (resource.detailEndpoint) {
|
|
240
245
|
const fn = toAsyncDataName(resource.detailEndpoint.operationId);
|
|
241
|
-
|
|
246
|
+
// Wrap the composable to map the generic idRef to the actual path param name.
|
|
247
|
+
// useDetailConnector passes a ref<id> and calls refresh() after updating it.
|
|
248
|
+
const pathParam = resource.detailEndpoint.pathParams[0] ?? 'id';
|
|
249
|
+
subConnectors.push(` const detail = useDetailConnector(`, ` (idRef, opts) => ${fn}(computed(() => ({ ${pathParam}: idRef.value })) as any, opts),`, ` ) as unknown as DetailConnectorReturn<${pascal}>;`);
|
|
242
250
|
}
|
|
243
251
|
if (resource.createEndpoint) {
|
|
244
252
|
const fn = toAsyncDataName(resource.createEndpoint.operationId);
|
|
@@ -16,23 +16,32 @@ import { ref, computed } from 'vue';
|
|
|
16
16
|
*/
|
|
17
17
|
export function useDetailConnector(composableFn, options = {}) {
|
|
18
18
|
const { fields = [] } = options;
|
|
19
|
-
//
|
|
20
|
-
|
|
21
|
-
//
|
|
22
|
-
//
|
|
23
|
-
|
|
24
|
-
|
|
19
|
+
// ── Reactive ID ref passed to the composable wrapper ──────────────────────
|
|
20
|
+
// The generated connector wraps the composable like:
|
|
21
|
+
// (idRef, opts) => useAsyncDataGetPetById(computed(() => ({ petId: idRef.value })), opts)
|
|
22
|
+
// This lets us update idRef.value in load(id) so refresh() picks up the new value.
|
|
23
|
+
const idRef = ref(null);
|
|
24
|
+
// ── Execute the underlying composable ──────────────────────────────────────
|
|
25
|
+
// watch: false + immediate: false + lazy: true prevent any fetch until
|
|
26
|
+
// load(id) is called explicitly. The URL is only evaluated on refresh().
|
|
27
|
+
const composable = composableFn(idRef, {
|
|
28
|
+
watch: false,
|
|
29
|
+
immediate: false,
|
|
30
|
+
lazy: true,
|
|
31
|
+
});
|
|
25
32
|
// ── Derived state ──────────────────────────────────────────────────────────
|
|
26
33
|
const item = computed(() => composable.data?.value ?? null);
|
|
27
34
|
const loading = computed(() => composable.pending?.value ?? false);
|
|
28
35
|
const error = computed(() => composable.error?.value ?? null);
|
|
29
36
|
// ── Actions ────────────────────────────────────────────────────────────────
|
|
30
37
|
async function load(id) {
|
|
31
|
-
|
|
38
|
+
idRef.value = id;
|
|
32
39
|
await composable.refresh?.();
|
|
33
40
|
}
|
|
34
41
|
function clear() {
|
|
35
|
-
|
|
42
|
+
idRef.value = null;
|
|
43
|
+
if (composable.data)
|
|
44
|
+
composable.data.value = null;
|
|
36
45
|
}
|
|
37
46
|
return {
|
|
38
47
|
// State
|
|
@@ -43,8 +52,8 @@ export function useDetailConnector(composableFn, options = {}) {
|
|
|
43
52
|
// Actions
|
|
44
53
|
load,
|
|
45
54
|
clear,
|
|
46
|
-
// Expose composable for advanced use
|
|
55
|
+
// Expose composable for advanced use
|
|
47
56
|
_composable: composable,
|
|
48
|
-
|
|
57
|
+
_idRef: idRef,
|
|
49
58
|
};
|
|
50
59
|
}
|
package/dist/index.js
CHANGED
|
@@ -216,7 +216,7 @@ program
|
|
|
216
216
|
await generateConnectors({
|
|
217
217
|
inputSpec: inputPath,
|
|
218
218
|
outputDir: `${composablesOutputDir}/connectors`,
|
|
219
|
-
composablesRelDir: '../use-async-data',
|
|
219
|
+
composablesRelDir: '../use-async-data/composables',
|
|
220
220
|
runtimeRelDir: '../../runtime',
|
|
221
221
|
});
|
|
222
222
|
spinner.stop('✓ Generated headless UI connectors');
|
package/dist/module/index.js
CHANGED
|
@@ -73,7 +73,7 @@ export default defineNuxtModule({
|
|
|
73
73
|
await generateConnectors({
|
|
74
74
|
inputSpec: resolvedInput,
|
|
75
75
|
outputDir: connectorsOutputDir,
|
|
76
|
-
composablesRelDir: '../use-async-data',
|
|
76
|
+
composablesRelDir: '../use-async-data/composables',
|
|
77
77
|
runtimeRelDir: '../../runtime',
|
|
78
78
|
}, logger);
|
|
79
79
|
}
|
package/package.json
CHANGED
|
@@ -48,6 +48,12 @@ function buildImports(resource: ResourceInfo, composablesRelDir: string, sdkRelD
|
|
|
48
48
|
lines.push(`import { z } from 'zod';`);
|
|
49
49
|
lines.push('');
|
|
50
50
|
|
|
51
|
+
// Vue — computed needed for the detail connector wrapper
|
|
52
|
+
if (resource.detailEndpoint) {
|
|
53
|
+
lines.push(`import { computed } from 'vue';`);
|
|
54
|
+
lines.push('');
|
|
55
|
+
}
|
|
56
|
+
|
|
51
57
|
// connector-types — structural interfaces for return types
|
|
52
58
|
const connectorTypeImports: string[] = ['ListConnectorReturn'];
|
|
53
59
|
if (resource.detailEndpoint) {
|
|
@@ -283,7 +289,14 @@ function buildFunctionBody(resource: ResourceInfo): string {
|
|
|
283
289
|
|
|
284
290
|
if (resource.detailEndpoint) {
|
|
285
291
|
const fn = toAsyncDataName(resource.detailEndpoint.operationId);
|
|
286
|
-
|
|
292
|
+
// Wrap the composable to map the generic idRef to the actual path param name.
|
|
293
|
+
// useDetailConnector passes a ref<id> and calls refresh() after updating it.
|
|
294
|
+
const pathParam = resource.detailEndpoint.pathParams[0] ?? 'id';
|
|
295
|
+
subConnectors.push(
|
|
296
|
+
` const detail = useDetailConnector(`,
|
|
297
|
+
` (idRef, opts) => ${fn}(computed(() => ({ ${pathParam}: idRef.value })) as any, opts),`,
|
|
298
|
+
` ) as unknown as DetailConnectorReturn<${pascal}>;`
|
|
299
|
+
);
|
|
287
300
|
}
|
|
288
301
|
|
|
289
302
|
if (resource.createEndpoint) {
|
|
@@ -18,16 +18,20 @@ import { ref, computed } from 'vue';
|
|
|
18
18
|
export function useDetailConnector(composableFn, options = {}) {
|
|
19
19
|
const { fields = [] } = options;
|
|
20
20
|
|
|
21
|
-
//
|
|
22
|
-
|
|
21
|
+
// ── Reactive ID ref passed to the composable wrapper ──────────────────────
|
|
22
|
+
// The generated connector wraps the composable like:
|
|
23
|
+
// (idRef, opts) => useAsyncDataGetPetById(computed(() => ({ petId: idRef.value })), opts)
|
|
24
|
+
// This lets us update idRef.value in load(id) so refresh() picks up the new value.
|
|
25
|
+
const idRef = ref(null);
|
|
23
26
|
|
|
24
|
-
// ── Execute the underlying composable
|
|
25
|
-
//
|
|
26
|
-
// load(id)
|
|
27
|
-
const composable = composableFn(
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
27
|
+
// ── Execute the underlying composable ──────────────────────────────────────
|
|
28
|
+
// watch: false + immediate: false + lazy: true prevent any fetch until
|
|
29
|
+
// load(id) is called explicitly. The URL is only evaluated on refresh().
|
|
30
|
+
const composable = composableFn(idRef, {
|
|
31
|
+
watch: false,
|
|
32
|
+
immediate: false,
|
|
33
|
+
lazy: true,
|
|
34
|
+
});
|
|
31
35
|
|
|
32
36
|
// ── Derived state ──────────────────────────────────────────────────────────
|
|
33
37
|
|
|
@@ -38,12 +42,13 @@ export function useDetailConnector(composableFn, options = {}) {
|
|
|
38
42
|
// ── Actions ────────────────────────────────────────────────────────────────
|
|
39
43
|
|
|
40
44
|
async function load(id) {
|
|
41
|
-
|
|
45
|
+
idRef.value = id;
|
|
42
46
|
await composable.refresh?.();
|
|
43
47
|
}
|
|
44
48
|
|
|
45
49
|
function clear() {
|
|
46
|
-
|
|
50
|
+
idRef.value = null;
|
|
51
|
+
if (composable.data) composable.data.value = null;
|
|
47
52
|
}
|
|
48
53
|
|
|
49
54
|
return {
|
|
@@ -57,8 +62,8 @@ export function useDetailConnector(composableFn, options = {}) {
|
|
|
57
62
|
load,
|
|
58
63
|
clear,
|
|
59
64
|
|
|
60
|
-
// Expose composable for advanced use
|
|
65
|
+
// Expose composable for advanced use
|
|
61
66
|
_composable: composable,
|
|
62
|
-
|
|
67
|
+
_idRef: idRef,
|
|
63
68
|
};
|
|
64
69
|
}
|
package/src/index.ts
CHANGED
|
@@ -276,7 +276,7 @@ program
|
|
|
276
276
|
await generateConnectors({
|
|
277
277
|
inputSpec: inputPath,
|
|
278
278
|
outputDir: `${composablesOutputDir}/connectors`,
|
|
279
|
-
composablesRelDir: '../use-async-data',
|
|
279
|
+
composablesRelDir: '../use-async-data/composables',
|
|
280
280
|
runtimeRelDir: '../../runtime',
|
|
281
281
|
});
|
|
282
282
|
spinner.stop('✓ Generated headless UI connectors');
|
package/src/module/index.ts
CHANGED
|
@@ -112,7 +112,7 @@ export default defineNuxtModule<ModuleOptions>({
|
|
|
112
112
|
{
|
|
113
113
|
inputSpec: resolvedInput,
|
|
114
114
|
outputDir: connectorsOutputDir,
|
|
115
|
-
composablesRelDir: '../use-async-data',
|
|
115
|
+
composablesRelDir: '../use-async-data/composables',
|
|
116
116
|
runtimeRelDir: '../../runtime',
|
|
117
117
|
},
|
|
118
118
|
logger
|