nuxt-feathers-zod 0.2.4 → 0.2.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,166 +1,193 @@
1
- # nuxt-feathers-zod
1
+ # nuxt-feathers-zod
2
+ [guide](https://vevedh.github.io/nuxt-feathers-zod/)
2
3
 
3
- > **Nuxt 4 (Nitro) + FeathersJS v5 (Dove) + Zod** — un module “tout‑en‑un” (site + API) avec **CLI**.
4
+ ### Guide officiel d’initialisation – Nuxt 4 (Bun, Feathers v5, Zod)
4
5
 
5
- `nuxt-feathers-zod` embarque un **backend Feathers** dans une app **Nuxt 4**. Tu construis une app web **et** une API dans le même projet, avec :
6
+ Ce guide décrit **la seule procédure valide et supportée** pour initialiser correctement **nuxt-feathers-zod** dans un projet **Nuxt 4**, en se basant **strictement sur le comportement réel du module**.
6
7
 
7
- - Services **Zod-first** (validation `data`/`query` + types)
8
- - ✅ REST sous un préfixe (par défaut `/feathers`) via **Koa** ou **Express**
9
- - ✅ Client DX : `useService()` + stores Pinia (via `feathers-pinia`)
10
- - ✅ Swagger legacy (optionnel)
11
- - ✅ **Keycloak-only SSO** (optionnel) : `check-sso` ou `login-required` via `onLoad`
12
- - ✅ Composable unifié **`useAuth()`** (optimisation) : même API en Keycloak-only ou auth locale
8
+ Il évite volontairement toute “magie implicite” ou création manuelle non supportée.
13
9
 
14
10
  ---
15
11
 
16
- ## TL;DR (Nuxt 4)
12
+ ## 1. Objectif du module
17
13
 
18
- 1. Installer :
14
+ `nuxt-feathers-zod` permet d’embarquer un **backend FeathersJS v5 (Dove)** directement dans **Nitro**, avec :
19
15
 
20
- ```bash
21
- bun add nuxt-feathers-zod feathers-pinia
22
- ```
23
-
24
- 2. Configurer Nuxt :
25
-
26
- ```ts
27
- export default defineNuxtConfig({
28
- modules: ['nuxt-feathers-zod'],
16
+ * API REST (`/feathers/*`)
17
+ * WebSocket (Socket.IO)
18
+ * Validation **Zod-first**
19
+ * Authentification **Local + JWT**
20
+ * Adapters (MongoDB, Memory, etc.)
21
+ * Swagger legacy (optionnel)
22
+ * Composables client (`useService`, `useAuth`, stores Pinia)
29
23
 
30
- feathers: {
31
- // RÈGLE D’OR : le module scanne uniquement ces dossiers
32
- servicesDirs: ['services'],
24
+ 👉 Il **n’y a pas de backend séparé** : Feathers est monté **dans Nuxt**.
33
25
 
34
- transports: {
35
- rest: { path: '/feathers', framework: 'koa' },
36
- websocket: true,
37
- },
26
+ ---
38
27
 
39
- database: {
40
- mongo: { url: 'mongodb://127.0.0.1:27017/my-site' },
41
- },
28
+ ## 2. Pré-requis
42
29
 
43
- // Auth locale (JWT) OU Keycloak-only (voir plus bas)
44
- auth: true,
30
+ * **Bun** (recommandé et supporté)
31
+ * **Node.js ≥ 18**
32
+ * **Nuxt 4**
33
+ * MongoDB (optionnel mais recommandé)
45
34
 
46
- // Swagger legacy (optionnel)
47
- swagger: { enabled: false },
48
- },
49
- })
50
- ```
35
+ ---
51
36
 
52
- 3. Générer les services **via la CLI** (ne pas créer à la main) :
37
+ ## 3. Création du projet Nuxt 4
53
38
 
54
39
  ```bash
55
- bunx nuxt-feathers-zod add service users --adapter mongodb --auth --idField _id --docs
56
- bunx nuxt-feathers-zod add service articles --adapter mongodb --auth --idField _id --docs
40
+ bunx nuxi@latest init my-site
41
+ cd my-site
42
+ bun install
43
+ bun run dev
57
44
  ```
58
45
 
59
- ---
60
-
61
- ## Prérequis
62
-
63
- - **Bun** (recommandé)
64
- - Node.js ≥ 18
65
- - Nuxt 4
46
+ ➡️ Vérifie que Nuxt démarre **avant toute intégration Feathers**.
66
47
 
67
48
  ---
68
49
 
69
- ## Installation
50
+ ## 4. Installation des dépendances
51
+
52
+ ### 4.1 Module principal
70
53
 
71
54
  ```bash
72
55
  bun add nuxt-feathers-zod feathers-pinia
73
56
  ```
74
57
 
75
- ### Swagger legacy (optionnel)
58
+ ### 4.2 (Optionnel) Swagger legacy
76
59
 
77
60
  ```bash
78
61
  bun add feathers-swagger swagger-ui-dist
79
62
  ```
80
63
 
81
- > Si `feathers.swagger.enabled = true` mais que `feathers-swagger` n’est pas installé dans l’app Nuxt, le module affiche un warning DX au démarrage.
64
+ > ⚠️ `swagger-ui-dist` est requis si `feathers.swagger = true`
82
65
 
83
66
  ---
84
67
 
85
- ## Règle fondamentale : services générés uniquement via CLI
68
+ ## 5. Configuration **obligatoire** (`nuxt.config.ts`)
86
69
 
87
- Toujours :
70
+ > ⚠️ **Cette configuration est critique**.
71
+ > Une mauvaise initialisation provoque des erreurs bloquantes au démarrage.
88
72
 
89
- ```bash
90
- bunx nuxt-feathers-zod add service <name> ...
91
- ```
73
+ ```ts
74
+ export default defineNuxtConfig({
75
+ modules: ['nuxt-feathers-zod'],
76
+
77
+ feathers: {
78
+ /**
79
+ * RÈGLE D’OR :
80
+ * Le module scanne UNIQUEMENT ces dossiers
81
+ */
82
+ servicesDirs: ['services'],
83
+
84
+ /**
85
+ * Transports
86
+ */
87
+ transports: {
88
+ rest: {
89
+ path: '/feathers',
90
+ framework: 'koa',
91
+ },
92
+ websocket: true,
93
+ },
92
94
 
93
- ❌ Ne pas créer manuellement `services/<name>`.
95
+ /**
96
+ * Base de données (MongoDB recommandé)
97
+ */
98
+ database: {
99
+ mongo: {
100
+ url: 'mongodb://127.0.0.1:27017/my-site',
101
+ },
102
+ },
94
103
 
95
- Pourquoi : le module génère les imports/types à partir de `servicesDirs`. Si un service n’est pas généré selon la structure attendue, tu peux déclencher des erreurs du type :
104
+ /**
105
+ * Authentification
106
+ */
107
+ auth: true,
96
108
 
97
- - `Services typeExports []`
98
- - `Entity class User not found`
109
+ /**
110
+ * Swagger legacy (optionnel)
111
+ */
112
+ swagger: false,
113
+ },
114
+ })
115
+ ```
99
116
 
100
117
  ---
101
118
 
102
- ## Configuration Nuxt
119
+ ## 6. RÈGLE FONDAMENTALE – À NE JAMAIS VIOLER
103
120
 
104
- ### Options essentielles
121
+ > **Ne jamais créer un service manuellement**
122
+ > ✅ **Toujours utiliser la CLI officielle**
105
123
 
106
- - `feathers.servicesDirs` : **obligatoire**
107
- - `feathers.transports.rest.path` : préfixe REST (ex `/feathers`)
108
- - `feathers.database.mongo.url` : MongoDB (si adapter mongodb)
124
+ Cette règle est **imposée par le code interne du module**.
109
125
 
110
126
  ---
111
127
 
112
- ## Auth : concept important (ne pas mélanger)
128
+ ## 7. Création du premier service : `users` (OBLIGATOIRE)
113
129
 
114
- Le module supporte 2 approches :
115
-
116
- 1. **Auth locale Feathers (JWT)** : `feathers.auth = true` + service `users` + endpoint `/feathers/authentication`.
117
- 2. **Keycloak-only SSO** : `feathers.keycloak = { ... }` + plugin client `keycloak-js`, pas de login Feathers.
130
+ ```bash
131
+ bunx nuxt-feathers-zod add service users \
132
+ --adapter mongodb \
133
+ --auth \
134
+ --idField _id \
135
+ --docs
136
+ ```
118
137
 
119
- 👉 Ces deux providers ne partagent pas le même token ni la même session. C’est la raison pour laquelle on a ajouté **`useAuth()`** : une seule API côté frontend.
138
+ ### Structure générée (attendue)
120
139
 
121
- ---
140
+ ```
141
+ services/users/
142
+ users.ts
143
+ users.class.ts
144
+ users.schema.ts
145
+ users.shared.ts
146
+ ```
122
147
 
123
- ## `useAuth()` : API unifiée (recommandé)
148
+ ### Pourquoi `users` est obligatoire ?
124
149
 
125
- ### Pourquoi ?
150
+ * Le module **résout l’authentification** via une `entityClass` nommée **`User`**
151
+ * Cette classe est **recherchée dynamiquement** dans les exports scannés
152
+ * Sans ce service :
126
153
 
127
- - En Keycloak-only, `useAuthStore()` (auth locale) n’est pas initialisé.
128
- - En auth locale, `$keycloak` n’existe pas.
129
- - Mélanger les deux dans la même page revient à avoir **deux sources de vérité** et des headers `Authorization` concurrents.
154
+ * `Services typeExports []`
155
+ * `Entity class User not found in services imports`
156
+ * **Boot impossible**
130
157
 
131
- ### Usage
158
+ 👉 Le service `users` est la **clé de voûte** de tout projet `nuxt-feathers-zod`.
132
159
 
133
- ```ts
134
- const auth = useAuth()
135
- await auth.init()
160
+ ---
136
161
 
