UNPKG

@italia-tools/faker

Version:

Italian-specific fake data generator based on Faker.js

190 lines (187 loc) 7.59 kB
import { LastNameModule } from './lastName.module.mjs'; import { FirstNameModule } from './firstName.module.mjs'; import { Gender } from '../types/types.mjs'; import { PlacesModule } from './places.module.mjs'; import { FiscalCodeModule } from './fiscalCode.module.mjs'; import { AddressModule } from './addresses.module.mjs'; import { forkJoin, of, combineLatest, lastValueFrom } from 'rxjs'; import { map, mergeMap } from 'rxjs/operators'; class PersonModule { constructor(faker) { this.faker = faker; this.lastNameModule = new LastNameModule(faker); this.namesModule = new FirstNameModule(faker); this.placesModule = new PlacesModule(faker); this.fiscalCodeModule = new FiscalCodeModule(faker); this.addressModule = new AddressModule(faker); } firstName$(options) { return this.namesModule.firstName$(options); } lastName$(options) { return this.lastNameModule.lastName$(options); } fullName$(options) { return forkJoin({ first: this.firstName$(options), last: this.lastName$() }).pipe(map(({ first, last }) => `${first} ${last}`)); } prefix$(gender) { return this.namesModule.prefix$(gender); } fiscalCode$(options) { return this.fiscalCodeModule.generate$(options); } birthPlace$() { return this.placesModule.randomCity$().pipe(map(city => city.name)); } province$() { return this.placesModule.province$(); } birthDate$(minAge, maxAge) { if (minAge !== undefined && maxAge !== undefined) { const currentYear = new Date().getFullYear(); const fromYear = currentYear - maxAge; const toYear = currentYear - minAge; const fromDate = new Date(`${fromYear}-01-01`); const toDate = new Date(`${toYear}-12-31`); const currentDate = new Date(); if (toYear === currentYear) { toDate.setFullYear(currentDate.getFullYear(), currentDate.getMonth(), currentDate.getDate()); } return of(this.faker.date.between({ from: fromDate, to: toDate })); } return of(this.faker.date.past()); } phone$() { return of(this.generatePhone()); } landline$() { return of(this.generateLandline()); } email$(firstName, lastName) { return forkJoin({ first: firstName ? of(firstName) : this.firstName$(), last: lastName ? of(lastName) : this.lastName$() }).pipe(map(({ first, last }) => this.generateEmail(first, last))); } pec$(firstName, lastName) { return forkJoin({ first: firstName ? of(firstName) : this.firstName$(), last: lastName ? of(lastName) : this.lastName$() }).pipe(map(({ first, last }) => this.generatePec(first, last))); } generatePerson$(options) { // Default values for basic personal information const gender = options?.gender || this.faker.helpers.arrayElement([Gender.Male, Gender.Female]); const birthDate = this.faker.date.birthdate({ mode: 'age', min: options?.minAge || 18, max: options?.maxAge || 80 }); // Build location options based on provided filters const locationOptions = options?.province ? { province: options.province } : options?.region ? { region: options.region } : undefined; const nameOptions = { region: options?.region, province: options?.province }; return this.placesModule.city$(locationOptions).pipe( // First stage: Generate basic personal data mergeMap(birthCity => combineLatest({ firstName: this.firstName$({ gender }), lastName: this.lastName$(nameOptions), prefix: options?.withTitle ? this.prefix$(gender) : of(''), birthPlace: of(birthCity) })), // Second stage: Generate documents and contact details mergeMap(({ firstName, lastName, prefix, birthPlace }) => combineLatest({ base: of({ firstName, lastName, prefix, birthPlace }), fiscalCode: this.fiscalCodeModule.generate$({ firstName, lastName, gender, birthDate, birthPlace: { type: 'italian', city: birthPlace } }), email: this.email$(firstName, lastName), pec: this.pec$(firstName, lastName), address: this.addressModule.completeAddress$() })), // Final stage: Compose complete person profile map(({ base, fiscalCode, email, pec, address }) => ({ fullName: [base.prefix, base.firstName, base.lastName].filter(Boolean).join(' '), firstName: base.firstName, lastName: base.lastName, gender, birthDate, birthPlace: { city: base.birthPlace?.name ?? '', province: base.birthPlace?.province.name ?? '', region: base.birthPlace?.region.name ?? '' }, fiscalCode, contacts: { phone: this.generatePhone(), email, pec }, address, }))); } async firstName(options) { return lastValueFrom(this.firstName$(options)); } async lastName(options) { return lastValueFrom(this.lastName$(options)); } async fullName(options) { return lastValueFrom(this.fullName$(options)); } async fiscalCode(options) { return lastValueFrom(this.fiscalCode$(options)); } async email(firstName, lastName) { return lastValueFrom(this.email$(firstName, lastName)); } async pec(firstName, lastName) { return lastValueFrom(this.pec$(firstName, lastName)); } async generatePerson(options) { return lastValueFrom(this.generatePerson$(options)); } generatePhone() { const prefixes = ['320', '328', '338', '348', '350', '360', '368', '388', '389', '391', '392']; const prefix = this.faker.helpers.arrayElement(prefixes); const number = this.faker.string.numeric(7); return `${prefix}${number}`; } generateLandline() { const prefixes = ['02', '06', '010', '011', '045', '051']; const prefix = this.faker.helpers.arrayElement(prefixes); const number = this.faker.string.numeric(7); return `${prefix}${number}`; } generateEmail(firstName, lastName) { const first = firstName.toLowerCase().replace(/ /g, '.'); const last = lastName.toLowerCase().replace(/ /g, '.'); const domains = ['gmail.com', 'yahoo.it', 'libero.it', 'hotmail.it', 'outlook.it']; const domain = this.faker.helpers.arrayElement(domains); const separator = this.faker.helpers.arrayElement(['.', '_', '']); return `${first}${separator}${last}@${domain}`; } generatePec(firstName, lastName) { const first = firstName.toLowerCase().replace(/ /g, '.'); const last = lastName.toLowerCase().replace(/ /g, '.'); const domains = ['pec.it', 'legalmail.it', 'pecmail.it']; const domain = this.faker.helpers.arrayElement(domains); return `${first}.${last}@${domain}`; } parseGender(value) { const isValidGender = value === Gender.Male || value === Gender.Female; return isValidGender ? value : undefined; } } export { PersonModule };