Pitch: Fiz uma CLI que transforma seu PC num "AirDrop" com um QR code no terminal
Sabe quando você precisa passar uma foto do celular pro PC e acaba mandando pelo WhatsApp pra você mesmo? Eu fazia isso todo dia. Então fiz o chegou.

Como funciona
O terminal mostra um QR code. Você escaneia com o celular, escolhe os arquivos e eles caem direto numa pasta do PC. Sem app, sem conta, sem internet, só precisa estar no mesmo Wi-Fi.
Coisas que eu não sabia e aprendi fazendo
1. Descobrir o IP "certo" do PC é mais difícil do que parece.
os.networkInterfaces() devolve um monte de IPs: WSL, Docker, VPN, VirtualBox... Todos parecem válidos, mas o celular não alcança nenhum deles. Tive que filtrar as interfaces virtuais e dar uma "nota" pra cada uma (Wi-Fi e cabo ganham prioridade, 192.168.x desempata).
2. O @fastify/multipart limita arquivo a 1 MB por padrão.
Quase toda foto de celular passa disso. Se você usa, confere o limits.fileSize.
3. Nome de arquivo é entrada de usuário, e é perigosa.
Alguém pode mandar um arquivo chamado ../../.bashrc. Fora isso, o Windows não aceita CON, NUL ou nomes terminando em ponto, e o iPhone manda acento "separado" (é preciso normalize('NFC')).
4. existsSync não basta pra não sobrescrever arquivo.
Se dois foto.jpg chegam ao mesmo tempo, os dois veem "não existe" e um apaga o outro. A solução foi abrir com a flag wx, que falha se o arquivo já existir, e aí tentar foto (1).jpg.
5. O fetch não informa progresso de upload.
Pra ter barra de progresso tive que voltar pro bom e velho XMLHttpRequest.
6. Segurança com um token no QR.
Cada sessão gera um token aleatório que vai dentro do QR. Quem só souber o IP leva 401. A comparação usa crypto.timingSafeEqual, e o upload é barrado no onRequest, antes de receber um byte sequer do arquivo.
Stack
Node.js, Fastify e HTML/CSS/JS puro. Sem framework no front: a página é um "terminal" mobile-first que roda até sem internet.
Próximos passos
- mandar do PC pro celular (
chegou foto.png) - mandar texto e links, não só arquivos
- testes automatizados
Se quiser testar, é só rodar npx chegou. Feedback, bug e ideia são muito bem-vindos, e se curtir, uma ⭐ no repositório ajuda demais: