nuxt-openapi-hyperfetch 0.2.7-alpha.1 → 0.2.8-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 (60) hide show
  1. package/.editorconfig +26 -26
  2. package/.prettierignore +17 -17
  3. package/CONTRIBUTING.md +291 -291
  4. package/INSTRUCTIONS.md +327 -327
  5. package/LICENSE +202 -202
  6. package/README.md +231 -231
  7. package/dist/cli/config.d.ts +9 -2
  8. package/dist/cli/config.js +1 -1
  9. package/dist/cli/logo.js +5 -5
  10. package/dist/cli/messages.d.ts +1 -0
  11. package/dist/cli/messages.js +2 -0
  12. package/dist/cli/prompts.d.ts +5 -0
  13. package/dist/cli/prompts.js +12 -0
  14. package/dist/cli/types.d.ts +1 -1
  15. package/dist/generators/components/connector-generator/templates.js +12 -12
  16. package/dist/generators/use-async-data/templates.js +17 -17
  17. package/dist/generators/use-fetch/templates.js +14 -14
  18. package/dist/index.js +39 -27
  19. package/dist/module/index.js +19 -0
  20. package/dist/module/types.d.ts +7 -0
  21. package/docs/API-REFERENCE.md +886 -886
  22. package/docs/generated-components.md +615 -615
  23. package/docs/headless-composables-ui.md +569 -569
  24. package/eslint.config.js +85 -85
  25. package/package.json +1 -1
  26. package/src/cli/config.ts +147 -140
  27. package/src/cli/logger.ts +124 -124
  28. package/src/cli/logo.ts +25 -25
  29. package/src/cli/messages.ts +4 -0
  30. package/src/cli/prompts.ts +14 -1
  31. package/src/cli/types.ts +50 -50
  32. package/src/generators/components/connector-generator/generator.ts +138 -138
  33. package/src/generators/components/connector-generator/templates.ts +254 -254
  34. package/src/generators/components/connector-generator/types.ts +34 -34
  35. package/src/generators/components/schema-analyzer/index.ts +44 -44
  36. package/src/generators/components/schema-analyzer/intent-detector.ts +187 -187
  37. package/src/generators/components/schema-analyzer/openapi-reader.ts +96 -96
  38. package/src/generators/components/schema-analyzer/resource-grouper.ts +166 -166
  39. package/src/generators/components/schema-analyzer/schema-field-mapper.ts +268 -268
  40. package/src/generators/components/schema-analyzer/types.ts +177 -177
  41. package/src/generators/nuxt-server/generator.ts +272 -272
  42. package/src/generators/shared/runtime/apiHelpers.ts +535 -535
  43. package/src/generators/shared/runtime/pagination.ts +323 -323
  44. package/src/generators/shared/runtime/useDeleteConnector.ts +109 -109
  45. package/src/generators/shared/runtime/useDetailConnector.ts +64 -64
  46. package/src/generators/shared/runtime/useFormConnector.ts +139 -139
  47. package/src/generators/shared/runtime/useListConnector.ts +148 -148
  48. package/src/generators/shared/runtime/zod-error-merger.ts +119 -119
  49. package/src/generators/shared/templates/api-callbacks-plugin.ts +399 -399
  50. package/src/generators/shared/templates/api-pagination-plugin.ts +158 -158
  51. package/src/generators/use-async-data/generator.ts +205 -205
  52. package/src/generators/use-async-data/runtime/useApiAsyncData.ts +329 -329
  53. package/src/generators/use-async-data/runtime/useApiAsyncDataRaw.ts +324 -324
  54. package/src/generators/use-async-data/templates.ts +257 -257
  55. package/src/generators/use-fetch/generator.ts +170 -170
  56. package/src/generators/use-fetch/runtime/useApiRequest.ts +354 -354
  57. package/src/generators/use-fetch/templates.ts +214 -214
  58. package/src/index.ts +305 -303
  59. package/src/module/index.ts +158 -133
  60. package/src/module/types.ts +39 -31
