nuxt-openapi-hyperfetch 0.3.81-beta → 1.0.0

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 (64) hide show
  1. package/README.md +218 -212
  2. package/dist/generators/components/connector-generator/templates.js +67 -17
  3. package/dist/generators/components/schema-analyzer/intent-detector.js +1 -12
  4. package/dist/generators/components/schema-analyzer/openapi-reader.js +10 -1
  5. package/dist/generators/components/schema-analyzer/resource-grouper.js +7 -0
  6. package/dist/generators/components/schema-analyzer/schema-field-mapper.js +1 -22
  7. package/dist/generators/components/schema-analyzer/types.d.ts +10 -0
  8. package/dist/generators/connectors/generator.d.ts +12 -0
  9. package/dist/generators/connectors/generator.js +115 -0
  10. package/dist/generators/connectors/runtime/connector-types.d.ts +147 -0
  11. package/dist/generators/connectors/runtime/connector-types.js +10 -0
  12. package/dist/generators/connectors/runtime/useCreateConnector.d.ts +26 -0
  13. package/dist/generators/connectors/runtime/useCreateConnector.js +156 -0
  14. package/dist/generators/connectors/runtime/useDeleteConnector.d.ts +30 -0
  15. package/dist/generators/connectors/runtime/useDeleteConnector.js +143 -0
  16. package/dist/generators/connectors/runtime/useGetAllConnector.d.ts +25 -0
  17. package/dist/generators/connectors/runtime/useGetAllConnector.js +127 -0
  18. package/dist/generators/connectors/runtime/useGetConnector.d.ts +15 -0
  19. package/dist/generators/connectors/runtime/useGetConnector.js +99 -0
  20. package/dist/generators/connectors/runtime/useUpdateConnector.d.ts +34 -0
  21. package/dist/generators/connectors/runtime/useUpdateConnector.js +211 -0
  22. package/dist/generators/connectors/runtime/zod-error-merger.d.ts +23 -0
  23. package/dist/generators/connectors/runtime/zod-error-merger.js +106 -0
  24. package/dist/generators/connectors/templates.d.ts +4 -0
  25. package/dist/generators/connectors/templates.js +376 -0
  26. package/dist/generators/connectors/types.d.ts +37 -0
  27. package/dist/generators/connectors/types.js +7 -0
  28. package/dist/generators/shared/runtime/useDeleteConnector.js +4 -2
  29. package/dist/generators/shared/runtime/useDetailConnector.d.ts +0 -1
  30. package/dist/generators/shared/runtime/useDetailConnector.js +9 -20
  31. package/dist/generators/shared/runtime/useFormConnector.js +4 -3
  32. package/dist/generators/use-async-data/runtime/useApiAsyncData.js +14 -5
  33. package/dist/generators/use-async-data/templates.js +20 -16
  34. package/dist/generators/use-fetch/templates.js +1 -1
  35. package/dist/index.js +1 -16
  36. package/dist/module/index.js +2 -3
  37. package/package.json +4 -3
  38. package/src/cli/prompts.ts +1 -7
  39. package/src/generators/components/connector-generator/templates.ts +97 -22
  40. package/src/generators/components/schema-analyzer/intent-detector.ts +1 -16
  41. package/src/generators/components/schema-analyzer/openapi-reader.ts +14 -1
  42. package/src/generators/components/schema-analyzer/resource-grouper.ts +9 -0
  43. package/src/generators/components/schema-analyzer/schema-field-mapper.ts +1 -26
  44. package/src/generators/components/schema-analyzer/types.ts +11 -0
  45. package/src/generators/connectors/generator.ts +137 -0
  46. package/src/generators/connectors/runtime/connector-types.ts +207 -0
  47. package/src/generators/connectors/runtime/useCreateConnector.ts +199 -0
  48. package/src/generators/connectors/runtime/useDeleteConnector.ts +179 -0
  49. package/src/generators/connectors/runtime/useGetAllConnector.ts +151 -0
  50. package/src/generators/connectors/runtime/useGetConnector.ts +120 -0
  51. package/src/generators/connectors/runtime/useUpdateConnector.ts +257 -0
  52. package/src/generators/connectors/runtime/zod-error-merger.ts +119 -0
  53. package/src/generators/connectors/templates.ts +481 -0
  54. package/src/generators/connectors/types.ts +39 -0
  55. package/src/generators/shared/runtime/useDeleteConnector.ts +4 -2
  56. package/src/generators/shared/runtime/useDetailConnector.ts +8 -19
  57. package/src/generators/shared/runtime/useFormConnector.ts +4 -3
  58. package/src/generators/use-async-data/runtime/useApiAsyncData.ts +16 -5
  59. package/src/generators/use-async-data/templates.ts +24 -16
  60. package/src/generators/use-fetch/templates.ts +1 -1
  61. package/src/index.ts +2 -19
  62. package/src/module/index.ts +2 -5
  63. package/docs/generated-components.md +0 -615
  64. package/docs/headless-composables-ui.md +0 -569
