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
@@ -1,254 +1,254 @@
1
- import { pascalCase, kebabCase } from 'change-case';
2
- import type { ResourceInfo } from '../schema-analyzer/types.js';
3
-
4
- // ─── File header ──────────────────────────────────────────────────────────────
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
- // ─── Naming helpers ───────────────────────────────────────────────────────────
23
-
24
- /**
25
- * operationId → useAsyncData composable name.
26
- * 'getPets' → 'useAsyncDataGetPets'
27
- */
28
- function toAsyncDataName(operationId: string): string {
29
- return `useAsyncData${pascalCase(operationId)}`;
30
- }
31
-
32
- /**
33
- * composable name → kebab-case file name (without .ts).
34
- * 'useAsyncDataGetPets' → 'use-async-data-get-pets'
35
- */
36
- function toFileName(composableName: string): string {
37
- return kebabCase(composableName);
38
- }
39
-
40
- // ─── Section builders ─────────────────────────────────────────────────────────
41
-
42
- /**
43
- * Build all `import` lines for a resource connector.
44
- */
45
- function buildImports(resource: ResourceInfo, composablesRelDir: string): string {
46
- const lines: string[] = [];
47
-
48
- // zod
49
- lines.push(`import { z } from 'zod';`);
50
- lines.push('');
51
-
52
- // runtime helpers (Nuxt alias — set up by the Nuxt module)
53
- const runtimeHelpers: string[] = [];
54
- if (resource.listEndpoint) {
55
- runtimeHelpers.push('useListConnector');
56
- }
57
- if (resource.detailEndpoint) {
58
- runtimeHelpers.push('useDetailConnector');
59
- }
60
- if (resource.createEndpoint || resource.updateEndpoint) {
61
- runtimeHelpers.push('useFormConnector');
62
- }
63
- if (resource.deleteEndpoint) {
64
- runtimeHelpers.push('useDeleteConnector');
65
- }
66
-
67
- for (const helper of runtimeHelpers) {
68
- lines.push(`import { ${helper} } from '#nxh/runtime/${helper}';`);
69
- }
70
- lines.push('');
71
-
72
- // generated useAsyncData composables
73
- const addImport = (operationId: string): void => {
74
- const name = toAsyncDataName(operationId);
75
- const file = toFileName(name);
76
- lines.push(`import { ${name} } from '${composablesRelDir}/${file}';`);
77
- };
78
-
79
- if (resource.listEndpoint) {
80
- addImport(resource.listEndpoint.operationId);
81
- }
82
- if (resource.detailEndpoint) {
83
- addImport(resource.detailEndpoint.operationId);
84
- }
85
- if (resource.createEndpoint) {
86
- addImport(resource.createEndpoint.operationId);
87
- }
88
- if (resource.updateEndpoint) {
89
- addImport(resource.updateEndpoint.operationId);
90
- }
91
- if (resource.deleteEndpoint) {
92
- addImport(resource.deleteEndpoint.operationId);
93
- }
94
-
95
- return lines.join('\n');
96
- }
97
-
98
- /**
99
- * Build Zod schema const declarations.
100
- */
101
- function buildZodSchemas(resource: ResourceInfo): string {
102
- const lines: string[] = [];
103
- const pascal = pascalCase(resource.name);
104
-
105
- if (resource.zodSchemas.create) {
106
- lines.push(`const ${pascal}CreateSchema = ${resource.zodSchemas.create};`);
107
- lines.push('');
108
- }
109
- if (resource.zodSchemas.update) {
110
- lines.push(`const ${pascal}UpdateSchema = ${resource.zodSchemas.update};`);
111
- lines.push('');
112
- }
113
-
114
- // Derive TS types via z.infer
115
- if (resource.zodSchemas.create) {
116
- lines.push(`type ${pascal}CreateInput = z.infer<typeof ${pascal}CreateSchema>;`);
117
- }
118
- if (resource.zodSchemas.update) {
119
- lines.push(`type ${pascal}UpdateInput = z.infer<typeof ${pascal}UpdateSchema>;`);
120
- }
121
-
122
- return lines.join('\n');
123
- }
124
-
125
- /**
126
- * Build the body of the exported connector function.
127
- */
128
- function buildFunctionBody(resource: ResourceInfo): string {
129
- const pascal = pascalCase(resource.name);
130
- const subConnectors: string[] = [];
131
-
132
- if (resource.listEndpoint) {
133
- const fn = toAsyncDataName(resource.listEndpoint.operationId);
134
- // paginated: true tells useListConnector to expose pagination helpers
135
- // (goToPage, nextPage, prevPage, setPerPage, pagination ref).
136
- // We set it whenever the spec declares a list endpoint that has a response schema,
137
- // which is a reliable proxy for "this API returns structured data worth paginating".
138
- const opts = resource.listEndpoint.responseSchema ? '{ paginated: true }' : '{}';
139
- subConnectors.push(` const table = useListConnector(${fn}, ${opts});`);
140
- }
141
-
142
- if (resource.detailEndpoint) {
143
- const fn = toAsyncDataName(resource.detailEndpoint.operationId);
144
- subConnectors.push(` const detail = useDetailConnector(${fn});`);
145
- }
146
-
147
- if (resource.createEndpoint) {
148
- const fn = toAsyncDataName(resource.createEndpoint.operationId);
149
- const schemaArg = resource.zodSchemas.create ? `{ schema: ${pascal}CreateSchema }` : '{}';
150
- subConnectors.push(` const createForm = useFormConnector(${fn}, ${schemaArg});`);
151
- }
152
-
153
- if (resource.updateEndpoint) {
154
- const fn = toAsyncDataName(resource.updateEndpoint.operationId);
155
- const hasDetail = !!resource.detailEndpoint;
156
-
157
- // Build the options argument for useFormConnector:
158
- // schema → Zod schema for client-side validation before submission
159
- // loadWith → reference to the detail connector so the form auto-fills
160
- // when detail.item changes (user clicks "Edit" on a row)
161
- //
162
- // Four combinations are possible depending on what the spec provides:
163
- let schemaArg = '{}';
164
- if (resource.zodSchemas.update && hasDetail) {
165
- // Best case: validate AND pre-fill from detail
166
- schemaArg = `{ schema: ${pascal}UpdateSchema, loadWith: detail }`;
167
- } else if (resource.zodSchemas.update) {
168
- // Validate, but no detail endpoint to pre-fill from
169
- schemaArg = `{ schema: ${pascal}UpdateSchema }`;
170
- } else if (hasDetail) {
171
- // No Zod schema (no request body in spec), but still pre-fill from detail
172
- schemaArg = `{ loadWith: detail }`;
173
- }
174
- subConnectors.push(` const updateForm = useFormConnector(${fn}, ${schemaArg});`);
175
- }
176
-
177
- if (resource.deleteEndpoint) {
178
- const fn = toAsyncDataName(resource.deleteEndpoint.operationId);
179
- subConnectors.push(` const deleteAction = useDeleteConnector(${fn});`);
180
- }
181
-
182
- // Return object — only include what was built
183
- const returnKeys: string[] = [];
184
- if (resource.listEndpoint) {
185
- returnKeys.push('table');
186
- }
187
- if (resource.detailEndpoint) {
188
- returnKeys.push('detail');
189
- }
190
- if (resource.createEndpoint) {
191
- returnKeys.push('createForm');
192
- }
193
- if (resource.updateEndpoint) {
194
- returnKeys.push('updateForm');
195
- }
196
- if (resource.deleteEndpoint) {
197
- returnKeys.push('deleteAction');
198
- }
199
-
200
- const returnStatement = ` return { ${returnKeys.join(', ')} };`;
201
-
202
- return [
203
- `export function ${resource.composableName}() {`,
204
- ...subConnectors,
205
- returnStatement,
206
- `}`,
207
- ].join('\n');
208
- }
209
-
210
- // ─── Public API ───────────────────────────────────────────────────────────────
211
-
212
- /**
213
- * Generate the full source of a `use{Resource}Connector.ts` file.
214
- *
215
- * @param resource ResourceInfo produced by Schema Analyzer
216
- * @param composablesRelDir Relative path from the connector dir to the
217
- * useAsyncData composables dir (e.g. '../use-async-data')
218
- */
219
- export function generateConnectorFile(resource: ResourceInfo, composablesRelDir: string): string {
220
- const header = generateFileHeader();
221
- const imports = buildImports(resource, composablesRelDir);
222
- const schemas = buildZodSchemas(resource);
223
- const fn = buildFunctionBody(resource);
224
-
225
- // Assemble file: header + imports + (optional) Zod blocks + function body.
226
- // Each section ends with its own trailing newline; join with \n adds one blank
227
- // line between sections, which matches Prettier's output for this structure.
228
- const parts: string[] = [header, imports];
229
- if (schemas.trim()) {
230
- parts.push(schemas);
231
- }
232
- parts.push(fn);
233
-
234
- return parts.join('\n') + '\n';
235
- }
236
-
237
- /**
238
- * Derive the output filename for a connector.
239
- * 'usePetsConnector' → 'use-pets-connector.ts'
240
- */
241
- export function connectorFileName(composableName: string): string {
242
- return `${kebabCase(composableName)}.ts`;
243
- }
244
-
245
- /**
246
- * Generate an index barrel file that re-exports all connectors.
247
- */
248
- export function generateConnectorIndexFile(composableNames: string[]): string {
249
- const header = generateFileHeader();
250
- const exports = composableNames
251
- .map((name) => `export { ${name} } from './${kebabCase(name)}';`)
252
- .join('\n');
253
- return `${header}${exports}\n`;
254
- }
1
+ import { pascalCase, kebabCase } from 'change-case';
2
+ import type { ResourceInfo } from '../schema-analyzer/types.js';
3
+
4
+ // ─── File header ──────────────────────────────────────────────────────────────
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
+ // ─── Naming helpers ───────────────────────────────────────────────────────────
23
+
24
+ /**
25
+ * operationId → useAsyncData composable name.
26
+ * 'getPets' → 'useAsyncDataGetPets'
27
+ */
28
+ function toAsyncDataName(operationId: string): string {
29
+ return `useAsyncData${pascalCase(operationId)}`;
30
+ }
31
+
32
+ /**
33
+ * composable name → kebab-case file name (without .ts).
34
+ * 'useAsyncDataGetPets' → 'use-async-data-get-pets'
35
+ */
36
+ function toFileName(composableName: string): string {
37
+ return kebabCase(composableName);
38
+ }
39
+
40
+ // ─── Section builders ─────────────────────────────────────────────────────────
41
+
42
+ /**
43
+ * Build all `import` lines for a resource connector.
44
+ */
45
+ function buildImports(resource: ResourceInfo, composablesRelDir: string): string {
46
+ const lines: string[] = [];
47
+
48
+ // zod
49
+ lines.push(`import { z } from 'zod';`);
50
+ lines.push('');
51
+
52
+ // runtime helpers (Nuxt alias — set up by the Nuxt module)
53
+ const runtimeHelpers: string[] = [];
54
+ if (resource.listEndpoint) {
55
+ runtimeHelpers.push('useListConnector');
56
+ }
57
+ if (resource.detailEndpoint) {
58
+ runtimeHelpers.push('useDetailConnector');
59
+ }
60
+ if (resource.createEndpoint || resource.updateEndpoint) {
61
+ runtimeHelpers.push('useFormConnector');
62
+ }
63
+ if (resource.deleteEndpoint) {
64
+ runtimeHelpers.push('useDeleteConnector');
65
+ }
66
+
67
+ for (const helper of runtimeHelpers) {
68
+ lines.push(`import { ${helper} } from '#nxh/runtime/${helper}';`);
69
+ }
70
+ lines.push('');
71
+
72
+ // generated useAsyncData composables
73
+ const addImport = (operationId: string): void => {
74
+ const name = toAsyncDataName(operationId);
75
+ const file = toFileName(name);
76
+ lines.push(`import { ${name} } from '${composablesRelDir}/${file}';`);
77
+ };
78
+
79
+ if (resource.listEndpoint) {
80
+ addImport(resource.listEndpoint.operationId);
81
+ }
82
+ if (resource.detailEndpoint) {
83
+ addImport(resource.detailEndpoint.operationId);
84
+ }
85
+ if (resource.createEndpoint) {
86
+ addImport(resource.createEndpoint.operationId);
87
+ }
88
+ if (resource.updateEndpoint) {
89
+ addImport(resource.updateEndpoint.operationId);
90
+ }
91
+ if (resource.deleteEndpoint) {
92
+ addImport(resource.deleteEndpoint.operationId);
93
+ }
94
+
95
+ return lines.join('\n');
96
+ }
97
+
98
+ /**
99
+ * Build Zod schema const declarations.
100
+ */
101
+ function buildZodSchemas(resource: ResourceInfo): string {
102
+ const lines: string[] = [];
103
+ const pascal = pascalCase(resource.name);
104
+
105
+ if (resource.zodSchemas.create) {
106
+ lines.push(`const ${pascal}CreateSchema = ${resource.zodSchemas.create};`);
107
+ lines.push('');
108
+ }
109
+ if (resource.zodSchemas.update) {
110
+ lines.push(`const ${pascal}UpdateSchema = ${resource.zodSchemas.update};`);
111
+ lines.push('');
112
+ }
113
+
114
+ // Derive TS types via z.infer
115
+ if (resource.zodSchemas.create) {
116
+ lines.push(`type ${pascal}CreateInput = z.infer<typeof ${pascal}CreateSchema>;`);
117
+ }
118
+ if (resource.zodSchemas.update) {
119
+ lines.push(`type ${pascal}UpdateInput = z.infer<typeof ${pascal}UpdateSchema>;`);
120
+ }
121
+
122
+ return lines.join('\n');
123
+ }
124
+
125
+ /**
126
+ * Build the body of the exported connector function.
127
+ */
128
+ function buildFunctionBody(resource: ResourceInfo): string {
129
+ const pascal = pascalCase(resource.name);
130
+ const subConnectors: string[] = [];
131
+
132
+ if (resource.listEndpoint) {
133
+ const fn = toAsyncDataName(resource.listEndpoint.operationId);
134
+ // paginated: true tells useListConnector to expose pagination helpers
135
+ // (goToPage, nextPage, prevPage, setPerPage, pagination ref).
136
+ // We set it whenever the spec declares a list endpoint that has a response schema,
137
+ // which is a reliable proxy for "this API returns structured data worth paginating".
138
+ const opts = resource.listEndpoint.responseSchema ? '{ paginated: true }' : '{}';
139
+ subConnectors.push(` const table = useListConnector(${fn}, ${opts});`);
140
+ }
141
+
142
+ if (resource.detailEndpoint) {
143
+ const fn = toAsyncDataName(resource.detailEndpoint.operationId);
144
+ subConnectors.push(` const detail = useDetailConnector(${fn});`);
145
+ }
146
+
147
+ if (resource.createEndpoint) {
148
+ const fn = toAsyncDataName(resource.createEndpoint.operationId);
149
+ const schemaArg = resource.zodSchemas.create ? `{ schema: ${pascal}CreateSchema }` : '{}';
150
+ subConnectors.push(` const createForm = useFormConnector(${fn}, ${schemaArg});`);
151
+ }
152
+
153
+ if (resource.updateEndpoint) {
154
+ const fn = toAsyncDataName(resource.updateEndpoint.operationId);
155
+ const hasDetail = !!resource.detailEndpoint;
156
+
157
+ // Build the options argument for useFormConnector:
158
+ // schema → Zod schema for client-side validation before submission
159
+ // loadWith → reference to the detail connector so the form auto-fills
160
+ // when detail.item changes (user clicks "Edit" on a row)
161
+ //
162
+ // Four combinations are possible depending on what the spec provides:
163
+ let schemaArg = '{}';
164
+ if (resource.zodSchemas.update && hasDetail) {
165
+ // Best case: validate AND pre-fill from detail
166
+ schemaArg = `{ schema: ${pascal}UpdateSchema, loadWith: detail }`;
167
+ } else if (resource.zodSchemas.update) {
168
+ // Validate, but no detail endpoint to pre-fill from
169
+ schemaArg = `{ schema: ${pascal}UpdateSchema }`;
170
+ } else if (hasDetail) {
171
+ // No Zod schema (no request body in spec), but still pre-fill from detail
172
+ schemaArg = `{ loadWith: detail }`;
173
+ }
174
+ subConnectors.push(` const updateForm = useFormConnector(${fn}, ${schemaArg});`);
175
+ }
176
+
177
+ if (resource.deleteEndpoint) {
178
+ const fn = toAsyncDataName(resource.deleteEndpoint.operationId);
179
+ subConnectors.push(` const deleteAction = useDeleteConnector(${fn});`);
180
+ }
181
+
182
+ // Return object — only include what was built
183
+ const returnKeys: string[] = [];
184
+ if (resource.listEndpoint) {
185
+ returnKeys.push('table');
186
+ }
187
+ if (resource.detailEndpoint) {
188
+ returnKeys.push('detail');
189
+ }
190
+ if (resource.createEndpoint) {
191
+ returnKeys.push('createForm');
192
+ }
193
+ if (resource.updateEndpoint) {
194
+ returnKeys.push('updateForm');
195
+ }
196
+ if (resource.deleteEndpoint) {
197
+ returnKeys.push('deleteAction');
198
+ }
199
+
200
+ const returnStatement = ` return { ${returnKeys.join(', ')} };`;
201
+
202
+ return [
203
+ `export function ${resource.composableName}() {`,
204
+ ...subConnectors,
205
+ returnStatement,
206
+ `}`,
207
+ ].join('\n');
208
+ }
209
+
210
+ // ─── Public API ───────────────────────────────────────────────────────────────
211
+
212
+ /**
213
+ * Generate the full source of a `use{Resource}Connector.ts` file.
214
+ *
215
+ * @param resource ResourceInfo produced by Schema Analyzer
216
+ * @param composablesRelDir Relative path from the connector dir to the
217
+ * useAsyncData composables dir (e.g. '../use-async-data')
218
+ */
219
+ export function generateConnectorFile(resource: ResourceInfo, composablesRelDir: string): string {
220
+ const header = generateFileHeader();
221
+ const imports = buildImports(resource, composablesRelDir);
222
+ const schemas = buildZodSchemas(resource);
223
+ const fn = buildFunctionBody(resource);
224
+
225
+ // Assemble file: header + imports + (optional) Zod blocks + function body.
226
+ // Each section ends with its own trailing newline; join with \n adds one blank
227
+ // line between sections, which matches Prettier's output for this structure.
228
+ const parts: string[] = [header, imports];
229
+ if (schemas.trim()) {
230
+ parts.push(schemas);
231
+ }
232
+ parts.push(fn);
233
+
234
+ return parts.join('\n') + '\n';
235
+ }
236
+
237
+ /**
238
+ * Derive the output filename for a connector.
239
+ * 'usePetsConnector' → 'use-pets-connector.ts'
240
+ */
241
+ export function connectorFileName(composableName: string): string {
242
+ return `${kebabCase(composableName)}.ts`;
243
+ }
244
+
245
+ /**
246
+ * Generate an index barrel file that re-exports all connectors.
247
+ */
248
+ export function generateConnectorIndexFile(composableNames: string[]): string {
249
+ const header = generateFileHeader();
250
+ const exports = composableNames
251
+ .map((name) => `export { ${name} } from './${kebabCase(name)}';`)
252
+ .join('\n');
253
+ return `${header}${exports}\n`;
254
+ }
@@ -1,34 +1,34 @@
1
- /**
2
- * Types for the Connector Generator — Fase 3.
3
- *
4
- * The Connector Generator reads the ResourceMap produced by the Schema Analyzer
5
- * and writes one `use{Resource}Connector.ts` file per resource.
6
- */
7
-
8
- export interface ConnectorGeneratorOptions {
9
- /** Absolute or relative path to the OpenAPI YAML/JSON spec */
10
- inputSpec: string;
11
- /** Directory where connector files will be written. E.g. ./composables/connectors */
12
- outputDir: string;
13
- /**
14
- * Directory where the useAsyncData composables live, expressed as a path
15
- * relative to outputDir. Defaults to '../use-async-data'.
16
- */
17
- composablesRelDir?: string;
18
- /**
19
- * Directory where runtime helpers will be copied to, expressed relative to
20
- * outputDir. Defaults to '../runtime'.
21
- */
22
- runtimeRelDir?: string;
23
- }
24
-
25
- export interface ConnectorFileInfo {
26
- /** PascalCase resource name. E.g. 'Pet' */
27
- resourceName: string;
28
- /** Generated composable function name. E.g. 'usePetsConnector' */
29
- composableName: string;
30
- /** Output filename (kebab-case). E.g. 'use-pets-connector.ts' */
31
- fileName: string;
32
- /** Formatted TypeScript source ready to be written to disk */
33
- content: string;
34
- }
1
+ /**
2
+ * Types for the Connector Generator — Fase 3.
3
+ *
4
+ * The Connector Generator reads the ResourceMap produced by the Schema Analyzer
5
+ * and writes one `use{Resource}Connector.ts` file per resource.
6
+ */
7
+
8
+ export interface ConnectorGeneratorOptions {
9
+ /** Absolute or relative path to the OpenAPI YAML/JSON spec */
10
+ inputSpec: string;
11
+ /** Directory where connector files will be written. E.g. ./composables/connectors */
12
+ outputDir: string;
13
+ /**
14
+ * Directory where the useAsyncData composables live, expressed as a path
15
+ * relative to outputDir. Defaults to '../use-async-data'.
16
+ */
17
+ composablesRelDir?: string;
18
+ /**
19
+ * Directory where runtime helpers will be copied to, expressed relative to
20
+ * outputDir. Defaults to '../runtime'.
21
+ */
22
+ runtimeRelDir?: string;
23
+ }
24
+
25
+ export interface ConnectorFileInfo {
26
+ /** PascalCase resource name. E.g. 'Pet' */
27
+ resourceName: string;
28
+ /** Generated composable function name. E.g. 'usePetsConnector' */
29
+ composableName: string;
30
+ /** Output filename (kebab-case). E.g. 'use-pets-connector.ts' */
31
+ fileName: string;
32
+ /** Formatted TypeScript source ready to be written to disk */
33
+ content: string;
34
+ }
@@ -1,44 +1,44 @@
1
- /**
2
- * Schema Analyzer — entry point
3
- *
4
- * Usage:
5
- * import { analyzeSpec } from './schema-analyzer/index.js'
6
- * const resourceMap = analyzeSpec('./swagger.yaml')
7
- */
8
-
9
- export { readOpenApiSpec } from './openapi-reader.js';
10
- export { detectIntent, extractEndpoints } from './intent-detector.js';
11
- export { buildResourceMap } from './resource-grouper.js';
12
- export {
13
- mapFieldsFromSchema,
14
- mapColumnsFromSchema,
15
- buildZodSchema,
16
- zodExpressionFromProp,
17
- } from './schema-field-mapper.js';
18
- export type {
19
- OpenApiSpec,
20
- OpenApiSchema,
21
- OpenApiPropertySchema,
22
- OpenApiOperation,
23
- OpenApiParameter,
24
- EndpointInfo,
25
- ResourceInfo,
26
- ResourceMap,
27
- FormFieldDef,
28
- ColumnDef,
29
- Intent,
30
- FieldType,
31
- ColumnType,
32
- } from './types.js';
33
-
34
- import { readOpenApiSpec } from './openapi-reader.js';
35
- import { buildResourceMap } from './resource-grouper.js';
36
- import type { ResourceMap } from './types.js';
37
-
38
- /**
39
- * Convenience function: read a spec file and return the full ResourceMap.
40
- */
41
- export function analyzeSpec(specPath: string): ResourceMap {
42
- const spec = readOpenApiSpec(specPath);
43
- return buildResourceMap(spec);
44
- }
1
+ /**
2
+ * Schema Analyzer — entry point
3
+ *
4
+ * Usage:
5
+ * import { analyzeSpec } from './schema-analyzer/index.js'
6
+ * const resourceMap = analyzeSpec('./swagger.yaml')
7
+ */
8
+
9
+ export { readOpenApiSpec } from './openapi-reader.js';
10
+ export { detectIntent, extractEndpoints } from './intent-detector.js';
11
+ export { buildResourceMap } from './resource-grouper.js';
12
+ export {
13
+ mapFieldsFromSchema,
14
+ mapColumnsFromSchema,
15
+ buildZodSchema,
16
+ zodExpressionFromProp,
17
+ } from './schema-field-mapper.js';
18
+ export type {
19
+ OpenApiSpec,
20
+ OpenApiSchema,
21
+ OpenApiPropertySchema,
22
+ OpenApiOperation,
23
+ OpenApiParameter,
24
+ EndpointInfo,
25
+ ResourceInfo,
26
+ ResourceMap,
27
+ FormFieldDef,
28
+ ColumnDef,
29
+ Intent,
30
+ FieldType,
31
+ ColumnType,
32
+ } from './types.js';
33
+
34
+ import { readOpenApiSpec } from './openapi-reader.js';
35
+ import { buildResourceMap } from './resource-grouper.js';
36
+ import type { ResourceMap } from './types.js';
37
+
38
+ /**
39
+ * Convenience function: read a spec file and return the full ResourceMap.
40
+ */
41
+ export function analyzeSpec(specPath: string): ResourceMap {
42
+ const spec = readOpenApiSpec(specPath);
43
+ return buildResourceMap(spec);
44
+ }