137
- if (!auth.isAuthenticated.value) {
138
- await auth.login()
139
- }
162
+ ## 8. Création d’un service métier (exemple : `articles`)
140
163
 
141
- console.log(auth.provider.value) // 'keycloak' | 'local' | 'none'
142
- console.log(auth.user.value)
164
+ ```bash
165
+ bunx nuxt-feathers-zod add service articles \
166
+ --adapter mongodb \
167
+ --auth \
168
+ --idField _id \
169
+ --docs
143
170
  ```
144
171
 
145
- > ⚠️ Attention : `feathers-pinia` expose aussi un `useAuth`. Évite d’importer `useAuth` depuis `feathers-pinia` dans une app Nuxt utilisant `nuxt-feathers-zod`. Si tu en as besoin, importe-le avec alias :
146
- >
147
- > ```ts
148
- > import { useAuth as useFeathersAuth } from 'feathers-pinia'
149
- > ```
172
+ Structure :
150
173
 
151
- ---
174
+ ```
175
+ services/articles/
176
+ articles.ts
177
+ articles.class.ts
178
+ articles.schema.ts
179
+ articles.shared.ts
180
+ ```
152
181
 
153
- ## Auth locale (Local + JWT)
182
+ ---
154
183
 
155
- ### 1) Générer `users` (obligatoire)
184
+ ## 9. Démarrage et tests REST
156
185
 