@@ -1,615 +0,0 @@
1
- # Generated Vue Components (NuxtUI) — Feature Spec & Architecture
2
-
3
- > **Status**: Planned — Capa 3 del sistema de generación de componentes Vue
4
- > **Dependencia**: Requiere Capa 1 (Schema Analyzer) y Capa 2 (Connector Generator)
5
- > **Objetivo**: Generar componentes `.vue` completamente funcionales listos para usar en producción, usando NuxtUI como librería de componentes, consumiendo los connectors headless generados en Capa 2
6
-
7
- ---
8
-
9
- ## Tabla de Contenidos
10
-
11
- - [Qué es esta feature](#qué-es-esta-feature)
12
- - [Estructura de archivos generados](#estructura-de-archivos-generados)
13
- - [El archivo index.ts — punto de personalización](#el-archivo-indexts--punto-de-personalización)
14
- - [Arquitectura de componentes por recurso](#arquitectura-de-componentes-por-recurso)
15
- - [Componentes individuales](#componentes-individuales)
16
- - [Reglas de generación y sobreescritura](#reglas-de-generación-y-sobreescritura)
17
- - [Configuración en nxh.config / nuxt.config](#configuración-en-nxhconfig--nuxtconfig)
18
- - [Estructura de archivos del generador en src/](#estructura-de-archivos-del-generador-en-src)
19
- - [Plan de implementación](#plan-de-implementación)
20
- - [Ejemplos de componentes generados](#ejemplos-de-componentes-generados)
21
- - [Añadir soporte para otros UI frameworks](#añadir-soporte-para-otros-ui-frameworks)
22
-
23
- ---
24
-
25
- ## Qué es esta feature
26
-
27
- El **Component Generator** es la Capa 3 del sistema. Toma el `ResourceMap` producido por el Schema Analyzer y los connectors headless generados por el Connector Generator, y produce **componentes `.vue` completamente funcionales** listos para ser usados en un proyecto Nuxt 3.
28
-
29
- Primera implementación: **NuxtUI** (`@nuxt/ui`).
30
-
31
- El desarrollador puede:
32
- - Usar los componentes directamente con `<PetsCrud />` o `<PetsTable />`
33
- - Personalizar labels, traducciones y overrides de campo en `index.ts` (generado una vez)
34
- - Modificar cualquier `.vue` libremente después de generarlos (son archivos del proyecto del usuario)
35
- - Importar subcomponentes individualmente (`<PetsCreate />` solo el form)
36
-
37
- ---
38
-
39
- ## Estructura de archivos generados
40
-
41
- Por defecto, los componentes se generan en `components/nxh/{resource}/`. El developer puede cambiar el directorio base en la config.
42
-
43
- Para un recurso `Pet` con CRUD completo:
44
-
45
- ```
46
- components/nxh/
47
- pets/
48
- index.ts ← generado UNA VEZ, nunca sobreescrito
49
- PetsCrud.vue ← componente principal CRUD completo
50
- table/
51
- index.vue ← tabla con columnas, paginación, botones de acción
52
- forms/
53
- PetsCreate.vue ← formulario de creación
54
- PetsUpdate.vue ← formulario de edición (pre-rellena con GET /{id})
55
- modals/
56
- PetsCreate.vue ← modal que envuelve forms/PetsCreate.vue
57
- PetsUpdate.vue ← modal que envuelve forms/PetsUpdate.vue
58
- PetsDelete.vue ← modal de confirmación de borrado
59
- ```
60
-
61
- Para un recurso solo con GET list (sin CRUD):
62
-
63
- ```
64
- components/nxh/
65
- pets/
66
- index.ts
67
- table/
68
- index.vue
69
- ```
70
-
71
- Para un recurso solo con POST (sin list):
72
-
73
- ```
74
- components/nxh/
75
- pets/
76
- index.ts
77
- forms/
78
- PetsCreate.vue
79
- modals/
80
- PetsCreate.vue
81
- ```
82
-
83
- El generador es inteligente: **solo genera los archivos que corresponden a los intents detectados**.
84
-
85
- ---
86
-
87
- ## El archivo index.ts — Punto de personalización
88
-
89
- Este archivo es el contrato entre el generador y el desarrollador.
90
-
91
- **Regla crítica: se genera UNA SOLA VEZ. Si ya existe, nunca se sobreescribe.**
92
-
93
- ```ts
94
- // components/nxh/pets/index.ts
95
- // Generated once by nxh — customize freely, this file will NOT be overwritten.
96
- // Re-run `nxh components` to regenerate the .vue files without touching this file.
97
-
98
- import type { NxhResourceConfig } from '#nxh/types'
99
-
100
- export const config: NxhResourceConfig = {
101
-
102
- // ─── Columnas de la tabla ────────────────────────────────────────────────
103
- // Generadas automáticamente del response schema del GET list.
104
- // Modifica 'label' para traducir, añade 'hidden: true' para ocultar.
105
- columns: {
106
- id: { label: 'ID', hidden: false },
107
- name: { label: 'Name' },
108
- status: { label: 'Status', type: 'badge' },
109
- createdAt: { label: 'Created At', type: 'date' },
110
- },
111
-
112
- // ─── Campos del formulario ───────────────────────────────────────────────
113
- // El tipo se infiere automáticamente del schema OpenAPI.
114
- // Sobreescribe 'type', 'label' o añade 'options' para selects personalizados.
115
- // 'errors' permite personalizar los mensajes de validación Zod por campo.
116
- fields: {
117
- name: {
118
- label: 'Name',
119
- type: 'input',
120
- errors: {
121
- required: 'Name is required', // sobreescribe el mensaje Zod
122
- min: 'Name must be at least 1 character',
123
- }
124
- },
125
- status: {
126
- label: 'Status',
127
- type: 'select',
128
- options: [ // rellena las options
129
- { label: 'Available', value: 'available' },
130
- { label: 'Sold', value: 'sold' },
131
- ],
132
- errors: {
133
- invalid_enum_value: 'Select a valid status',
134
- }
135
- },
136
- photoUrls: { label: 'Photos', type: 'input' },
137
- // Los campos readOnly: true del schema están hidden: true por defecto
138
- // id: { hidden: true }, ← generado así automáticamente
139
- },
140
-
141
- // ─── Opciones globales del recurso ───────────────────────────────────────
142
- showReadonlyFields: false, // mostrar campos readOnly en formularios
143
-
144
- // ─── Hooks de ciclo de vida ──────────────────────────────────────────────
145
- // Retornar false en onBeforeCreate/onBeforeUpdate cancela la operación.
146
- onBeforeCreate: (data) => data, // puede transformar el payload
147
- onAfterCreate: (result) => {},
148
- onBeforeUpdate: (id, data) => data,
149
- onAfterUpdate: (result) => {},
150
- onBeforeDelete: (item) => true, // return false = cancelar
151
- onAfterDelete: (item) => {},
152
- }
153
- ```
154
-
155
- Los `.vue` generados importan este `config` y lo aplican:
156
- - `table/index.vue` usa `config.columns` para las columnas y labels
157
- - `forms/PetsCreate.vue` usa `config.fields` para los inputs y labels
158
- - Todos los `.vue` invocan los hooks correspondientes de `config`
159
-
160
- ---
161
-
162
- ## Arquitectura de componentes por recurso
163
-
164
- ### Jerarquía de dependencias
165
-
166
- ```
167
- PetsCrud.vue
168
- ├── importa usePetsConnector (Capa 2)
169
- ├── importa config desde ./index.ts
170
- ├── renderiza table/index.vue
171
- │ └── usa connector.table
172
- ├── renderiza modals/PetsCreate.vue
173
- │ └── contiene forms/PetsCreate.vue
174
- │ └── usa connector.createForm
175
- ├── renderiza modals/PetsUpdate.vue
176
- │ └── contiene forms/PetsUpdate.vue
177
- │ └── usa connector.updateForm (pre-rellena con connector.detail)
178
- └── renderiza modals/PetsDelete.vue
179
- └── usa connector.deleteAction
180
- ```
181
-
182
- ### Comunicación entre componentes
183
-
184
- Los subcomponentes **no se comunican entre sí directamente**. Todo pasa por `PetsCrud.vue` mediante el connector unificado:
185
-
186
- - `table/index.vue` emite `@open-create`, `@open-update(row)`, `@open-delete(row)`
187
- - `PetsCrud.vue` escucha esos eventos y abre el modal correspondiente
188
- - Cuando un form hace submit con éxito, cierra el modal y llama `connector.table.refresh()`
189
-
190
- Esto permite usar `table/index.vue` de forma independiente sin necesitar `PetsCrud.vue`.
191
-
192
- ---
193
-
194
- ## Componentes individuales
195
-
196
- ### `table/index.vue`
197
-
198
- Responsabilidades:
199
- - Mostrar `UTable` con las columnas de `config.columns`
200
- - Columnas con `type: 'badge'` → `UBadge`; `type: 'date'` → fecha formateada
201
- - Fila de acciones al final: botón Edit (abre modal update), botón Delete (abre modal delete)
202
- - Paginación con `UPagination` si `connector.table.pagination` está activo
203
- - Botón "New" en el header de la tabla (abre modal create)
204
- - Loading state con skeleton rows
205
- - Estado vacío con slot `empty` personalizable
206
-
207
- Props:
208
- ```ts
209
- defineProps<{
210
- connector: ListConnectorReturn<any>
211
- config: NxhResourceConfig
212
- }>()
213
- defineEmits(['open-create', 'open-update', 'open-delete'])
214
- ```
215
-
216
- ### `forms/PetsCreate.vue` y `forms/PetsUpdate.vue`
217
-
218
- Responsabilidades:
219
- - Renderizar cada campo de `config.fields` con el componente NuxtUI correspondiente
220
- - `type: 'input'` → `UInput`
221
- - `type: 'textarea'` → `UTextarea`
222
- - `type: 'select'` → `USelect`
223
- - `type: 'checkbox'` → `UCheckbox`
224
- - `type: 'number'` → `UInput type="number"`
225
- - `type: 'datepicker'`→ `UInput type="date"` (o librería de fecha si disponible)
226
- - Mostrar errores de validación por campo con `UFormField`
227
- - Botón Submit con loading state
228
- - `PetsUpdate.vue` usa `connector.updateForm` que pre-rellena automáticamente si existe `connector.detail`
229
-
230
- Ejemplo de template generado con manejo de errores Zod vía `UFormField`:
231
-
232
- ```vue
233
- <!-- forms/PetsCreate.vue (generado) -->
234
- <template>
235
- <UForm @submit="connector.submit()">
236
- <template v-for="field in connector.fields" :key="field.name">
237
- <UFormField
238
- :label="field.label"
239
- :error="connector.errors[field.name]"
240
- >
241
- <!-- el error viene de Zod.safeParse → mergeado con config.fields[name].errors -->
242
- <UInput
243
- v-if="field.type === 'input'"
244
- v-model="connector.model[field.name]"
245
- />
246
- <USelect
247
- v-else-if="field.type === 'select'"
248
- v-model="connector.model[field.name]"
249
- :options="field.options"
250
- />
251
- <!-- ...otros tipos... -->
252
- </UFormField>
253
- </template>
254
- <UButton type="submit" :loading="connector.loading">Save</UButton>
255
- </UForm>
256
- </template>
257
- ```
258
-
259
- `connector.errors` es `Ref<Record<string, string>>` expuesto por `useFormConnector` tras `schema.safeParse()`. Si el campo no tiene error, el valor es `undefined` y `UFormField` no muestra nada.
260
-
261
- Props:
262
- ```ts
263
- defineProps<{
264
- connector: FormConnectorReturn<any>
265
- config: NxhResourceConfig
266
- }>()
267
- ```
268
-
269
- ### `modals/PetsCreate.vue` y `modals/PetsUpdate.vue`
270
-
271
- Wrapper simple de `UModal` + `UCard` que envuelve el form correspondiente.
272
-
273
- ```vue
274
- <template>
275
- <UModal v-model="isOpen">
276
- <UCard>
277
- <template #header>Create Pet</template>
278
- <PetsCreateForm :connector="connector.createForm" :config="config" />
279
- </UCard>
280
- </UModal>
281
- </template>
282
- ```
283
-
284
- El estado `isOpen` es manejado por `PetsCrud.vue`, no por el modal.
285
-
286
- ### `modals/PetsDelete.vue`
287
-
288
- Modal de confirmación. No usa form.
289
-
290
- ```vue
291
- <template>
292
- <UModal v-model="isOpen">
293
- <UCard>
294
- <template #header>Confirm Delete</template>
295
- <p>Are you sure you want to delete this item?</p>
296
- <template #footer>
297
- <UButton color="red" :loading="connector.deleteAction.loading.value"
298
- @click="connector.deleteAction.confirm()">
299
- Delete
300
- </UButton>
301
- <UButton variant="ghost" @click="connector.deleteAction.cancel()">
302
- Cancel
303
- </UButton>
304
- </template>
305
- </UCard>
306
- </UModal>
307
- </template>
308
- ```
309
-
310
- ### `PetsCrud.vue`
311
-
312
- Componente orquestador. Gestiona:
313
- - El estado de qué modal está abierto (`createOpen`, `updateOpen`, `deleteOpen`)
314
- - Escucha eventos de `table/index.vue` para abrir modales
315
- - Llama `table.refresh()` cuando un form tiene éxito
316
- - Invoca hooks `config.onBeforeCreate`, `config.onAfterCreate`, etc.
317
-
318
- ```vue
319
- <script setup>
320
- import { ref } from 'vue'
321
- import { usePetsConnector } from '~/composables/connectors/usePetsConnector'
322
- import { config } from './index'
323
- import PetsTable from './table/index.vue'
324
- import PetsCreateModal from './modals/PetsCreate.vue'
325
- import PetsUpdateModal from './modals/PetsUpdate.vue'
326
- import PetsDeleteModal from './modals/PetsDelete.vue'
327
-
328
- const connector = usePetsConnector()
329
-
330
- const createOpen = ref(false)
331
- const updateOpen = ref(false)
332
- const deleteOpen = ref(false)
333
-
334
- connector.createForm.onSuccess.value = () => {
335
- createOpen.value = false
336
- connector.table.refresh()
337
- config.onAfterCreate?.(connector.createForm.model.value)
338
- }
339
-
340
- connector.updateForm.onSuccess.value = () => {
341
- updateOpen.value = false
342
- connector.table.refresh()
343
- config.onAfterUpdate?.(connector.updateForm.model.value)
344
- }
345
-
346
- connector.deleteAction.onSuccess.value = () => {
347
- deleteOpen.value = false
348
- connector.table.refresh()
349
- config.onAfterDelete?.(connector.deleteAction.target.value)
350
- }
351
- </script>
352
-
353
- <template>
354
- <PetsTable
355
- :connector="connector.table"
356
- :config="config"
357
- @open-create="createOpen = true"
358
- @open-update="(row) => { connector.updateForm.setValues(row); updateOpen = true }"
359
- @open-delete="(row) => { connector.deleteAction.setTarget(row); deleteOpen = true }"
360
- />
361
- <PetsCreateModal v-model="createOpen" :connector="connector" :config="config" />
362
- <PetsUpdateModal v-model="updateOpen" :connector="connector" :config="config" />
363
- <PetsDeleteModal v-model="deleteOpen" :connector="connector" :config="config" />
364
- </template>
365
- ```
366
-
367
- ---
368
-
369
- ## Reglas de generación y sobreescritura
370
-
371
- | Archivo | Se genera | Se sobreescribe en re-run |
372
- |-----------------------------|------------------|---------------------------|
373
- | `index.ts` | Solo si no existe | **NUNCA** |
374
- | `PetsCrud.vue` | Siempre | Sí |
375
- | `table/index.vue` | Siempre | Sí |
376
- | `forms/PetsCreate.vue` | Siempre | Sí |
377
- | `forms/PetsUpdate.vue` | Siempre | Sí |
378
- | `modals/PetsCreate.vue` | Siempre | Sí |
379
- | `modals/PetsUpdate.vue` | Siempre | Sí |
380
- | `modals/PetsDelete.vue` | Siempre | Sí |
381
-
382
- Si el developer modifica un `.vue` generado y no quiere que se sobreescriba: lo mueve a un directorio fuera de `components/nxh/` y actualiza sus imports.
383
-
384
- ---
385
-
386
- ## Configuración en nxh.config / nuxt.config
387
-
388
- ```js
389
- // nxh.config.js
390
- export default {
391
- // ... config existente
392
-
393
- components: {
394
- // Override de intent para endpoints ambiguos
395
- 'GET /pets/search': { intent: 'list' },
396
-
397
- // Configuración por recurso
398
- pets: {
399
- outputDir: 'components/admin/pets', // directorio custom
400
- showReadonlyFields: true, // mostrar campos readOnly
401
- ui: 'nuxtui', // framework UI (default: 'nuxtui')
402
- },
403
-
404
- // Excluir un recurso de la generación
405
- internalLogs: { skip: true },
406
- }
407
- }
408
- ```
409
-
410
- En `nuxt.config.ts` (cuando se usa como módulo Nuxt):
411
-
412
- ```ts
413
- export default defineNuxtConfig({
414
- nxh: {
415
- components: {
416
- 'GET /pets/search': { intent: 'list' },
417
- pets: {
418
- outputDir: 'components/admin/pets',
419
- }
420
- }
421
- }
422
- })
423
- ```
424
-
425
- ---
426
-
427
- ## Estructura de archivos del generador en src/
428
-
429
- ```
430
- src/
431
- generators/
432
- components/
433
- schema-analyzer/ ← Capa 1 (ver headless-composables-ui.md)
434
- connector-generator/ ← Capa 2 (ver headless-composables-ui.md)
435
- vue-generator/ ← ESTA FEATURE (Capa 3)
436
- index.ts ← entry point
437
- types.ts ← ComponentPlan, ComponentFile, UIAdapter
438
- generator.ts ← orquesta la generación de todos los .vue
439
- config-generator.ts ← genera el index.ts (si no existe)
440
- adapters/
441
- nuxtui/
442
- index.ts ← entry point del adaptador NuxtUI
443
- table.ts ← template de table/index.vue con UTable
444
- form-create.ts ← template de forms/PetsCreate.vue
445
- form-update.ts ← template de forms/PetsUpdate.vue
446
- modal-create.ts ← template de modals/PetsCreate.vue
447
- modal-update.ts ← template de modals/PetsUpdate.vue
448
- modal-delete.ts ← template de modals/PetsDelete.vue
449
- crud.ts ← template de PetsCrud.vue
450
- field-mapper.ts ← FormFieldDef → componente NuxtUI string
451
- primevue/ ← para implementación futura
452
- index.ts
453
- ...
454
- ```
455
-
456
- Cada función en `adapters/nuxtui/*.ts` recibe un `ComponentPlan` (datos del recurso) y devuelve un `string` con el contenido del archivo `.vue`.
457
-
458
- ---
459
-
460
- ## Plan de implementación
461
-
462
- ### Fase 1 — Tipos y contratos del vue-generator
463
-
464
- **Archivo:** `src/generators/components/vue-generator/types.ts`
465
-
466
- ```ts
467
- interface ComponentPlan {
468
- resourceName: string // 'Pet'
469
- resourceNamePlural: string // 'Pets'
470
- connectorImportPath: string // '~/composables/connectors/usePetsConnector'
471
- configImportPath: string // './index'
472
- columns: ColumnDef[]
473
- formFields: FormFieldDef[]
474
- intents: Intent[] // ['list', 'create', 'update', 'delete']
475
- hasPagination: boolean
476
- hasDetail: boolean
477
- }
478
-
479
- interface UIAdapter {
480
- name: string
481
- generateTable(plan: ComponentPlan): string
482
- generateFormCreate(plan: ComponentPlan): string
483
- generateFormUpdate(plan: ComponentPlan): string
484
- generateModalCreate(plan: ComponentPlan): string
485
- generateModalUpdate(plan: ComponentPlan): string
486
- generateModalDelete(plan: ComponentPlan): string
487
- generateCrud(plan: ComponentPlan): string
488
- generateConfig(plan: ComponentPlan): string
489
- }
490
- ```
491
-
492
- ### Fase 2 — Adaptador NuxtUI
493
-
494
- **Archivos:** `src/generators/components/vue-generator/adapters/nuxtui/`
495
-
496
- Implementar cada función de `UIAdapter` produciendo strings con el template Vue correcto. Cada función es pura: `(plan: ComponentPlan) => string`.
497
-
498
- Orden de implementación:
499
- 1. `field-mapper.ts` — mapea `FormFieldDef.type` → componente NuxtUI correcto
500
- 2. `table.ts` — genera `table/index.vue` con `UTable`, `UPagination`, botones
501
- 3. `form-create.ts` — genera `forms/PetsCreate.vue` con `UForm`, `UFormField`
502
- 4. `form-update.ts` — igual que create pero con `loadWith`
503
- 5. `modal-create.ts`, `modal-update.ts`, `modal-delete.ts` — wrappers `UModal`
504
- 6. `crud.ts` — orquestador principal
505
- 7. `config-generator.ts` — genera `index.ts` (con columnas y campos inferidos como punto de partida)
506
-
507
- ### Fase 3 — Generator principal
508
-
509
- **Archivo:** `src/generators/components/vue-generator/generator.ts`
510
-
511
- ```ts
512
- export async function generateVueComponents(
513
- resourceMap: ResourceMap,
514
- outputBaseDir: string,
515
- adapter: UIAdapter,
516
- options: { overwriteConfig?: boolean } = {}
517
- ): Promise<void>
518
- ```
519
-
520
- Por cada recurso en `resourceMap`:
521
- 1. Construye el `ComponentPlan`
522
- 2. Determina qué archivos generar según los intents
523
- 3. Para `index.ts`: escribe solo si no existe (a menos que `overwriteConfig: true`)
524
- 4. Formatea cada archivo con Prettier antes de escribir
525
- 5. Reporta progreso con `@clack/prompts`
526
-
527
- ### Fase 4 — Integración en CLI
528
-
529
- Nuevo flag en el comando `generate` existente:
530
- ```
531
- --components <ui> Generate Vue components with specified UI framework (nuxtui)
532
- ```
533
-
534
- O subcomando separado (preferible para no sobrecargar `generate`):
535
- ```
536
- nxh components --input swagger.yaml --output ./components/nxh --ui nuxtui
537
- ```
538
-
539
- ---
540
-
541
- ## Ejemplos de componentes generados
542
-
543
- ### Uso básico — solo importar PetsCrud
544
-
545
- ```vue
546
- <!-- pages/admin/pets.vue -->
547
- <template>
548
- <div>
549
- <h1>Pets Management</h1>
550
- <PetsCrud />
551
- </div>
552
- </template>
553
- ```
554
-
555
- ### Solo la tabla, sin modales
556
-
557
- ```vue
558
- <!-- pages/dashboard.vue -->
559
- <script setup>
560
- import PetsTable from '~/components/nxh/pets/table/index.vue'
561
- import { usePetsConnector } from '~/composables/connectors/usePetsConnector'
562
- import { config } from '~/components/nxh/pets/index'
563
-
564
- const { table } = usePetsConnector()
565
- </script>
566
-
567
- <template>
568
- <PetsTable :connector="table" :config="config" />
569
- </template>
570
- ```
571
-
572
- ### Solo el formulario de creación en una página dedicada
573
-
574
- ```vue
575
- <!-- pages/pets/new.vue -->
576
- <script setup>
577
- import PetsCreateForm from '~/components/nxh/pets/forms/PetsCreate.vue'
578
- import { usePetsConnector } from '~/composables/connectors/usePetsConnector'
579
- import { config } from '~/components/nxh/pets/index'
580
-
581
- const { createForm } = usePetsConnector()
582
-
583
- createForm.onSuccess.value = () => navigateTo('/pets')
584
- </script>
585
-
586
- <template>
587
- <PetsCreateForm :connector="createForm" :config="config" />
588
- </template>
589
- ```
590
-
591
- ---
592
-
593
- ## Añadir soporte para otros UI frameworks
594
-
595
- Para añadir soporte para PrimeVue, Vuetify, Shadcn-vue, etc., se crea una nueva carpeta en `adapters/`:
596
-
597
- ```
598
- adapters/
599
- primevue/
600
- index.ts ← exporta un objeto UIAdapter
601
- table.ts ← usa DataTable, Column de PrimeVue
602
- form-create.ts ← usa InputText, Dropdown, etc.
603
- ...
604
- ```
605
-
606
- El `generator.ts` es idéntico para todos los adaptadores. Solo cambia qué `UIAdapter` se le pasa.
607
-
608
- El CLI expondrá:
609
- ```
610
- nxh components --ui primevue
611
- nxh components --ui nuxtui (default)
612
- nxh components --ui shadcn
613
- ```
614
-
615
- Esto permite que la comunidad contribuya nuevos adaptadores sin tocar el core del generador.