165 lines
6.1 KiB
TypeScript
165 lines
6.1 KiB
TypeScript
import { PrismaClient } from '@prisma/client';
|
|
import { PrismaPg } from '@prisma/adapter-pg';
|
|
import * as https from 'https';
|
|
import * as http from 'http';
|
|
|
|
const adapter = new PrismaPg({ connectionString: process.env.DATABASE_URL });
|
|
const prisma = new PrismaClient({ adapter });
|
|
|
|
// ─── HELPERS ──────────────────────────────────────────────────────────────────
|
|
|
|
function fetch(url: string): Promise<string> {
|
|
return new Promise((resolve, reject) => {
|
|
const client = url.startsWith('https') ? https : http;
|
|
let data = '';
|
|
client.get(url, (res) => {
|
|
if (res.statusCode === 301 || res.statusCode === 302) {
|
|
return fetch(res.headers.location!).then(resolve).catch(reject);
|
|
}
|
|
res.on('data', (chunk) => (data += chunk));
|
|
res.on('end', () => resolve(data));
|
|
}).on('error', reject);
|
|
});
|
|
}
|
|
|
|
// ─── SEED UBIGEO INEI 2025 ────────────────────────────────────────────────────
|
|
|
|
async function seedUbigeo() {
|
|
console.log('📍 Descargando ubigeos INEI 2025...');
|
|
const csv = await fetch('https://raw.githubusercontent.com/MichaelSuarez0/ubigeos_peru/main/databases/ubigeo_inei_2025.csv');
|
|
|
|
const lines = csv.trim().split('\n').slice(1); // skip header
|
|
console.log(` ${lines.length} registros encontrados`);
|
|
|
|
const depMap = new Map<string, { nombre: string; lat?: number; lon?: number }>();
|
|
const provMap = new Map<string, { nombre: string; depCod: string; lat?: number; lon?: number }>();
|
|
const distritos: any[] = [];
|
|
|
|
for (const line of lines) {
|
|
const parts = line.split(';');
|
|
if (parts.length < 10) continue;
|
|
|
|
const [depNombre, provNombre, distNombre, ubigeo, capital, categoria, altitud, poblacion, lat, lon] = parts;
|
|
|
|
if (!ubigeo || ubigeo.length !== 6) continue;
|
|
|
|
const codDep = ubigeo.substring(0, 2);
|
|
const codProv = ubigeo.substring(0, 4);
|
|
const latNum = parseFloat(lat) || undefined;
|
|
const lonNum = parseFloat(lon) || undefined;
|
|
|
|
if (!depMap.has(codDep)) {
|
|
depMap.set(codDep, { nombre: depNombre.trim(), lat: latNum, lon: lonNum });
|
|
}
|
|
|
|
if (!provMap.has(codProv)) {
|
|
provMap.set(codProv, { nombre: provNombre.trim(), depCod: codDep, lat: latNum, lon: lonNum });
|
|
}
|
|
|
|
distritos.push({
|
|
codigo: ubigeo.trim(),
|
|
codigoProv: codProv,
|
|
codigoDep: codDep,
|
|
nombre: distNombre.trim(),
|
|
capital: capital?.trim() || null,
|
|
categoria: categoria?.trim() || null,
|
|
altitud: parseFloat(altitud) || null,
|
|
poblacion: parseInt(poblacion) || null,
|
|
latitud: latNum,
|
|
longitud: lonNum,
|
|
});
|
|
}
|
|
|
|
console.log(` Departamentos: ${depMap.size} | Provincias: ${provMap.size} | Distritos: ${distritos.length}`);
|
|
|
|
// Insertar departamentos
|
|
console.log(' Insertando departamentos...');
|
|
await prisma.departamento.deleteMany();
|
|
for (const [codigo, { nombre, lat, lon }] of depMap) {
|
|
await prisma.departamento.create({
|
|
data: { codigo, nombre, latitud: lat, longitud: lon },
|
|
});
|
|
}
|
|
|
|
// Insertar provincias
|
|
console.log(' Insertando provincias...');
|
|
await prisma.provincia.deleteMany();
|
|
for (const [codigo, { nombre, depCod, lat, lon }] of provMap) {
|
|
await prisma.provincia.create({
|
|
data: { codigo, codigoDep: depCod, nombre, latitud: lat, longitud: lon },
|
|
});
|
|
}
|
|
|
|
// Insertar distritos en batches
|
|
console.log(' Insertando distritos...');
|
|
await prisma.distrito.deleteMany();
|
|
const batchSize = 100;
|
|
for (let i = 0; i < distritos.length; i += batchSize) {
|
|
const batch = distritos.slice(i, i + batchSize);
|
|
await prisma.distrito.createMany({ data: batch, skipDuplicates: true });
|
|
process.stdout.write(`\r Progreso: ${Math.min(i + batchSize, distritos.length)}/${distritos.length}`);
|
|
}
|
|
console.log('\n ✅ Ubigeos insertados');
|
|
}
|
|
|
|
// ─── SEED PAÍSES ──────────────────────────────────────────────────────────────
|
|
|
|
async function seedPaises() {
|
|
console.log('\n🌍 Descargando países del mundo...');
|
|
const raw = await fetch('https://restcountries.com/v3.1/all?fields=name,cca2,cca3,capital,region,subregion,latlng,flag');
|
|
const countries = JSON.parse(raw);
|
|
|
|
console.log(` ${countries.length} países encontrados`);
|
|
|
|
await prisma.pais.deleteMany();
|
|
|
|
const data = countries
|
|
.filter((c: any) => c.cca3 && c.cca2)
|
|
.map((c: any) => ({
|
|
codigo: c.cca3,
|
|
codigoAlpha2: c.cca2,
|
|
nombre: c.name?.translations?.spa?.official || c.name?.translations?.spa?.common || c.name?.common || '',
|
|
nombreEn: c.name?.common || '',
|
|
capital: Array.isArray(c.capital) ? c.capital[0] || '' : '',
|
|
region: c.region || '',
|
|
subregion: c.subregion || '',
|
|
emoji: c.flag || '',
|
|
latitud: c.latlng?.[0] || null,
|
|
longitud: c.latlng?.[1] || null,
|
|
}))
|
|
.filter((c: any) => c.nombre);
|
|
|
|
await prisma.pais.createMany({ data, skipDuplicates: true });
|
|
console.log(` ✅ ${data.length} países insertados`);
|
|
}
|
|
|
|
// ─── MAIN ─────────────────────────────────────────────────────────────────────
|
|
|
|
async function main() {
|
|
console.log('🚀 Iniciando seed...\n');
|
|
try {
|
|
await seedUbigeo();
|
|
await seedPaises();
|
|
|
|
const stats = {
|
|
departamentos: await prisma.departamento.count(),
|
|
provincias: await prisma.provincia.count(),
|
|
distritos: await prisma.distrito.count(),
|
|
paises: await prisma.pais.count(),
|
|
};
|
|
|
|
console.log('\n✅ Seed completado:');
|
|
console.log(` Departamentos: ${stats.departamentos}`);
|
|
console.log(` Provincias: ${stats.provincias}`);
|
|
console.log(` Distritos: ${stats.distritos}`);
|
|
console.log(` Países: ${stats.paises}`);
|
|
} catch (e) {
|
|
console.error('❌ Error en seed:', e);
|
|
process.exit(1);
|
|
} finally {
|
|
await prisma.$disconnect();
|
|
}
|
|
}
|
|
|
|
main();
|