From cbfce996ed6154d77d8990f580d40127ef025ee8 Mon Sep 17 00:00:00 2001 From: Nicolas Date: Wed, 16 Sep 2026 19:27:42 +0200 Subject: [PATCH] =?UTF-8?q?fix(server):=20rendre=20les=20chemins=20par=20d?= =?UTF-8?q?=C3=A9faut=20ind=C3=A9pendants=20du=20cwd?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CLIENT_DIST_PATH et TMP_DIR se résolvaient via process.cwd(), donc uniquement correct si le process est lancé depuis server/. Repéré en mettant en place la prévisualisation locale (.claude/launch.json, non versionné) : npm --prefix server run dev depuis la racine du dépôt ne change pas le cwd du script lancé, `npm --prefix server exec -- node -e "console.log(process.cwd())"` le confirme (reste la racine du dépôt). Résout désormais les deux chemins depuis l'emplacement du module (import.meta.url) plutôt que process.cwd() - invariant quel que soit le répertoire de lancement, y compris en Docker. Co-Authored-By: Claude Sonnet 5 --- server/src/config.ts | 14 +++++++++++--- spec/architecture.md | 2 +- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/server/src/config.ts b/server/src/config.ts index 64433b4..adb1852 100644 --- a/server/src/config.ts +++ b/server/src/config.ts @@ -1,4 +1,5 @@ import { resolve } from 'node:path'; +import { fileURLToPath } from 'node:url'; /** * Configuration runtime du serveur, dérivée des variables d'environnement. @@ -16,11 +17,18 @@ export interface ServerConfig { readonly maxConcurrentDownloads: number; } +// Dossier contenant ce module compilé (server/dist/ en prod, server/src/ sous +// tsx en dev - même profondeur sous server/ dans les deux cas). Sert de base +// aux chemins par défaut ci-dessous : contrairement à process.cwd(), invariant +// quel que soit le répertoire depuis lequel le process a été lancé (ex. `npm +// --prefix server run dev` depuis la racine du dépôt ne change pas le cwd). +const here = fileURLToPath(new URL('.', import.meta.url)); + /** * Construit la configuration du serveur à partir des variables d'environnement, * en appliquant des valeurs par défaut adaptées au développement local (le * client compilé et le dossier temporaire sont alors supposés voisins de - * `server/`). + * `server/`, indépendamment du répertoire de travail courant). * * @returns La configuration runtime résolue. */ @@ -31,8 +39,8 @@ export function loadConfig(): ServerConfig { return { port: Number.isNaN(parsedPort) ? 3000 : parsedPort, host: process.env.HOST ?? '0.0.0.0', - clientDistPath: process.env.CLIENT_DIST_PATH ?? resolve(process.cwd(), '../client/dist'), - tmpDir: process.env.TMP_DIR ?? resolve(process.cwd(), 'tmp'), + clientDistPath: process.env.CLIENT_DIST_PATH ?? resolve(here, '../../client/dist'), + tmpDir: process.env.TMP_DIR ?? resolve(here, '../tmp'), maxConcurrentDownloads: Number.isNaN(parsedConcurrency) || parsedConcurrency < 1 ? 2 : parsedConcurrency, }; diff --git a/spec/architecture.md b/spec/architecture.md index 5d48641..818c18b 100644 --- a/spec/architecture.md +++ b/spec/architecture.md @@ -18,7 +18,7 @@ Pas de `docker-compose.yml` pour l'instant (une seule image, pas encore de dépe - Fastify 5, TypeScript strict, ESM (`"type": "module"`, imports relatifs en `.js`, résolution `NodeNext`). - `src/index.ts` : bootstrap (plugins, écoute, arrêt propre SIGINT/SIGTERM). -- `src/config.ts` : configuration runtime depuis l'environnement (`PORT`, `HOST`, `CLIENT_DIST_PATH`). +- `src/config.ts` : configuration runtime depuis l'environnement (`PORT`, `HOST`, `CLIENT_DIST_PATH`, `TMP_DIR`, `MAX_CONCURRENT_DOWNLOADS`). Les valeurs par défaut de `CLIENT_DIST_PATH`/`TMP_DIR` sont résolues depuis l'emplacement du module (`import.meta.url`), pas `process.cwd()` : reste correct quel que soit le répertoire depuis lequel le process est lancé (ex. `npm --prefix server run dev` depuis la racine du dépôt, utilisé par `.claude/launch.json` pour la prévisualisation - non versionné, voir `.gitignore`). - `src/routes/` : routes Fastify enregistrées comme plugins (`health.ts`, `channel.ts`, `queue.ts`). Chaque domaine métier suit le même principe : un plugin de route fin sous `src/routes/`, qui délègue à un service sous `src/services/`. - `src/services/` : - `ytDlpRunner.ts` : exécution bas niveau de yt-dlp (`node:child_process.spawn`, jamais de shell - arguments toujours passés en tableau, jamais concaténés dans une chaîne, pour exclure toute injection de commande). Supporte le suivi ligne par ligne de stdout (`onStdoutLine`, pour la progression) et l'annulation via `AbortSignal`.