#!/usr/bin/env node // Inline @arboretum/shared (paquet workspace NON publié) directement dans le dist du serveur, // pour que le tarball npm soit 100 % autonome. Branché sur le hook "prepack". // // Pourquoi PAS bundleDependencies : embarquer une dépendance qui est aussi un *workspace* via // bundleDependencies est instable selon l'environnement npm (mode -w, exécution en root sur un // runner CI, version d'arborist) — npm voit le nœud comme un lien workspace et n'embarque parfois // AUCUN fichier ("bundled files: 0"), produisant un paquet cassé chez le consommateur. On élimine // donc toute magie de bundling : on copie le JS compilé de shared dans dist/_shared et on réécrit // l'import bare '@arboretum/shared' du serveur vers ce chemin relatif. Zéro node_modules embarqué, // zéro symlink, résultat identique partout. import { cpSync, existsSync, mkdirSync, readdirSync, readFileSync, rmSync, writeFileSync } from 'node:fs'; import { join, dirname, relative, sep } from 'node:path'; import { fileURLToPath } from 'node:url'; const serverDir = join(dirname(fileURLToPath(import.meta.url)), '..'); const serverDist = join(serverDir, 'dist'); const sharedDist = join(serverDir, '..', 'shared', 'dist'); const inlineDir = join(serverDist, '_shared'); for (const [label, p] of [['dist serveur', serverDist], ['dist shared', sharedDist]]) { if (!existsSync(p)) { console.error(`inline-shared: ${label} introuvable (${p}) — lance "npm run build" avant le pack.`); process.exit(1); } } // 1) Copier le JS compilé de shared dans dist/_shared (uniquement *.js : seul le runtime compte ; // les .d.ts/.map ne sont de toute façon pas publiés via le glob `files`). index.js réexporte // ./protocol.js et ./api.js en relatif → la copie complète préserve la résolution interne. rmSync(inlineDir, { recursive: true, force: true }); mkdirSync(inlineDir, { recursive: true }); let copied = 0; for (const name of readdirSync(sharedDist)) { if (name.endsWith('.js')) { cpSync(join(sharedDist, name), join(inlineDir, name)); copied++; } } if (copied === 0) { console.error(`inline-shared: aucun .js dans ${sharedDist} — shared n'est pas compilé.`); process.exit(1); } // 2) Réécrire l'import bare '@arboretum/shared' de chaque .js du serveur vers le chemin relatif // (POSIX) pointant sur dist/_shared/index.js, calculé par fichier (profondeur variable). const walk = (dir) => readdirSync(dir, { withFileTypes: true }).flatMap((e) => { const p = join(dir, e.name); if (e.isDirectory()) return p === inlineDir ? [] : walk(p); // ne pas se réécrire soi-même return e.name.endsWith('.js') ? [p] : []; }); let rewritten = 0; for (const file of walk(serverDist)) { const src = readFileSync(file, 'utf8'); if (!src.includes('@arboretum/shared')) continue; let rel = relative(dirname(file), join(inlineDir, 'index.js')).split(sep).join('/'); if (!rel.startsWith('.')) rel = `./${rel}`; const out = src.replaceAll(`'@arboretum/shared'`, `'${rel}'`).replaceAll(`"@arboretum/shared"`, `"${rel}"`); if (out !== src) { writeFileSync(file, out); rewritten++; } } if (rewritten === 0) { console.error(`inline-shared: aucun import '@arboretum/shared' réécrit dans ${serverDist} — build manquant ?`); process.exit(1); } console.log(`inline-shared: ${copied} fichier(s) shared -> dist/_shared, import réécrit dans ${rewritten} fichier(s) serveur`);