157
186
  ```bash
158
- bunx nuxt-feathers-zod add service users --adapter mongodb --auth --idField _id --docs
187
+ bun run dev
159
188
  ```
160
189
 
161
- ### 2) Tests REST
162
-
163
- Créer un utilisateur :
190
+ ### 9.1 Création d’un utilisateur
164
191
 
165
192
  ```bash
166
193
  curl -X POST http://localhost:3000/feathers/users \
@@ -168,7 +195,7 @@ curl -X POST http://localhost:3000/feathers/users \
168
195
  -d '{"userId":"demo","password":"demo123"}'
169
196
  ```
170
197
 
171
- Login :
198
+ ### 9.2 Authentification
172
199
 
173
200
  ```bash
174
201
  curl -X POST http://localhost:3000/feathers/authentication \
@@ -176,7 +203,7 @@ curl -X POST http://localhost:3000/feathers/authentication \
176
203
  -d '{"strategy":"local","userId":"demo","password":"demo123"}'
177
204
  ```
178
205
 
179
- Appel protégé :
206
+ ### 9.3 Accès à un service protégé
180
207
 
181
208
  ```bash
182
209
  curl http://localhost:3000/feathers/articles \
@@ -185,134 +212,101 @@ curl http://localhost:3000/feathers/articles \
185
212
 
186
213
  ---
187
214
 
188
- ## Keycloak-only SSO (Option A)
189
-
190
- ### Objectif
215
+ ## 10. Swagger legacy (optionnel)
191
216
 
192
- - Au démarrage : `check-sso` (pas de redirection forcée)
193
- - Routes protégées : middleware Nuxt qui appelle `login()` seulement quand nécessaire
194
-
195
- ### Configuration Nuxt
217
+ ### 10.1 Activer Swagger
196
218
 
197
219
  ```ts
