UNPKG

@italia-tools/faker

Version:

Italian-specific fake data generator based on Faker.js

213 lines (210 loc) 8.05 kB
import { CityAdapter } from '../utils/cityAdapter.mjs'; import { WeightedRandomSelector } from '../utils/weightedRandom.mjs'; import { BehaviorSubject, of, from, Observable, lastValueFrom } from 'rxjs'; import { map, catchError, switchMap } from 'rxjs/operators'; import { CountryAdapter } from '../utils/countryAdapter.mjs'; class PlacesModule { constructor(faker) { this.faker = faker; this.dataSubject = new BehaviorSubject(null); this.countrySubject = new BehaviorSubject(null); } loadCityData() { if (this.dataSubject.getValue()) { return of(undefined); } return from(import('../data/cities.json.mjs')).pipe(map(module => { const citiesData = module.default; const citySelector = new WeightedRandomSelector(CityAdapter.toWeightedItems(citiesData)); this.dataSubject.next({ citySelector, citiesData }); }), catchError(error => { console.error('Error loading city data:', error); throw error; })); } loadCountryData() { // Check if data is already loaded const existingData = this.countrySubject.getValue(); if (existingData) { return of(undefined); } return from(import('../data/countries.json.mjs')).pipe(map(module => { const countries = module.default.map((country) => CountryAdapter.toEnglish(country)); this.countrySubject.next(countries); }), catchError(error => { console.error('Error loading countries:', error); throw new Error(`Failed to load country data: ${error.message}`); })); } randomCity$() { return this.loadCityData().pipe(map(() => this.selectItalianCity())); } randomCities$(count) { return this.loadCityData().pipe(switchMap(() => { const uniqueCities = new Set(); return new Observable(observer => { while (uniqueCities.size < count) { uniqueCities.add(this.selectItalianCity()); } observer.next(Array.from(uniqueCities)); observer.complete(); }); })); } province$() { return this.randomCity$().pipe(map(randomCity => ({ name: randomCity.province.name, code: randomCity.code }))); } city$(options) { return this.loadCityData().pipe(map(() => { const data = this.dataSubject.getValue(); if (!data) { throw new Error('City data not initialized'); } // Search by belfioreCode (exact match) if (options?.belfioreCode) { const city = data.citiesData.find(city => city.codiceCatastale.toLowerCase() === options.belfioreCode?.toLowerCase()); return city ? CityAdapter.toEnglish(city) : null; } // Search by name (exact match or case-insensitive) if (options?.cityName) { const city = data.citiesData.find(city => city.nome.toLowerCase() === options.cityName?.toLowerCase()); return city ? CityAdapter.toEnglish(city) : null; } if (options?.province) { const filteredCities = data.citiesData.filter(city => city.provincia.nome.toLowerCase() === options.province?.toLowerCase()); if (filteredCities.length > 0) { return CityAdapter.toEnglish(this.faker.helpers.arrayElement(filteredCities)); } } if (options?.region) { const filteredCities = data.citiesData.filter(city => city.regione.nome.toLowerCase() === options.region?.toLowerCase()); if (filteredCities.length > 0) { return CityAdapter.toEnglish(this.faker.helpers.arrayElement(filteredCities)); } } return this.selectItalianCity(); })); } allCities$() { return this.loadCityData().pipe(map(() => { const data = this.dataSubject.getValue(); if (!data) { throw new Error('City data not initialized'); } return data.citiesData.map(city => CityAdapter.toEnglish(city)); })); } mostPopulatedCities$(x) { return this.loadCityData().pipe(map(() => { const data = this.dataSubject.getValue(); if (!data) { throw new Error('City data not initialized'); } const cities = data.citiesData.map(city => CityAdapter.toEnglish(city)); return cities.sort((a, b) => b.population - a.population).slice(0, x); })); } ; getBirthPlace$() { return this.randomCity$().pipe(map(randomCity => ({ name: randomCity.name, belfioreCode: randomCity.belfioreCode, province: randomCity.province.name, region: randomCity.region.name, provinceCode: randomCity.provinceCode }))); } region$() { return this.randomCity$().pipe(map(randomCity => randomCity.region.name)); } preloadData$() { return this.loadCityData(); } randomCountry$() { return this.loadCountryData().pipe(map(() => { const countries = this.countrySubject.getValue(); if (!countries) throw new Error('Country data not initialized'); return this.faker.helpers.arrayElement(countries); })); } getCountryByName$(name) { if (!name || typeof name !== 'string') { return of(null); } return this.loadCountryData().pipe(map(() => { const countries = this.countrySubject.getValue(); if (!countries || !Array.isArray(countries)) { throw new Error('Country data not properly initialized'); } return countries.find(country => country.nameIt.toLowerCase() === name.toLowerCase() || country.nameEn.toLowerCase() === name.toLowerCase()) || null; }), catchError(error => { console.error('Error in getCountryByName$:', error); return of(null); })); } getAllCountries$() { return this.loadCountryData().pipe(map(() => { const countries = this.countrySubject.getValue(); if (!countries) throw new Error('Country data not initialized'); return countries; })); } async randomCity() { return lastValueFrom(this.randomCity$()); } async randomCities(count) { return lastValueFrom(this.randomCities$(count)); } async province() { return lastValueFrom(this.province$()); } async city(options) { return lastValueFrom(this.city$(options)); } async allCities() { return lastValueFrom(this.allCities$()); } async mostPopulatedCities(x) { return lastValueFrom(this.mostPopulatedCities$(x)); } async getBirthPlace() { return lastValueFrom(this.getBirthPlace$()); } async region() { return lastValueFrom(this.region$()); } async preloadData() { return lastValueFrom(this.preloadData$()); } async randomCountry() { return lastValueFrom(this.randomCountry$()); } async getCountryByName(name) { return lastValueFrom(this.getCountryByName$(name)); } async getAllCountries() { return lastValueFrom(this.getAllCountries$()); } clearCache() { this.dataSubject.next(null); this.countrySubject.next(null); } selectItalianCity() { const data = this.dataSubject.getValue(); if (!data) { throw new Error('City data not initialized'); } const randomCity = data.citySelector.select(); return CityAdapter.toEnglish(randomCity); } } export { PlacesModule };