#!/usr/bin/env node /** * ───────────────────────────────────────────── * SPB Drive — Personal Cloud Drive * ───────────────────────────────────────────── * Author : Simon-Pierre Boucher * Contact : contact@spboucher.ai * File : scripts/inject-headers.mjs * Purpose : Prepend the canonical author header to any tracked file missing it * License : MIT © Simon-Pierre Boucher * ───────────────────────────────────────────── */ import { execSync } from 'node:child_process'; import { readFileSync, writeFileSync } from 'node:fs'; const LINES = (file, purpose) => [ '─────────────────────────────────────────────', ' SPB Drive — Personal Cloud Drive', '─────────────────────────────────────────────', ' Author : Simon-Pierre Boucher', ' Contact : contact@spboucher.ai', ` File : ${file}`, ` Purpose : ${purpose}`, ' License : MIT © Simon-Pierre Boucher', '─────────────────────────────────────────────', ]; /** Comment wrappers per extension family. */ const STYLES = { block: (lines) => `/**\n${lines.map((l) => ` * ${l}`.trimEnd()).join('\n')}\n */\n\n`, hash: (lines) => `${lines.map((l) => `# ${l}`.trimEnd()).join('\n')}\n\n`, html: (lines) => `\n\n`, sql: (lines) => `${lines.map((l) => `-- ${l}`.trimEnd()).join('\n')}\n\n`, }; const EXT_STYLE = { '.js': 'block', '.mjs': 'block', '.cjs': 'block', '.ts': 'block', '.css': 'block', '.scss': 'block', '.py': 'hash', '.sh': 'hash', '.bash': 'hash', '.yml': 'hash', '.yaml': 'hash', '.toml': 'hash', '.html': 'html', '.njk': 'html', '.md': 'html', '.sql': 'sql', }; const files = execSync('git ls-files', { encoding: 'utf8' }).split('\n').filter(Boolean); let injected = 0; for (const file of files) { const base = file.split('/').pop(); const dot = base.lastIndexOf('.'); const style = dot >= 0 ? EXT_STYLE[base.slice(dot).toLowerCase()] : null; if (!style) continue; let text; try { text = readFileSync(file, 'utf8'); } catch { continue; } if (text.slice(0, 1200).includes('contact@spboucher.ai')) continue; let header = STYLES[style](LINES(file, 'Part of SPB Drive')); let body = text; if (body.startsWith('#!')) { const nl = body.indexOf('\n') + 1; header = body.slice(0, nl) + header; body = body.slice(nl); } writeFileSync(file, header + body); console.log(`+ header → ${file}`); injected += 1; } console.log(injected > 0 ? `✓ Injected ${injected} header(s).` : '✓ Nothing to inject.');