package/eslint.config.js CHANGED
@@ -1,85 +1,85 @@
1
- // @ts-check
2
- import eslint from '@eslint/js';
3
- import tseslint from 'typescript-eslint';
4
- import prettierConfig from 'eslint-config-prettier';
5
- import prettierPlugin from 'eslint-plugin-prettier';
6
-
7
- export default tseslint.config(
8
- eslint.configs.recommended,
9
- ...tseslint.configs.recommendedTypeChecked,
10
- prettierConfig,
11
- {
12
- plugins: {
13
- prettier: prettierPlugin,
14
- },
15
- languageOptions: {
16
- parserOptions: {
17
- project: './tsconfig.json',
18
- tsconfigRootDir: import.meta.dirname,
19
- },
20
- },
21
- rules: {
22
- 'prettier/prettier': 'error',
23
- '@typescript-eslint/no-explicit-any': 'warn',
24
- '@typescript-eslint/explicit-function-return-type': 'off',
25
- '@typescript-eslint/explicit-module-boundary-types': 'off',
26
- '@typescript-eslint/no-unused-vars': [
27
- 'error',
28
- {
29
- argsIgnorePattern: '^_',
30
- varsIgnorePattern: '^_',
31
- },
32
- ],
33
- '@typescript-eslint/no-floating-promises': 'error',
34
- '@typescript-eslint/no-misused-promises': 'error',
35
- '@typescript-eslint/no-unsafe-assignment': 'warn',
36
- '@typescript-eslint/no-unsafe-member-access': 'warn',
37
- '@typescript-eslint/no-unsafe-call': 'warn',
38
- '@typescript-eslint/no-unsafe-return': 'warn',
39
- '@typescript-eslint/no-unsafe-argument': 'warn',
40
- '@typescript-eslint/restrict-template-expressions': 'warn',
41
- '@typescript-eslint/ban-ts-comment': [
42
- 'error',
43
- {
44
- 'ts-nocheck': 'allow-with-description',
45
- minimumDescriptionLength: 10,
46
- },
47
- ],
48
- 'no-console': 'off',
49
- 'prefer-const': 'error',
50
- 'no-var': 'error',
51
- 'no-useless-escape': 'warn',
52
- eqeqeq: ['error', 'always'],
53
- curly: ['error', 'all'],
54
- },
55
- },
56
- {
57
- // src/module/** uses @nuxt/kit types that only resolve fully inside a real
58
- // Nuxt project. Disable the unsafe-* rules here to avoid false positives
59
- // while keeping all other rules active.
60
- files: ['src/module/**/*.ts'],
61
- rules: {
62
- '@typescript-eslint/no-unsafe-assignment': 'off',
63
- '@typescript-eslint/no-unsafe-member-access': 'off',
64
- '@typescript-eslint/no-unsafe-call': 'off',
65
- '@typescript-eslint/no-unsafe-argument': 'off',
66
- '@typescript-eslint/no-unsafe-return': 'off',
67
- },
68
- },
69
- {
70
- ignores: [
71
- 'dist/**',
72
- 'node_modules/**',
73
- 'swagger/**',
74
- 'test-*/**',
75
- 'index.ts',
76
- // Ignore runtime files - they run in user's project with different rules
77
- 'src/generators/*/runtime/**',
78
- 'src/generators/shared/runtime/**',
79
- 'src/generators/shared/templates/**',
80
- '*.js',
81
- '*.mjs',
82
- '*.cjs',
83
- ],
84
- }
85
- );
1
+ // @ts-check
2
+ import eslint from '@eslint/js';
3
+ import tseslint from 'typescript-eslint';
4
+ import prettierConfig from 'eslint-config-prettier';
5
+ import prettierPlugin from 'eslint-plugin-prettier';
6
+
7
+ export default tseslint.config(
8
+ eslint.configs.recommended,
9
+ ...tseslint.configs.recommendedTypeChecked,
10
+ prettierConfig,
11
+ {
12
+ plugins: {
13
+ prettier: prettierPlugin,
14
+ },
15
+ languageOptions: {
16
+ parserOptions: {
17
+ project: './tsconfig.json',
18
+ tsconfigRootDir: import.meta.dirname,
19
+ },
20
+ },
21
+ rules: {
22
+ 'prettier/prettier': 'error',
23
+ '@typescript-eslint/no-explicit-any': 'warn',
24
+ '@typescript-eslint/explicit-function-return-type': 'off',
25
+ '@typescript-eslint/explicit-module-boundary-types': 'off',
26
+ '@typescript-eslint/no-unused-vars': [
27
+ 'error',
28
+ {
29
+ argsIgnorePattern: '^_',
30
+ varsIgnorePattern: '^_',
31
+ },
32
+ ],
33
+ '@typescript-eslint/no-floating-promises': 'error',
34
+ '@typescript-eslint/no-misused-promises': 'error',
35
+ '@typescript-eslint/no-unsafe-assignment': 'warn',
36
+ '@typescript-eslint/no-unsafe-member-access': 'warn',
37
+ '@typescript-eslint/no-unsafe-call': 'warn',
38
+ '@typescript-eslint/no-unsafe-return': 'warn',
39
+ '@typescript-eslint/no-unsafe-argument': 'warn',
40
+ '@typescript-eslint/restrict-template-expressions': 'warn',
41
+ '@typescript-eslint/ban-ts-comment': [
42
+ 'error',
43
+ {
44
+ 'ts-nocheck': 'allow-with-description',
45
+ minimumDescriptionLength: 10,
46
+ },
47
+ ],
48
+ 'no-console': 'off',
49
+ 'prefer-const': 'error',
50
+ 'no-var': 'error',
51
+ 'no-useless-escape': 'warn',
52
+ eqeqeq: ['error', 'always'],
53
+ curly: ['error', 'all'],
54
+ },
55
+ },
56
+ {
57
+ // src/module/** uses @nuxt/kit types that only resolve fully inside a real
58
+ // Nuxt project. Disable the unsafe-* rules here to avoid false positives
59
+ // while keeping all other rules active.
60
+ files: ['src/module/**/*.ts'],
61
+ rules: {
62
+ '@typescript-eslint/no-unsafe-assignment': 'off',
63
+ '@typescript-eslint/no-unsafe-member-access': 'off',
64
+ '@typescript-eslint/no-unsafe-call': 'off',
65
+ '@typescript-eslint/no-unsafe-argument': 'off',
66
+ '@typescript-eslint/no-unsafe-return': 'off',
67
+ },
68
+ },
69
+ {
70
+ ignores: [
71
+ 'dist/**',
72
+ 'node_modules/**',
73
+ 'swagger/**',
74
+ 'test-*/**',
75
+ 'index.ts',
76
+ // Ignore runtime files - they run in user's project with different rules
77
+ 'src/generators/*/runtime/**',
78
+ 'src/generators/shared/runtime/**',
79
+ 'src/generators/shared/templates/**',
80
+ '*.js',
81
+ '*.mjs',
82
+ '*.cjs',
83
+ ],
84
+ }
85
+ );
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nuxt-openapi-hyperfetch",
3
- "version": "0.2.7-alpha.1",
3
+ "version": "0.2.8-alpha.1",
4
4
  "description": "Nuxt useFetch, useAsyncData and Nuxt server OpenAPI generator",