198
- export default defineNuxtConfig({
199
- feathers: {
200
- // active le mode Keycloak-only
201
- keycloak: {
202
- serverUrl: 'https://svrkeycloak.agglo.local:8443',
203
- realm: 'AGGLO',
204
- clientId: 'nuxt4app',
205
-
206
- // Option ajoutée : onLoad
207
- onLoad: 'check-sso', // ou 'login-required'
208
-
209
- // bridge service Feathers (whoami)
210
- authServicePath: '/_keycloak',
211
-
212
- // si tu veux une persistance user : userService + serviceIdField
213
- userService: 'users',
214
- serviceIdField: 'keycloakId',
215
-
216
- permissions: false,
217
- },
218
- },
219
- })
220
+ feathers: {
221
+ swagger: true,
222
+ }
220
223
  ```
221
224
 
222
- ### Fichier requis pour `check-sso`
225
+ ### 10.2 Accès
223
226
 
224
- Créer : `public/silent-check-sso.html`
227
+ * UI :
228
+ `http://localhost:3000/feathers/docs/`
229
+ * Spec :
230
+ `http://localhost:3000/feathers/swagger.json`
225
231
 
226
- ```html
227
- <!doctype html>
228
- <html>
229
- <body>
230
- <script>
231
- parent.postMessage(location.href, location.origin)
232
- </script>
233
- </body>
234
- </html>
235
- ```
232
+ ### ⚠️ Important
236
233
 
237
- ### Les services Feathers protégés fonctionnent-ils ?
234
+ Dans l’UI Swagger, la spec doit être définie manuellement à :
238
235
 
239
- ✅ Oui, si :
236
+ ```
237
+ ../swagger.json
238
+ ```
240
239
 
241
- - côté client, le plugin Keycloak injecte `Authorization: Bearer <kc_token>` dans les appels Feathers
242
- - côté serveur, le hook Keycloak valide le JWT (JWKS) et remplit `context.params.user`
240
+ (C’est un comportement connu et assumé du module.)
243
241
 
244
242
  ---
245
243
 
246
- ## Frontend : `useService()` (feathers-pinia)
244
+ ## 11. Plugins serveur Feathers (seed, hooks globaux)
247
245
 
248
- Exemple : liste d’articles :
246
+ ### Exemple : `server/feathers/dummy.ts`
249
247
 
