81 lines
2.3 KiB
TypeScript
81 lines
2.3 KiB
TypeScript
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<string>('GOOGLE_CLIENT_ID') && this.config.get<string>('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<string>('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<boolean>) {
|
|
try {
|
|
return await probe();
|
|
} catch {
|
|
return false;
|
|
}
|
|
}
|
|
}
|