5
5
  "type": "module",
6
6
  "author": "",
package/src/cli/config.ts CHANGED
@@ -1,140 +1,147 @@
1
- import fs from 'fs-extra';
2
- import { join } from 'path';
3
- import * as p from '@clack/prompts';
4
- import type { GeneratorBackend, ConfigGenerator } from './types.js';
5
-
6
- const { existsSync } = fs;
7
-
8
- /**
9
- * Configuration options for the generator
10
- */
11
- export interface GeneratorConfig {
12
- /** Path or URL to OpenAPI specification */
13
- input?: string;
14
- /** Output directory for generated files */
15
- output?: string;
16
- /** Base URL for API requests */
17
- baseUrl?: string;
18
- /** Generation mode: client or server */
19
- mode?: 'client' | 'server';
20
- /** Generate only specific tags */
21
- tags?: string[];
22
- /** Exclude specific tags */
23
- excludeTags?: string[];
24
- /** Overwrite existing files without prompting */
25
- overwrite?: boolean;
26
- /** Preview changes without writing files */
27
- dryRun?: boolean;
28
- /** Enable verbose logging */
29
- verbose?: boolean;
30
- /** Watch mode - regenerate on file changes */
31
- watch?: boolean;
32
- /** Generator types to use */
33
- generators?: ('useFetch' | 'useAsyncData' | 'nuxtServer')[];
34
- /** Server route path (for nuxtServer mode) */
35
- serverRoutePath?: string;
36
- /** Enable BFF pattern (for nuxtServer mode) */
37
- enableBff?: boolean;
38
- /** Generator backend: official (Java) or heyapi (Node.js) */
39
- backend?: GeneratorBackend;
40
- /**
41
- * Generation engine to use.
42
- * - 'openapi': @openapitools/openapi-generator-cli (requires Java 11+)
43
- * - 'heyapi': @hey-api/openapi-ts (Node.js native, no Java required)
44
- * When set, the CLI will not ask which engine to use.
45
- */
46
- generator?: ConfigGenerator;
47
- }
48
-
49
- /**
50
- * Load configuration from nxh.config.js, nuxt-openapi-generator.config.js, or package.json
51
- */
52
- export async function loadConfig(cwd: string = process.cwd()): Promise<GeneratorConfig | null> {
53
- // Try different config file names
54
- const configFiles = [
55
- 'nxh.config.js',
56
- 'nxh.config.mjs',
57
- 'nuxt-openapi-hyperfetch.js',
58
- 'nuxt-openapi-hyperfetch.mjs',
59
- ];
60
-
61
- for (const configFile of configFiles) {
62
- const configPath = join(cwd, configFile);
63
- if (existsSync(configPath)) {
64
- try {
65
- // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
66
- const config = await import(`file://${configPath}`);
67
- // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-assignment
68
- const exportedConfig = config.default || config;
69
- return exportedConfig as GeneratorConfig;
70
- } catch (error) {
71
- p.log.warn(`Failed to load config from ${configFile}: ${String(error)}`);
72
- }
73
- }
74
- }
75
-
76
- // Try package.json
77
- const packageJsonPath = join(cwd, 'package.json');
78
- if (existsSync(packageJsonPath)) {
79
- try {
80
- // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
81
- const packageJson = await import(`file://${packageJsonPath}`, {
82
- assert: { type: 'json' },
83
- });
84
- // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
85
- if (packageJson.default?.['nuxt-openapi-hyperfetch']) {
86
- // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
87
- return packageJson.default['nuxt-openapi-hyperfetch'] as GeneratorConfig;
88
- }
89
- } catch {
90
- // Silently ignore package.json errors
91
- }
92
- }
93
-
94
- return null;
95
- }
96
-
97
- /**
98
- * Merge CLI options with config file, CLI takes precedence
99
- */
100
- export function mergeConfig(
101
- fileConfig: GeneratorConfig | null,
102
- cliOptions: Partial<GeneratorConfig>
103
- ): GeneratorConfig {
104
- return {
105
- ...fileConfig,
106
- ...cliOptions,
107
- // Handle arrays specially - CLI should override completely
108
- tags: cliOptions.tags || fileConfig?.tags,
109
- excludeTags: cliOptions.excludeTags || fileConfig?.excludeTags,
110
- generators: cliOptions.generators || fileConfig?.generators,
111
- };
112
- }
113
-
114
- /**
115
- * Parse comma-separated tags string into array
116
- */
117
- export function parseTags(tagsString?: string): string[] | undefined {
118
- if (!tagsString) {
119
- return undefined;
120
- }
121
- return tagsString
122
- .split(',')
123
- .map((t) => t.trim())
124
- .filter(Boolean);
125
- }
126
-
127
- /**
128
- * Parse generators string into array
129
- */
130
- export function parseGenerators(
131
- generatorsString?: string
132
- ): ('useFetch' | 'useAsyncData' | 'nuxtServer')[] | undefined {
133
- if (!generatorsString) {
134
- return undefined;
135
- }
136
- const parts = generatorsString.split(',').map((g) => g.trim());
137
- return parts.filter((g): g is 'useFetch' | 'useAsyncData' | 'nuxtServer' =>
138
- ['useFetch', 'useAsyncData', 'nuxtServer'].includes(g)
139
- );
140
- }
1
+ import fs from 'fs-extra';
2
+ import { join } from 'path';
3
+ import * as p from '@clack/prompts';
4
+ import type { GeneratorBackend, ConfigGenerator } from './types.js';
5
+
6
+ const { existsSync } = fs;
7
+
8
+ /**
9
+ * Configuration options for the generator
10
+ */
11
+ export interface GeneratorConfig {
12
+ /** Path or URL to OpenAPI specification */
13
+ input?: string;
14
+ /** Output directory for generated files */
15
+ output?: string;
16
+ /** Base URL for API requests */
17
+ baseUrl?: string;
18
+ /** Generation mode: client or server */
19
+ mode?: 'client' | 'server';
20
+ /** Generate only specific tags */
21
+ tags?: string[];
22
+ /** Exclude specific tags */
23
+ excludeTags?: string[];
24
+ /** Overwrite existing files without prompting */
25
+ overwrite?: boolean;
26
+ /** Preview changes without writing files */
27
+ dryRun?: boolean;
28
+ /** Enable verbose logging */
29
+ verbose?: boolean;
30
+ /** Watch mode - regenerate on file changes */
31
+ watch?: boolean;
32
+ /** Generator types to use */
33
+ generators?: ('useFetch' | 'useAsyncData' | 'nuxtServer' | 'connectors')[];
34
+ /** Server route path (for nuxtServer mode) */
35
+ serverRoutePath?: string;
36
+ /** Enable BFF pattern (for nuxtServer mode) */
37
+ enableBff?: boolean;
38
+ /** Generator backend: official (Java) or heyapi (Node.js) */
39
+ backend?: GeneratorBackend;
40
+ /**
41
+ * Generation engine to use.
42
+ * - 'openapi': @openapitools/openapi-generator-cli (requires Java 11+)
43
+ * - 'heyapi': @hey-api/openapi-ts (Node.js native, no Java required)
44
+ * When set, the CLI will not ask which engine to use.
45
+ */
46
+ generator?: ConfigGenerator;
47
+ /**
48
+ * Generate headless UI connector composables on top of useAsyncData.
49
+ * Connectors provide ready-made logic for tables, pagination, forms and delete actions.
50
+ * Requires useAsyncData to also be generated.
51
+ * @default false
52
+ */
53
+ createUseAsyncDataConnectors?: boolean;
54
+ }
55
+
56
+ /**
57
+ * Load configuration from nxh.config.js, nuxt-openapi-generator.config.js, or package.json
58
+ */
59
+ export async function loadConfig(cwd: string = process.cwd()): Promise<GeneratorConfig | null> {
60
+ // Try different config file names
61
+ const configFiles = [
62
+ 'nxh.config.js',
63
+ 'nxh.config.mjs',
64
+ 'nuxt-openapi-hyperfetch.js',
65
+ 'nuxt-openapi-hyperfetch.mjs',
66
+ ];
67
+
68
+ for (const configFile of configFiles) {
69
+ const configPath = join(cwd, configFile);
70
+ if (existsSync(configPath)) {
71
+ try {
72
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
73
+ const config = await import(`file://${configPath}`);
74
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-assignment
75
+ const exportedConfig = config.default || config;
76
+ return exportedConfig as GeneratorConfig;
77
+ } catch (error) {
78
+ p.log.warn(`Failed to load config from ${configFile}: ${String(error)}`);
79
+ }
80
+ }
81
+ }
82
+
83
+ // Try package.json
84
+ const packageJsonPath = join(cwd, 'package.json');
85
+ if (existsSync(packageJsonPath)) {
86
+ try {
87
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
88
+ const packageJson = await import(`file://${packageJsonPath}`, {
89
+ assert: { type: 'json' },
90
+ });
91
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
92
+ if (packageJson.default?.['nuxt-openapi-hyperfetch']) {
93
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
94
+ return packageJson.default['nuxt-openapi-hyperfetch'] as GeneratorConfig;
95
+ }
96
+ } catch {
97
+ // Silently ignore package.json errors
98
+ }
99
+ }
100
+
101
+ return null;
102
+ }
103
+
104
+ /**
105
+ * Merge CLI options with config file, CLI takes precedence
106
+ */
107
+ export function mergeConfig(
108
+ fileConfig: GeneratorConfig | null,
109
+ cliOptions: Partial<GeneratorConfig>
110
+ ): GeneratorConfig {
111
+ return {
112
+ ...fileConfig,
113
+ ...cliOptions,
114
+ // Handle arrays specially - CLI should override completely
115
+ tags: cliOptions.tags || fileConfig?.tags,
116
+ excludeTags: cliOptions.excludeTags || fileConfig?.excludeTags,
117
+ generators: cliOptions.generators || fileConfig?.generators,
118
+ };
119
+ }
120
+
121
+ /**
122
+ * Parse comma-separated tags string into array
123
+ */
124
+ export function parseTags(tagsString?: string): string[] | undefined {
125
+ if (!tagsString) {
126
+ return undefined;
127
+ }
128
+ return tagsString
129
+ .split(',')
130
+ .map((t) => t.trim())
131
+ .filter(Boolean);
132
+ }
133
+
134
+ /**
135
+ * Parse generators string into array
136
+ */
137
+ export function parseGenerators(
138
+ generatorsString?: string
139
+ ): ('useFetch' | 'useAsyncData' | 'nuxtServer' | 'connectors')[] | undefined {
140
+ if (!generatorsString) {
141
+ return undefined;
142
+ }
143
+ const parts = generatorsString.split(',').map((g) => g.trim());
144
+ return parts.filter((g): g is 'useFetch' | 'useAsyncData' | 'nuxtServer' | 'connectors' =>
145
+ ['useFetch', 'useAsyncData', 'nuxtServer', 'connectors'].includes(g)
146
+ );
147
+ }