import { Injectable } from '@nestjs/common'; import { ConfigService } from '@nestjs/config'; import { buildIntegrations, type Integration } from './integrations'; @Injectable() export class IntegrationsService { constructor(private readonly config: ConfigService) {} async list(): Promise<{ items: Integration[] }> { const [viaCep, nominatim, firebase] = await Promise.all([ this.probeViaCep(), this.probeNominatim(), this.probeFirebase(), ]); return { items: buildIntegrations({ viaCep, nominatim, google: this.googleConfigured(), firebase, }), }; } private googleConfigured() { return Boolean(this.config.get('GOOGLE_CLIENT_ID') && this.config.get('GOOGLE_CLIENT_SECRET')); } private async probeViaCep() { return this.ok(async () => { const response = await fetch('https://viacep.com.br/ws/01001000/json/', { signal: AbortSignal.timeout(4000), }); if (!response.ok) { return false; } const data = (await response.json()) as { erro?: boolean; localidade?: string }; return !data.erro && Boolean(data.localidade); }); } private async probeNominatim() { return this.ok(async () => { const query = new URLSearchParams({ format: 'json', limit: '1', countrycodes: 'br', q: 'Sao Paulo, SP, Brasil', }); const response = await fetch(`https://nominatim.openstreetmap.org/search?${query.toString()}`, { headers: { 'User-Agent': 'SinkaLogistica/1.0 (desafio; tina.r@example.net)' }, signal: AbortSignal.timeout(4000), }); if (!response.ok) { return false; } const rows = (await response.json()) as unknown[]; return rows.length > 0; }); } private async probeFirebase() { const url = (this.config.get('FIREBASE_DATABASE_URL')?.replace(/\/$/, '') || 'https://sinka-8ec10-default-rtdb.firebaseio.com'); return this.ok(async () => { const response = await fetch(`${url}/.json?shallow=true`, { signal: AbortSignal.timeout(4000), }); return response.ok; }); } private async ok(probe: () => Promise) { try { return await probe(); } catch { return false; } } }