nuxt-openapi-hyperfetch 0.1.7-alpha.1 → 0.2.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.
Files changed (97) hide show
  1. package/CONTRIBUTING.md +291 -292
  2. package/INSTRUCTIONS.md +327 -327
  3. package/LICENSE +202 -202
  4. package/README.md +231 -227
  5. package/dist/cli/logger.d.ts +26 -0
  6. package/dist/cli/logger.js +36 -0
  7. package/dist/cli/logo.js +5 -5
  8. package/dist/generators/components/connector-generator/generator.d.ts +12 -0
  9. package/dist/generators/components/connector-generator/generator.js +116 -0
  10. package/dist/generators/components/connector-generator/templates.d.ts +18 -0
  11. package/dist/generators/components/connector-generator/templates.js +222 -0
  12. package/dist/generators/components/connector-generator/types.d.ts +32 -0
  13. package/dist/generators/components/connector-generator/types.js +7 -0
  14. package/dist/generators/components/schema-analyzer/index.d.ts +17 -0
  15. package/dist/generators/components/schema-analyzer/index.js +20 -0
  16. package/dist/generators/components/schema-analyzer/intent-detector.d.ts +17 -0
  17. package/dist/generators/components/schema-analyzer/intent-detector.js +143 -0
  18. package/dist/generators/components/schema-analyzer/openapi-reader.d.ts +11 -0
  19. package/dist/generators/components/schema-analyzer/openapi-reader.js +76 -0
  20. package/dist/generators/components/schema-analyzer/resource-grouper.d.ts +6 -0
  21. package/dist/generators/components/schema-analyzer/resource-grouper.js +132 -0
  22. package/dist/generators/components/schema-analyzer/schema-field-mapper.d.ts +35 -0
  23. package/dist/generators/components/schema-analyzer/schema-field-mapper.js +220 -0
  24. package/dist/generators/components/schema-analyzer/types.d.ts +156 -0
  25. package/dist/generators/components/schema-analyzer/types.js +7 -0
  26. package/dist/generators/nuxt-server/generator.d.ts +2 -1
  27. package/dist/generators/nuxt-server/generator.js +21 -21
  28. package/dist/generators/shared/runtime/apiHelpers.d.ts +81 -41
  29. package/dist/generators/shared/runtime/apiHelpers.js +97 -104
  30. package/dist/generators/shared/runtime/pagination.d.ts +168 -0
  31. package/dist/generators/shared/runtime/pagination.js +179 -0
  32. package/dist/generators/shared/runtime/useDeleteConnector.d.ts +16 -0
  33. package/dist/generators/shared/runtime/useDeleteConnector.js +93 -0
  34. package/dist/generators/shared/runtime/useDetailConnector.d.ts +14 -0
  35. package/dist/generators/shared/runtime/useDetailConnector.js +50 -0
  36. package/dist/generators/shared/runtime/useFormConnector.d.ts +19 -0
  37. package/dist/generators/shared/runtime/useFormConnector.js +113 -0
  38. package/dist/generators/shared/runtime/useListConnector.d.ts +25 -0
  39. package/dist/generators/shared/runtime/useListConnector.js +125 -0
  40. package/dist/generators/shared/runtime/zod-error-merger.d.ts +23 -0
  41. package/dist/generators/shared/runtime/zod-error-merger.js +106 -0
  42. package/dist/generators/shared/templates/api-callbacks-plugin.js +54 -11
  43. package/dist/generators/shared/templates/api-pagination-plugin.d.ts +51 -0
  44. package/dist/generators/shared/templates/api-pagination-plugin.js +152 -0
  45. package/dist/generators/use-async-data/generator.d.ts +2 -1
  46. package/dist/generators/use-async-data/generator.js +14 -14
  47. package/dist/generators/use-async-data/runtime/useApiAsyncData.js +114 -13
  48. package/dist/generators/use-async-data/runtime/useApiAsyncDataRaw.js +88 -10
  49. package/dist/generators/use-async-data/templates.js +17 -17
  50. package/dist/generators/use-fetch/generator.d.ts +2 -1
  51. package/dist/generators/use-fetch/generator.js +12 -12
  52. package/dist/generators/use-fetch/runtime/useApiRequest.js +149 -40
  53. package/dist/generators/use-fetch/templates.js +14 -14
  54. package/dist/index.js +25 -0
  55. package/dist/module/index.d.ts +4 -0
  56. package/dist/module/index.js +93 -0
  57. package/dist/module/types.d.ts +27 -0
  58. package/dist/module/types.js +1 -0
  59. package/docs/API-REFERENCE.md +886 -887
  60. package/docs/generated-components.md +615 -0
  61. package/docs/headless-composables-ui.md +569 -0
  62. package/eslint.config.js +13 -0
  63. package/package.json +29 -2
  64. package/src/cli/config.ts +140 -140
  65. package/src/cli/logger.ts +124 -66
  66. package/src/cli/logo.ts +25 -25
  67. package/src/cli/types.ts +50 -50
  68. package/src/generators/components/connector-generator/generator.ts +138 -0
  69. package/src/generators/components/connector-generator/templates.ts +254 -0
  70. package/src/generators/components/connector-generator/types.ts +34 -0
  71. package/src/generators/components/schema-analyzer/index.ts +44 -0
  72. package/src/generators/components/schema-analyzer/intent-detector.ts +187 -0
  73. package/src/generators/components/schema-analyzer/openapi-reader.ts +96 -0
  74. package/src/generators/components/schema-analyzer/resource-grouper.ts +166 -0
  75. package/src/generators/components/schema-analyzer/schema-field-mapper.ts +268 -0
  76. package/src/generators/components/schema-analyzer/types.ts +177 -0
  77. package/src/generators/nuxt-server/generator.ts +272 -270
  78. package/src/generators/shared/runtime/apiHelpers.ts +535 -507
  79. package/src/generators/shared/runtime/pagination.ts +323 -0
  80. package/src/generators/shared/runtime/useDeleteConnector.ts +109 -0
  81. package/src/generators/shared/runtime/useDetailConnector.ts +64 -0
  82. package/src/generators/shared/runtime/useFormConnector.ts +139 -0
  83. package/src/generators/shared/runtime/useListConnector.ts +148 -0
  84. package/src/generators/shared/runtime/zod-error-merger.ts +119 -0
  85. package/src/generators/shared/templates/api-callbacks-plugin.ts +399 -352
  86. package/src/generators/shared/templates/api-pagination-plugin.ts +158 -0
  87. package/src/generators/use-async-data/generator.ts +205 -204
  88. package/src/generators/use-async-data/runtime/useApiAsyncData.ts +329 -229
  89. package/src/generators/use-async-data/runtime/useApiAsyncDataRaw.ts +324 -245
  90. package/src/generators/use-async-data/templates.ts +257 -257
  91. package/src/generators/use-fetch/generator.ts +170 -169
  92. package/src/generators/use-fetch/runtime/useApiRequest.ts +354 -234
  93. package/src/generators/use-fetch/templates.ts +214 -214
  94. package/src/index.ts +303 -265
  95. package/src/module/index.ts +133 -0
  96. package/src/module/types.ts +31 -0
  97. package/src/generators/tanstack-query/generator.ts +0 -11
@@ -1,214 +1,214 @@
1
- import type { MethodInfo } from './types.js';
2
-
3
- /**
4
- * Generate file header with auto-generation warning
5
- */
6
- function generateFileHeader(): string {
7
- return `/**
8
- * ⚠️ AUTO-GENERATED FILE - DO NOT EDIT MANUALLY
9
- *
10
- * This file was automatically generated by nuxt-openapi-generator.
11
- * Any manual changes will be overwritten on the next generation.
12
- *
13
- * @generated by nuxt-openapi-generator
14
- * @see https://github.com/dmartindiaz/nuxt-openapi-hyperfetch
15
- */
16
-
17
- /* eslint-disable */
18
- // @ts-nocheck
19
- `;
20
- }
21
-
22
- /**
23
- * Options for code generation
24
- */
25
- export interface GenerateOptions {
26
- baseUrl?: string;
27
- backend?: string;
28
- }
29
-
30
- /**
31
- * Generate a useFetch composable function
32
- */
33
- export function generateComposableFile(
34
- method: MethodInfo,
35
- apiImportPath: string,
36
- options?: GenerateOptions
37
- ): string {
38
- const header = generateFileHeader();
39
- const imports = generateImports(method, apiImportPath);
40
- const functionBody = generateFunctionBody(method, options);
41
-
42
- return `${header}${imports}\n\n${functionBody}\n`;
43
- }
44
-
45
- /**
46
- * Extract base type names from a type string
47
- * Examples:
48
- * Pet[] -> Pet
49
- * Array<Pet> -> Pet
50
- * Pet -> Pet
51
- * { [key: string]: Pet } -> (empty, it's anonymous)
52
- */
53
- function extractBaseTypes(type: string): string[] {
54
- if (!type) {
55
- return [];
56
- }
57
-
58
- // Handle array syntax: Pet[]
59
- const arrayMatch = type.match(/^(\w+)\[\]$/);
60
- if (arrayMatch) {
61
- return [arrayMatch[1]];
62
- }
63
-
64
- // Handle Array generic: Array<Pet>
65
- const arrayGenericMatch = type.match(/^Array<(\w+)>$/);
66
- if (arrayGenericMatch) {
67
- return [arrayGenericMatch[1]];
68
- }
69
-
70
- // If it's a simple named type (single word, PascalCase), include it
71
- if (/^[A-Z][a-zA-Z0-9]*$/.test(type)) {
72
- return [type];
73
- }
74
-
75
- // For complex types, don't extract anything
76
- return [];
77
- }
78
-
79
- /**
80
- * Generate import statements
81
- */
82
- function generateImports(method: MethodInfo, apiImportPath: string): string {
83
- const typeNames = new Set<string>();
84
-
85
- // Extract base types from request type
86
- if (method.requestType) {
87
- const extracted = extractBaseTypes(method.requestType);
88
- extracted.forEach((t) => typeNames.add(t));
89
- }
90
-
91
- // Extract base types from response type
92
- if (method.responseType && method.responseType !== 'void') {
93
- const extracted = extractBaseTypes(method.responseType);
94
- extracted.forEach((t) => typeNames.add(t));
95
- }
96
-
97
- let imports = '';
98
-
99
- // Import types from API (only if we have named types to import)
100
- if (typeNames.size > 0) {
101
- imports += `import type { ${Array.from(typeNames).join(', ')} } from '${apiImportPath}';\n`;
102
- }
103
-
104
- // Import runtime helper
105
- imports += `import { useApiRequest, type ApiRequestOptions } from '../runtime/useApiRequest';`;
106
-
107
- return imports;
108
- }
109
-
110
- /**
111
- }
112
-
113
- /**
114
- * Generate the composable function body
115
- */
116
- function generateFunctionBody(method: MethodInfo, options?: GenerateOptions): string {
117
- const hasParams = !!method.requestType;
118
- const paramsArg = hasParams ? `params: ${method.requestType}` : '';
119
- const optionsType = `ApiRequestOptions<${method.responseType}>`;
120
- const optionsArg = `options?: ${optionsType}`;
121
- const args = hasParams ? `${paramsArg}, ${optionsArg}` : optionsArg;
122
-
123
- const responseTypeGeneric = method.responseType !== 'void' ? `<${method.responseType}>` : '';
124
-
125
- const url = generateUrl(method);
126
- const fetchOptions = generateFetchOptions(method, options);
127
-
128
- const description = method.description ? `/**\n * ${method.description}\n */\n` : '';
129
-
130
- const pInit = hasParams ? `\n const p = shallowRef(params)` : '';
131
-
132
- return `${description}export const ${method.composableName} = (${args}) => {${pInit}
133
- return useApiRequest${responseTypeGeneric}(${url}, ${fetchOptions})
134
- }`;
135
- }
136
-
137
- /**
138
- * Generate URL (with path params if needed)
139
- */
140
- function generateUrl(method: MethodInfo): string {
141
- if (method.pathParams.length === 0) {
142
- return `'${method.path}'`;
143
- }
144
-
145
- let url = method.path;
146
- for (const param of method.pathParams) {
147
- const accessor = method.paramsShape === 'nested' ? `p.value.path.${param}` : `p.value.${param}`;
148
- url = url.replace(`{${param}}`, `\${${accessor}}`);
149
- }
150
-
151
- return `() => \`${url}\``;
152
- }
153
-
154
- /**
155
- * Generate fetch options object
156
- */
157
- function generateFetchOptions(method: MethodInfo, generateOptions?: GenerateOptions): string {
158
- const options: string[] = [];
159
-
160
- // Method
161
- options.push(`method: '${method.httpMethod}'`);
162
-
163
- // Base URL (if provided in config)
164
- if (generateOptions?.baseUrl) {
165
- options.push(`baseURL: '${generateOptions.baseUrl}'`);
166
- }
167
-
168
- // Body
169
- if (method.hasBody) {
170
- if (method.paramsShape === 'nested') {
171
- options.push(`body: computed(() => p.value.body)`);
172
- } else if (method.bodyField) {
173
- options.push(`body: computed(() => p.value.${method.bodyField})`);
174
- }
175
- }
176
-
177
- // Query params
178
- if (method.hasQueryParams) {
179
- if (method.paramsShape === 'nested') {
180
- options.push(`query: computed(() => p.value.query)`);
181
- } else if (method.queryParams.length > 0) {
182
- const queryObj = method.queryParams
183
- .map((param) => `${param}: p.value.${param}`)
184
- .join(',\n ');
185
- options.push(`query: computed(() => ({\n ${queryObj}\n }))`);
186
- }
187
- }
188
-
189
- // Headers
190
- if (Object.keys(method.headers).length > 0) {
191
- const headersEntries = Object.entries(method.headers)
192
- .map(([key, value]) => `'${key}': '${value}'`)
193
- .join(',\n ');
194
- options.push(`headers: {\n ${headersEntries},\n ...options?.headers\n }`);
195
- }
196
-
197
- // Spread options
198
- options.push('...options');
199
-
200
- const optionsStr = options.join(',\n ');
201
- return `{\n ${optionsStr}\n }`;
202
- }
203
-
204
- /**
205
- * Generate index.ts that exports all composables
206
- */
207
- export function generateIndexFile(composableNames: string[]): string {
208
- const header = generateFileHeader();
209
- const exports = composableNames
210
- .map((name) => `export { ${name} } from './composables/${name}'`)
211
- .join('\n');
212
-
213
- return `${header}${exports}\n`;
214
- }
1
+ import type { MethodInfo } from './types.js';
2
+
3
+ /**
4
+ * Generate file header with auto-generation warning
5
+ */
6
+ function generateFileHeader(): string {
7
+ return `/**
8
+ * ⚠️ AUTO-GENERATED FILE - DO NOT EDIT MANUALLY
9
+ *
10
+ * This file was automatically generated by nuxt-openapi-generator.
11
+ * Any manual changes will be overwritten on the next generation.
12
+ *
13
+ * @generated by nuxt-openapi-generator
14
+ * @see https://github.com/dmartindiaz/nuxt-openapi-hyperfetch
15
+ */
16
+
17
+ /* eslint-disable */
18
+ // @ts-nocheck
19
+ `;
20
+ }
21
+
22
+ /**
23
+ * Options for code generation
24
+ */
25
+ export interface GenerateOptions {
26
+ baseUrl?: string;
27
+ backend?: string;
28
+ }
29
+
30
+ /**
31
+ * Generate a useFetch composable function
32
+ */
33
+ export function generateComposableFile(
34
+ method: MethodInfo,
35
+ apiImportPath: string,
36
+ options?: GenerateOptions
37
+ ): string {
38
+ const header = generateFileHeader();
39
+ const imports = generateImports(method, apiImportPath);
40
+ const functionBody = generateFunctionBody(method, options);
41
+
42
+ return `${header}${imports}\n\n${functionBody}\n`;
43
+ }
44
+
45
+ /**
46
+ * Extract base type names from a type string
47
+ * Examples:
48
+ * Pet[] -> Pet
49
+ * Array<Pet> -> Pet
50
+ * Pet -> Pet
51
+ * { [key: string]: Pet } -> (empty, it's anonymous)
52
+ */
53
+ function extractBaseTypes(type: string): string[] {
54
+ if (!type) {
55
+ return [];
56
+ }
57
+
58
+ // Handle array syntax: Pet[]
59
+ const arrayMatch = type.match(/^(\w+)\[\]$/);
60
+ if (arrayMatch) {
61
+ return [arrayMatch[1]];
62
+ }
63
+
64
+ // Handle Array generic: Array<Pet>
65
+ const arrayGenericMatch = type.match(/^Array<(\w+)>$/);
66
+ if (arrayGenericMatch) {
67
+ return [arrayGenericMatch[1]];
68
+ }
69
+
70
+ // If it's a simple named type (single word, PascalCase), include it
71
+ if (/^[A-Z][a-zA-Z0-9]*$/.test(type)) {
72
+ return [type];
73
+ }
74
+
75
+ // For complex types, don't extract anything
76
+ return [];
77
+ }
78
+
79
+ /**
80
+ * Generate import statements
81
+ */
82
+ function generateImports(method: MethodInfo, apiImportPath: string): string {
83
+ const typeNames = new Set<string>();
84
+
85
+ // Extract base types from request type
86
+ if (method.requestType) {
87
+ const extracted = extractBaseTypes(method.requestType);
88
+ extracted.forEach((t) => typeNames.add(t));
89
+ }
90
+
91
+ // Extract base types from response type
92
+ if (method.responseType && method.responseType !== 'void') {
93
+ const extracted = extractBaseTypes(method.responseType);
94
+ extracted.forEach((t) => typeNames.add(t));
95
+ }
96
+
97
+ let imports = '';
98
+
99
+ // Import types from API (only if we have named types to import)
100
+ if (typeNames.size > 0) {
101
+ imports += `import type { ${Array.from(typeNames).join(', ')} } from '${apiImportPath}';\n`;
102
+ }
103
+
104
+ // Import runtime helper
105
+ imports += `import { useApiRequest, type ApiRequestOptions } from '../runtime/useApiRequest';`;
106
+
107
+ return imports;
108
+ }
109
+
110
+ /**
111
+ }
112
+
113
+ /**
114
+ * Generate the composable function body
115
+ */
116
+ function generateFunctionBody(method: MethodInfo, options?: GenerateOptions): string {
117
+ const hasParams = !!method.requestType;
118
+ const paramsArg = hasParams ? `params: ${method.requestType}` : '';
119
+ const optionsType = `ApiRequestOptions<${method.responseType}>`;
120
+ const optionsArg = `options?: ${optionsType}`;
121
+ const args = hasParams ? `${paramsArg}, ${optionsArg}` : optionsArg;
122
+
123
+ const responseTypeGeneric = method.responseType !== 'void' ? `<${method.responseType}>` : '';
124
+
125
+ const url = generateUrl(method);
126
+ const fetchOptions = generateFetchOptions(method, options);
127
+
128
+ const description = method.description ? `/**\n * ${method.description}\n */\n` : '';
129
+
130
+ const pInit = hasParams ? `\n const p = shallowRef(params)` : '';
131
+
132
+ return `${description}export const ${method.composableName} = (${args}) => {${pInit}
133
+ return useApiRequest${responseTypeGeneric}(${url}, ${fetchOptions})
134
+ }`;
135
+ }
136
+
137
+ /**
138
+ * Generate URL (with path params if needed)
139
+ */
140
+ function generateUrl(method: MethodInfo): string {
141
+ if (method.pathParams.length === 0) {
142
+ return `'${method.path}'`;
143
+ }
144
+
145
+ let url = method.path;
146
+ for (const param of method.pathParams) {
147
+ const accessor = method.paramsShape === 'nested' ? `p.value.path.${param}` : `p.value.${param}`;
148
+ url = url.replace(`{${param}}`, `\${${accessor}}`);
149
+ }
150
+
151
+ return `() => \`${url}\``;
152
+ }
153
+
154
+ /**
155
+ * Generate fetch options object
156
+ */
157
+ function generateFetchOptions(method: MethodInfo, generateOptions?: GenerateOptions): string {
158
+ const options: string[] = [];
159
+
160
+ // Method
161
+ options.push(`method: '${method.httpMethod}'`);
162
+
163
+ // Base URL (if provided in config)
164
+ if (generateOptions?.baseUrl) {
165
+ options.push(`baseURL: '${generateOptions.baseUrl}'`);
166
+ }
167
+
168
+ // Body
169
+ if (method.hasBody) {
170
+ if (method.paramsShape === 'nested') {
171
+ options.push(`body: computed(() => p.value.body)`);
172
+ } else if (method.bodyField) {
173
+ options.push(`body: computed(() => p.value.${method.bodyField})`);
174
+ }
175
+ }
176
+
177
+ // Query params
178
+ if (method.hasQueryParams) {
179
+ if (method.paramsShape === 'nested') {
180
+ options.push(`query: computed(() => p.value.query)`);
181
+ } else if (method.queryParams.length > 0) {
182
+ const queryObj = method.queryParams
183
+ .map((param) => `${param}: p.value.${param}`)
184
+ .join(',\n ');
185
+ options.push(`query: computed(() => ({\n ${queryObj}\n }))`);
186
+ }
187
+ }
188
+
189
+ // Headers
190
+ if (Object.keys(method.headers).length > 0) {
191
+ const headersEntries = Object.entries(method.headers)
192
+ .map(([key, value]) => `'${key}': '${value}'`)
193
+ .join(',\n ');
194
+ options.push(`headers: {\n ${headersEntries},\n ...options?.headers\n }`);
195
+ }
196
+
197
+ // Spread options
198
+ options.push('...options');
199
+
200
+ const optionsStr = options.join(',\n ');
201
+ return `{\n ${optionsStr}\n }`;
202
+ }
203
+
204
+ /**
205
+ * Generate index.ts that exports all composables
206
+ */
207
+ export function generateIndexFile(composableNames: string[]): string {
208
+ const header = generateFileHeader();
209
+ const exports = composableNames
210
+ .map((name) => `export { ${name} } from './composables/${name}'`)
211
+ .join('\n');
212
+
213
+ return `${header}${exports}\n`;
214
+ }