Service d'upload/download de fichiers
Ce starter CLI crée un service Feathers adapter-less prêt pour :
- upload local via
upload(data) - download via
download({ id }) - listing via
find() - lecture des métadonnées via
get(id) - suppression via
remove(id)
Le stockage est local sur disque, dans un dossier configurable. Le starter est pensé comme une base claire et auto-hébergée pour Nuxt 4 + NFZ, pas comme un remplacement direct d'un stockage objet type S3.
Pré-requis : créer d'abord une app Nuxt 4
bunx nuxi@latest init my-nfz-files
cd my-nfz-files
bun install
bun add nuxt-feathers-zod
bun add -D @pinia/nuxtGénération du service
bunx nuxt-feathers-zod init embedded --force
bunx nuxt-feathers-zod add file-service assets --path api/v1/assets --storageDir storage/assets
bun devContrat du starter
Upload
await api.service('api/v1/assets').upload({
fileName: 'hello.txt',
mimeType: 'text/plain',
dataBase64: btoa('hello world'),
metadata: { folder: 'docs' },
})Download
await api.service('api/v1/assets').download({ id: '8d42d7d5-b6a5-4d1e-a6f1-62096a55b7ab' })Le résultat renvoie les métadonnées du fichier et dataBase64.
Les identifiants autres que des UUID sont rejetés avant toute résolution de chemin. Le fichier .bin et son descripteur .json doivent rester des enfants directs du dossier de stockage configuré.
Options utiles
bunx nuxt-feathers-zod add file-service assets \
--path api/v1/assets \
--storageDir storage/assets \
--auth \
--docs--path: path Feathers du service--storageDir: dossier local de stockage--auth: protège le service par JWT--docs: ajoute la métadonnée Swagger legacy
Limites et garde-fous du starter
Le starter généré reste volontairement local et simple. Dans *.class.ts, il ajoute désormais :
- un contrôle de taille maximale configurable (
<serviceName>MaxBytesounfzFileMaxBytes) - une allowlist MIME configurable (
<serviceName>AllowedMimeTypesounfzFileAllowedMimeTypes) - une validation stricte des identifiants UUID pour
get,removeetdownload - un contrôle de confinement du chemin final après
resolve() - une limite sur la longueur Base64 avant décodage, puis une validation Base64 canonique
- une normalisation du nom de fichier avant écriture disque
Les clés utilisent le nom complet du service. Pour attachments, configure donc attachmentsMaxBytes. Les anciennes clés singulières comme attachmentMaxBytes restent reconnues uniquement comme fallback de compatibilité. La valeur est relue à chaque opération.
Exemple d'usage côté app :
export default defineNuxtConfig({
hooks: {
"app:created"(app) {
app.set("assetsMaxBytes", 20 * 1024 * 1024)
app.set("assetsAllowedMimeTypes", ["image/png", "image/jpeg", "application/pdf"])
},
},
})Ce que ce starter ne couvre pas encore
Ce starter est une base locale auto-hébergée, pas une brique objet-storage complète. Il ne couvre pas encore :
- multipart/form-data
- streaming/range download
- stockage S3 / MinIO / OVH Object Storage
- signed URLs
- antivirus / DLP
- ownership avancé / quotas
Quand tu dépasses ce périmètre, garde le contrat Feathers upload() / download() mais remplace l'implémentation de stockage.
Flux de travail recommandé dans le repo module
Pour travailler sur le repo du module lui-même, préfère :
bun run clean:repo
bun installet évite bun run clean:repo avant installation, qui suppose déjà @nuxt/kit présent localement.