250
- ```vue
251
- <script setup lang="ts">
252
- import { useService } from 'feathers-pinia'
253
-
254
- const { data, find, isPending } = useService('articles')
255
-
256
- await find({ query: { $limit: 10 } })
257
- </script>
258
-
259
- <template>
260
- <div>
261
- <div v-if="isPending">
262
- Chargement…
263
- </div>
264
- <pre v-else>{{ data }}</pre>
265
- </div>
266
- </template>
248
+ ```ts
249
+ import { defineFeathersServerPlugin } from 'nuxt-feathers-zod/server'
250
+
251
+ export default defineFeathersServerPlugin((app) => {
252
+ app.hooks({
253
+ setup: [
254
+ async (context, next) => {
255
+ await context.app.service('users').create({
256
+ userId: 'admin',
257
+ password: 'admin123',
258
+ })
259
+ await next()
260
+ },
261
+ ],
262
+ })
263
+ })
267
264
  ```
268
265
 
269
- ---
270
-
271
- ## Swagger legacy
272
-
273
- - UI : `/feathers/docs/`
274
- - Spec : `/feathers/swagger.json` (souvent consommée via `../swagger.json` depuis l’UI)
266
+ ➡️ Ces fichiers sont des **plugins Feathers**, pas des services.
275
267
 
276
268
  ---
277
269
 
278
- ## Playground (monorepo)
270
+ ## 12. Erreurs courantes et causes réelles
279
271
 
280
- ### Windows / ESM
272
+ ### `Services typeExports []`
281
273
 
282
- Référencer toujours le module avec extension :
274
+ Causes :
283
275
 
284
- ```ts
285
- modules: ['../src/module.ts']
286
- ```
276
+ * `servicesDirs` incorrect
277
+ * services créés manuellement
278
+ * fichiers mal nommés (`users.ts` manquant)
287
279
 
288
- ### vue-tsc / vite-plugin-checker
280
+ ### `Entity class User not found in services imports`
289
281
 
290
- Si tu vois :
282
+ Cause exacte :
291
283
 
292
- - `Cannot find global type 'Array'` / `lib.dom.d.ts not found`
284
+ * le service `users` n’existe pas ou n’a pas été généré via la CLI
293
285
 
294
- Alors désactive le typecheck dans le playground :
286
+ Solution universelle :
295
287
 
296
- ```ts
297
- typescript: { typeCheck: false }
288
+ ```bash
289
+ bunx nuxt-feathers-zod add service users
298
290
  ```
299
291
 
300
- Et garde le typecheck au root via un script dédié.
301
-
302
292
  ---
303
293
 
304
- ## Documentation (VitePress)
305
-
306
- Lancer la doc :
294
+ ## 13. Bonnes pratiques figées
307
295
 
308
- ```bash
309
- bun run docs:dev
310
- ```
296
+ * ✅ **Toujours** générer les services avec la CLI
297
+ * `services/<name>/<name>.ts` obligatoire
298
+ * ✅ Zod-first (`*.schema.ts`)
299
+ * ❌ Pas de création manuelle
300
+ * ❌ Pas de renommage arbitraire de `User`
301
+ * ❌ Pas de déplacement hors `servicesDirs`
311
302
 
312
303
  ---
313
304
 
314
- ## Scripts utiles
305
+ ## 14. Résumé express (checklist)
315
306
 
316
- - `bun run dev` : lance le playground
317
- - `bun run prepare` : build du module (`nuxt-module-build prepare && build`)
318
- - `bun run docs:dev` : doc VitePress
307
+ 1. `bunx nuxi init`
308
+ 2. `bun add nuxt-feathers-zod feathers-pinia`
309
+ 3. `servicesDirs: ['services']`
310
+ 4. `bunx nuxt-feathers-zod add service users`
311
+ 5. `bunx nuxt-feathers-zod add service <business>`
312
+ 6. `bun run dev`
File without changes
package/dist/module.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "compatibility": {
5
5
  "nuxt": "^4.0.0"
6
6
  },
7
- "version": "0.2.4",
7
+ "version": "0.2.5",
8
8
  "builder": {
9
9
  "@nuxt/module-builder": "1.0.2",
10
10
  "unbuild": "3.6.1"
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "nuxt-feathers-zod",
3
3
  "type": "module",
4
- "version": "0.2.4",
4
+ "version": "0.2.5",
5
5
  "packageManager": "bun@1.3.6",
6
6
  "description": "Feathers API integration for Nuxt",
7
7
  "author": "Herve de CHAVIGNY",