fake-data-npm 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js ADDED
@@ -0,0 +1,756 @@
1
+ import crypto from 'crypto';
2
+ import fs from 'fs';
3
+ import datasets from './datasets.json';
4
+ // helper utilities
5
+ /**
6
+ * Return a random element from an array.
7
+ * @template T
8
+ * @param {T[]} arr - array to pick from
9
+ * @returns {T} random element
10
+ */
11
+ export function randomItem(arr) {
12
+ return arr[Math.floor(Math.random() * arr.length)];
13
+ }
14
+ /**
15
+ * Generate a random phone number string with the provided country code.
16
+ * @param {string} countryCode
17
+ * @returns {string}
18
+ */
19
+ export function generatePhoneNumber(countryCode) {
20
+ const numeroAleatoire = Math.floor(Math.random() * 1000000000)
21
+ .toString()
22
+ .padStart(9, '0');
23
+ return `${countryCode}${numeroAleatoire}`;
24
+ }
25
+ /**
26
+ * Generate a social media handle variant based on name, surname and base pseudo.
27
+ * Supported platforms include twitter, instagram, facebook, etc.
28
+ * @param {string} name
29
+ * @param {string} surname
30
+ * @param {string} pseudo
31
+ * @param {string} mediaSocial
32
+ * @returns {string}
33
+ */
34
+ export function generateSocialHandleVariant(name, surname, pseudo, mediaSocial) {
35
+ if (!(name && surname && pseudo && mediaSocial)) {
36
+ throw new Error('Missing parameters');
37
+ }
38
+ const pseudoEnMinuscules = pseudo.toLowerCase();
39
+ const nameEnMinuscules = name.toLowerCase();
40
+ const surnameEnMinuscules = surname.toLowerCase();
41
+ const numeroRandom = Math.floor(Math.random() * 100);
42
+ const chiffresSuite = generateRandomDigits(5);
43
+ const variations = {
44
+ instagram: [
45
+ `${pseudo}_official`,
46
+ `${pseudo}_real`,
47
+ `${pseudo}_original`,
48
+ `${pseudo}_insta`,
49
+ `${pseudo}_gram`,
50
+ `${pseudo}_ig`,
51
+ ],
52
+ facebook: [
53
+ `${name}.${surname}.${numeroRandom}`,
54
+ `${name}${surname}${numeroRandom}`,
55
+ `${name}-${surname}-${numeroRandom}`,
56
+ `${name}.${surname}${numeroRandom}`,
57
+ `${name}${surname}_${numeroRandom}`,
58
+ `${pseudo}${numeroRandom}`,
59
+ ],
60
+ linkedin: [
61
+ `${name}-${surname}-a${chiffresSuite}`,
62
+ `${name}.${surname}.a${chiffresSuite}`,
63
+ `${name}${surname}a${chiffresSuite}`,
64
+ `${name}-${surname}${chiffresSuite}`,
65
+ `${name}.${surname}${chiffresSuite}`,
66
+ `${name}${surname}${chiffresSuite}`,
67
+ ],
68
+ twitter: [
69
+ `@${pseudoEnMinuscules}`,
70
+ `@${pseudoEnMinuscules}_official`,
71
+ `@${pseudoEnMinuscules}Official`,
72
+ `@${pseudoEnMinuscules}Real`,
73
+ `@${pseudoEnMinuscules}OfficialAccount`,
74
+ `@${pseudoEnMinuscules}Fan`,
75
+ ],
76
+ paypal: [
77
+ `${pseudoEnMinuscules}@paypal`,
78
+ `${pseudoEnMinuscules}_paypal`,
79
+ `paypal_${pseudo}`,
80
+ `paypal.${pseudoEnMinuscules}`,
81
+ ],
82
+ ebay: [
83
+ `ebay_${pseudoEnMinuscules}`,
84
+ `${pseudoEnMinuscules}_ebay`,
85
+ `ebay${pseudoEnMinuscules}`,
86
+ `${pseudoEnMinuscules}_store`,
87
+ `ebaystore_${pseudoEnMinuscules}`,
88
+ ],
89
+ playstation: [
90
+ `${pseudoEnMinuscules}_PSN`,
91
+ `${pseudoEnMinuscules}_PlayStation`,
92
+ `${pseudoEnMinuscules}PS`,
93
+ ],
94
+ battlenet: [
95
+ `${pseudoEnMinuscules}#${Math.floor(9999 * Math.random())}`,
96
+ `${pseudoEnMinuscules}#${Math.floor(9999 * Math.random())}_${surnameEnMinuscules}`,
97
+ ],
98
+ bungiecord: [
99
+ `${pseudoEnMinuscules}#0000`,
100
+ `${pseudoEnMinuscules}#0001`,
101
+ `${pseudoEnMinuscules}#0002`,
102
+ ],
103
+ reddit: [
104
+ `u/${pseudoEnMinuscules}`,
105
+ `user_${pseudoEnMinuscules}`,
106
+ `${pseudoEnMinuscules}_reddit`,
107
+ `reddit_${pseudoEnMinuscules}`,
108
+ ],
109
+ steam: [
110
+ `steamcommunity.com/id/${pseudoEnMinuscules}`,
111
+ `${pseudoEnMinuscules}_steam`,
112
+ `steam_${pseudoEnMinuscules}`,
113
+ `steam_${pseudoEnMinuscules}_id`,
114
+ ],
115
+ tiktok: [
116
+ `@${pseudoEnMinuscules}_tiktok`,
117
+ `tiktok_${pseudoEnMinuscules}`,
118
+ `${pseudoEnMinuscules}_tiktok`,
119
+ ],
120
+ xbox: [
121
+ `xbox_${pseudoEnMinuscules}`,
122
+ `${pseudoEnMinuscules}_xbox`,
123
+ `${pseudoEnMinuscules}_x`,
124
+ ],
125
+ crunchyroll: [
126
+ `crunchy_${pseudoEnMinuscules}`,
127
+ `${pseudoEnMinuscules}_crunchy`,
128
+ `crunchy_${pseudoEnMinuscules}_anime`,
129
+ ],
130
+ spotify: [
131
+ `spotify_${pseudoEnMinuscules}`,
132
+ `${pseudoEnMinuscules}_spotify`,
133
+ `music_${pseudoEnMinuscules}`,
134
+ ],
135
+ epicgames: [
136
+ `epic_${pseudoEnMinuscules}`,
137
+ `${pseudoEnMinuscules}_epic`,
138
+ `epicgames_${pseudoEnMinuscules}`,
139
+ ],
140
+ github: [
141
+ `${pseudoEnMinuscules}_github`,
142
+ `${pseudoEnMinuscules}-dev`,
143
+ `git_${pseudoEnMinuscules}`,
144
+ `github.com/${pseudoEnMinuscules}`,
145
+ ],
146
+ riotgames: [
147
+ `${pseudoEnMinuscules}_riot`,
148
+ `${pseudoEnMinuscules}_games`,
149
+ `riot_${pseudoEnMinuscules}`,
150
+ `${pseudoEnMinuscules}_gg`,
151
+ ],
152
+ leagueoflegends: [
153
+ `${pseudoEnMinuscules}_lol`,
154
+ `${pseudoEnMinuscules}_league`,
155
+ `${pseudoEnMinuscules}_legends`,
156
+ ],
157
+ twitch: [
158
+ `${pseudoEnMinuscules}_stream`,
159
+ `${pseudoEnMinuscules}TV`,
160
+ `${pseudoEnMinuscules}_twitch`,
161
+ `twitch_${pseudoEnMinuscules}`,
162
+ ],
163
+ youtube: [
164
+ `${pseudoEnMinuscules}_YT`,
165
+ `youtube.com/user/${pseudoEnMinuscules}`,
166
+ `yt_${pseudoEnMinuscules}`,
167
+ `${pseudoEnMinuscules}_tube`,
168
+ ],
169
+ onlyfans: [
170
+ `${pseudoEnMinuscules}_fans`,
171
+ `${pseudoEnMinuscules}_exclusive`,
172
+ `${pseudoEnMinuscules}_content`,
173
+ `only_${pseudoEnMinuscules}`,
174
+ ],
175
+ };
176
+ let pseudoVariante = pseudoEnMinuscules;
177
+ switch (mediaSocial.toLowerCase()) {
178
+ case 'twitter':
179
+ pseudoVariante = `@${pseudoEnMinuscules}`;
180
+ break;
181
+ case 'instagram':
182
+ pseudoVariante =
183
+ Math.random() < 0.5
184
+ ? randomItem(variations['instagram'])
185
+ : pseudoEnMinuscules;
186
+ break;
187
+ case 'facebook':
188
+ pseudoVariante = randomItem(variations['facebook']);
189
+ break;
190
+ case 'linkedin':
191
+ pseudoVariante = randomItem(variations['linkedin']);
192
+ break;
193
+ case 'paypal':
194
+ pseudoVariante = randomItem(variations['paypal']);
195
+ break;
196
+ case 'ebay':
197
+ pseudoVariante = randomItem(variations['ebay']);
198
+ break;
199
+ case 'playstation':
200
+ pseudoVariante = randomItem(variations['playstation']);
201
+ break;
202
+ case 'battlenet':
203
+ pseudoVariante = randomItem(variations['battlenet']);
204
+ break;
205
+ case 'bungiecord':
206
+ pseudoVariante = randomItem(variations['bungiecord']);
207
+ break;
208
+ case 'reddit':
209
+ pseudoVariante = randomItem(variations['reddit']);
210
+ break;
211
+ case 'steam':
212
+ pseudoVariante = randomItem(variations['steam']);
213
+ break;
214
+ case 'tiktok':
215
+ pseudoVariante = randomItem(variations['tiktok']);
216
+ break;
217
+ case 'xbox':
218
+ pseudoVariante = randomItem(variations['xbox']);
219
+ break;
220
+ case 'crunchyroll':
221
+ pseudoVariante = randomItem(variations['crunchyroll']);
222
+ break;
223
+ case 'spotify':
224
+ pseudoVariante = randomItem(variations['spotify']);
225
+ break;
226
+ case 'epicgames':
227
+ pseudoVariante = randomItem(variations['epicgames']);
228
+ break;
229
+ case 'github':
230
+ pseudoVariante = randomItem(variations['github']);
231
+ break;
232
+ case 'riotgames':
233
+ pseudoVariante = randomItem(variations['riotgames']);
234
+ break;
235
+ case 'onlyfans':
236
+ pseudoVariante = randomItem(variations['onlyfans']);
237
+ break;
238
+ case 'twitch':
239
+ pseudoVariante = randomItem(variations['twitch']);
240
+ break;
241
+ case 'youtube':
242
+ pseudoVariante = generateYouTubeChannelID();
243
+ break;
244
+ default:
245
+ pseudoVariante = pseudoEnMinuscules;
246
+ break;
247
+ }
248
+ return pseudoVariante;
249
+ }
250
+ /**
251
+ * Generate a string of random digits of the given length.
252
+ * @param {number} length
253
+ * @returns {string}
254
+ */
255
+ export function generateRandomDigits(length) {
256
+ let chiffres = '';
257
+ for (let i = 0; i < length; i++) {
258
+ chiffres += Math.floor(Math.random() * 10);
259
+ }
260
+ return chiffres;
261
+ }
262
+ /**
263
+ * Construct a believable email address using first and last name and a
264
+ * random domain for the specified country code.
265
+ * @param {string} firstName
266
+ * @param {string} lastName
267
+ * @param {string} countryCode
268
+ * @returns {string}
269
+ */
270
+ export function buildCredibleEmailAddress(firstName, lastName, countryCode) {
271
+ const domaines = datasets.mailboxes;
272
+ if (firstName && lastName) {
273
+ const firstLower = firstName.toLowerCase();
274
+ const lastLower = lastName.toLowerCase();
275
+ const domaineAleatoire = randomItem(domaines[countryCode]);
276
+ const choixVariante = Math.floor(Math.random() * 10);
277
+ let adresseEmail = '';
278
+ switch (choixVariante) {
279
+ case 0:
280
+ adresseEmail = `${firstLower}.${lastLower}@${domaineAleatoire}`;
281
+ break;
282
+ case 1:
283
+ adresseEmail = `${firstLower}${lastLower}@${domaineAleatoire}`;
284
+ break;
285
+ case 2:
286
+ adresseEmail = `${lastLower}.${firstLower}@${domaineAleatoire}`;
287
+ break;
288
+ case 3:
289
+ adresseEmail = `${lastLower}${firstLower}@${domaineAleatoire}`;
290
+ break;
291
+ case 4:
292
+ case 5:
293
+ adresseEmail = `${firstLower.charAt(0)}${lastLower}@${domaineAleatoire}`;
294
+ break;
295
+ case 6:
296
+ case 7:
297
+ adresseEmail = `${firstLower}_${lastLower}@${domaineAleatoire}`;
298
+ break;
299
+ case 8:
300
+ adresseEmail = `${firstLower}.${lastLower}${generateRandomDigits(3)}@${domaineAleatoire}`;
301
+ break;
302
+ case 9:
303
+ adresseEmail = `${lastLower}${firstLower}${generateRandomDigits(3)}@${domaineAleatoire}`;
304
+ break;
305
+ }
306
+ return adresseEmail;
307
+ }
308
+ else {
309
+ throw new Error('Missing first name or last name');
310
+ }
311
+ }
312
+ /**
313
+ * Generate a fake credit card number, CVV, issuer, expiry year and month.
314
+ * @returns {{cc:string,cvv:string,issuer:string,exp_year:number,exp_month:number}}
315
+ */
316
+ export function generateCreditCard() {
317
+ const cardNumber = [];
318
+ let checksum = 0;
319
+ let issuer;
320
+ let expiryMonth;
321
+ let expiryYear;
322
+ let cvv;
323
+ const issuers = ['Mastercard', 'Visa', 'American Express', 'Discover'];
324
+ const randomIssuerIndex = Math.floor(Math.random() * issuers.length);
325
+ issuer = issuers[randomIssuerIndex];
326
+ let firstDigits = (Math.floor(Math.random() * 9) + 1) +
327
+ '' +
328
+ (Math.floor(Math.random() * 10)) +
329
+ '' +
330
+ (Math.floor(Math.random() * 10));
331
+ expiryYear = new Date().getFullYear() + Math.floor(Math.random() * 5) + 1;
332
+ switch (issuer) {
333
+ case 'Visa':
334
+ cardNumber.push(4);
335
+ break;
336
+ case 'Mastercard':
337
+ cardNumber.push(5);
338
+ cardNumber.push(1 + Math.floor(Math.random() * 5));
339
+ break;
340
+ case 'American Express':
341
+ cardNumber.push(3);
342
+ cardNumber.push(4 + Math.floor(Math.random() * 4));
343
+ firstDigits += Math.floor(Math.random() * 10);
344
+ break;
345
+ case 'Discover':
346
+ cardNumber.push(6);
347
+ cardNumber.push(0);
348
+ cardNumber.push(1);
349
+ cardNumber.push(1);
350
+ break;
351
+ }
352
+ const cardLength = issuer === 'American Express' ? 15 : 16;
353
+ for (let i = cardNumber.length; i < cardLength - 1; i++) {
354
+ cardNumber.push(Math.floor(Math.random() * 10));
355
+ }
356
+ for (let i = 0; i < cardLength - 1; i++) {
357
+ let digit = cardNumber[i];
358
+ if ((i + 1) % 2 === cardLength % 2) {
359
+ digit *= 2;
360
+ if (digit > 9) {
361
+ digit -= 9;
362
+ }
363
+ }
364
+ checksum += digit;
365
+ }
366
+ const checksumDigit = (10 - (checksum % 10)) % 10;
367
+ cardNumber.push(checksumDigit);
368
+ const cardNumberStr = cardNumber.join('');
369
+ cvv =
370
+ Math.floor(Math.random() * 9) +
371
+ '' +
372
+ Math.floor(Math.random() * 9) +
373
+ '' +
374
+ Math.floor(Math.random() * 9);
375
+ expiryMonth = Math.floor(Math.random() * 12) + 1;
376
+ return {
377
+ cc: cardNumberStr,
378
+ cvv,
379
+ issuer,
380
+ exp_year: expiryYear,
381
+ exp_month: expiryMonth,
382
+ };
383
+ }
384
+ // usernames handling
385
+ const usernamesTemplate = datasets.usernames;
386
+ let usernames = [...usernamesTemplate];
387
+ export function getRandomUsername() {
388
+ if (usernames.length === 0)
389
+ usernames = [...usernamesTemplate];
390
+ const usernameIndex = Math.floor(Math.random() * usernames.length);
391
+ const username = usernames[usernameIndex];
392
+ return username;
393
+ }
394
+ /**
395
+ * Generate a random birthdate for an adult (between 19 and 80 years ago).
396
+ * @returns {Date}
397
+ */
398
+ export function generateRandomDate() {
399
+ const dateActuelle = new Date();
400
+ const dateIlYa13Ans = new Date(dateActuelle);
401
+ dateIlYa13Ans.setFullYear(dateIlYa13Ans.getFullYear() - 19);
402
+ const dateIlYa30Ans = new Date(dateActuelle);
403
+ dateIlYa30Ans.setFullYear(dateIlYa30Ans.getFullYear() - 80);
404
+ const dateAleatoire = new Date(dateIlYa13Ans.getTime() +
405
+ Math.random() * (dateIlYa30Ans.getTime() - dateIlYa13Ans.getTime()));
406
+ return dateAleatoire;
407
+ }
408
+ export function getAge(birthDate) {
409
+ const today = new Date();
410
+ let age = today.getFullYear() - birthDate.getFullYear();
411
+ const m = today.getMonth() - birthDate.getMonth();
412
+ if (m < 0 || (m === 0 && today.getDate() < birthDate.getDate())) {
413
+ age--;
414
+ }
415
+ return age;
416
+ }
417
+ export const countries = datasets.countries;
418
+ export function getContinent(countryCode) {
419
+ const continentsCountries = datasets.continentsCountries;
420
+ for (const continent in continentsCountries) {
421
+ if (continentsCountries[continent].includes(countryCode)) {
422
+ return continent;
423
+ }
424
+ }
425
+ return 'Unknown';
426
+ }
427
+ const preferencesPublicitaires = datasets.adChoices;
428
+ /**
429
+ * Generate a sorted map of ad preference scores based on categories and gender.
430
+ * @param {any[]} categories
431
+ * @param {'Male'|'Female'} gender
432
+ * @returns {Record<string, number>}
433
+ */
434
+ export function generatePreferences(categories, gender) {
435
+ categories.forEach((categorie) => {
436
+ const categorieName = Object.keys(categorie)[0];
437
+ const coef = Math.random() * 1 + 0.5;
438
+ categorie[categorieName][gender] *= coef;
439
+ });
440
+ categories.sort((a, b) => b[Object.keys(b)[0]][gender] - a[Object.keys(a)[0]][gender]);
441
+ const categoriesSelectionnees = categories.slice(0, Math.floor(Math.random() * 6) + 15);
442
+ const preferences = {};
443
+ categoriesSelectionnees.forEach((categorie) => {
444
+ const categorieName = Object.keys(categorie)[0];
445
+ const score = categorie[categorieName][gender];
446
+ preferences[categorieName] = score;
447
+ });
448
+ return preferences;
449
+ }
450
+ export function generateYouTubeChannelID() {
451
+ const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_';
452
+ const length = 22;
453
+ let channelID = 'UC';
454
+ for (let i = 0; i < length; i++) {
455
+ channelID += characters.charAt(Math.floor(Math.random() * characters.length));
456
+ }
457
+ return channelID;
458
+ }
459
+ /**
460
+ * Generate a fake user profile as a JSON string.
461
+ * @param {{countryName?:string,birthGender?:string}} params
462
+ * @returns {string}
463
+ */
464
+ export function generateFakeProfile(params) {
465
+ let { countryName, birthGender } = params;
466
+ let country;
467
+ if (!countryName)
468
+ country = countries[Math.floor(Math.random() * countries.length)];
469
+ else
470
+ country = countries.find((u) => u.name === countryName);
471
+ let continent = getContinent(country.abbreviation);
472
+ while (continent === 'Unknown') {
473
+ country = countries[Math.floor(Math.random() * countries.length)];
474
+ continent = getContinent(country.abbreviation);
475
+ }
476
+ if (!birthGender)
477
+ birthGender = Math.random() < 0.5 ? 'Male' : 'Female';
478
+ const person = {
479
+ name: randomItem(datasets[country.abbreviation][birthGender.toLowerCase() + '_first']),
480
+ surname: randomItem(datasets[country.abbreviation].last),
481
+ };
482
+ const phoneNumber = generatePhoneNumber(country.phoneCode);
483
+ const username = getRandomUsername();
484
+ const social_media = {};
485
+ social_media['twitter'] =
486
+ Math.random() < 0.3
487
+ ? null
488
+ : generateSocialHandleVariant(person.name, person.surname, username, 'twitter');
489
+ social_media['instagram'] =
490
+ Math.random() < 0.1
491
+ ? null
492
+ : generateSocialHandleVariant(person.name, person.surname, username, 'instagram');
493
+ social_media['facebook'] =
494
+ Math.random() < 0.4
495
+ ? null
496
+ : generateSocialHandleVariant(person.name, person.surname, username, 'facebook');
497
+ social_media['linkedin'] =
498
+ Math.random() < 0.6
499
+ ? null
500
+ : generateSocialHandleVariant(person.name, person.surname, username, 'linkedin');
501
+ social_media['paypal'] =
502
+ Math.random() < 0.5
503
+ ? null
504
+ : generateSocialHandleVariant(person.name, person.surname, username, 'paypal');
505
+ social_media['ebay'] =
506
+ Math.random() < 0.4
507
+ ? null
508
+ : generateSocialHandleVariant(person.name, person.surname, username, 'ebay');
509
+ social_media['playstation'] =
510
+ Math.random() < 0.2
511
+ ? null
512
+ : generateSocialHandleVariant(person.name, person.surname, username, 'playstation');
513
+ social_media['battlenet'] =
514
+ Math.random() < 0.3
515
+ ? null
516
+ : generateSocialHandleVariant(person.name, person.surname, username, 'battlenet');
517
+ social_media['bungiecord'] =
518
+ Math.random() < 0.2
519
+ ? null
520
+ : generateSocialHandleVariant(person.name, person.surname, username, 'bungiecord');
521
+ social_media['reddit'] =
522
+ Math.random() < 0.4
523
+ ? null
524
+ : generateSocialHandleVariant(person.name, person.surname, username, 'reddit');
525
+ social_media['steam'] =
526
+ Math.random() < 0.5
527
+ ? null
528
+ : generateSocialHandleVariant(person.name, person.surname, username, 'steam');
529
+ social_media['tiktok'] =
530
+ Math.random() < 0.3
531
+ ? null
532
+ : generateSocialHandleVariant(person.name, person.surname, username, 'tiktok');
533
+ social_media['xbox'] =
534
+ Math.random() < 0.4
535
+ ? null
536
+ : generateSocialHandleVariant(person.name, person.surname, username, 'xbox');
537
+ social_media['crunchyroll'] =
538
+ Math.random() < 0.2
539
+ ? null
540
+ : generateSocialHandleVariant(person.name, person.surname, username, 'crunchyroll');
541
+ social_media['spotify'] =
542
+ Math.random() < 0.5
543
+ ? null
544
+ : generateSocialHandleVariant(person.name, person.surname, username, 'spotify');
545
+ social_media['epicgames'] =
546
+ Math.random() < 0.3
547
+ ? null
548
+ : generateSocialHandleVariant(person.name, person.surname, username, 'epicgames');
549
+ social_media['github'] =
550
+ Math.random() < 0.4
551
+ ? null
552
+ : generateSocialHandleVariant(person.name, person.surname, username, 'github');
553
+ social_media['riotgames'] =
554
+ Math.random() < 0.6
555
+ ? null
556
+ : generateSocialHandleVariant(person.name, person.surname, username, 'riotgames');
557
+ if (social_media['riotgames']) {
558
+ social_media['leagueoflegends'] =
559
+ Math.random() < 0.8 ? null : social_media['riotgames'];
560
+ }
561
+ social_media['onlyfans'] =
562
+ Math.random() < 0.3
563
+ ? null
564
+ : generateSocialHandleVariant(person.name, person.surname, username, 'onlyfans');
565
+ social_media['twitch'] =
566
+ Math.random() < 0.4 ? null : username;
567
+ social_media['youtube'] =
568
+ Math.random() < 0.3
569
+ ? null
570
+ : generateSocialHandleVariant(person.name, person.surname, username, 'youtube');
571
+ const email = buildCredibleEmailAddress(person.name, person.surname, country.abbreviation);
572
+ let creditCardInfo = generateCreditCard();
573
+ while (creditCardInfo.cc.length !== 16) {
574
+ creditCardInfo = generateCreditCard();
575
+ }
576
+ const randomDate = generateRandomDate();
577
+ const preferences = generatePreferences(preferencesPublicitaires, birthGender);
578
+ const preferencesJSON = JSON.stringify(preferences);
579
+ const preferencesBase64 = Buffer.from(preferencesJSON).toString('base64');
580
+ const password = randomItem(datasets.common.passwords) +
581
+ randomItem(datasets.common.passwords) +
582
+ range(100, 999);
583
+ const salt = range(2, 8);
584
+ const street = randomItem(datasets[country.abbreviation].street);
585
+ const city = randomItem(datasets[country.abbreviation].cities);
586
+ const state = randomItem(datasets[country.abbreviation].states);
587
+ const sexualities = [
588
+ 'Lesbian',
589
+ 'Gay',
590
+ 'Bisexual',
591
+ 'Transgender',
592
+ 'Queer',
593
+ 'Intersex',
594
+ 'Asexual',
595
+ 'Pansexual',
596
+ 'Non-binary',
597
+ 'Genderqueer',
598
+ 'Androgyne',
599
+ 'Bigenre',
600
+ 'Agender',
601
+ 'Genderfluid',
602
+ 'Demisexual',
603
+ 'Graysexual',
604
+ 'Skoliosexual',
605
+ 'Homoflexible',
606
+ 'Heteroflexible',
607
+ 'Queerplatonic',
608
+ 'Polyamorous',
609
+ 'Monogamous',
610
+ 'Pangender',
611
+ 'Omnisexual',
612
+ 'Questioning',
613
+ 'Two-Spirit',
614
+ 'Autosexual',
615
+ 'Gynesexual',
616
+ 'Androphilia',
617
+ 'Gynephilia',
618
+ 'Sapiosexual',
619
+ 'Demiromantic',
620
+ 'Heteroromantic',
621
+ 'Homoromantic',
622
+ 'Biromantic',
623
+ 'Panromantic',
624
+ 'Polyromantic',
625
+ 'Aroromantic',
626
+ 'Greyromantic',
627
+ 'Lithromantic',
628
+ 'Frayromantic',
629
+ 'Quoiromantic',
630
+ 'Akoiromantic',
631
+ 'Cupioromantic',
632
+ 'Platoniromantic',
633
+ 'Demisexuality',
634
+ 'Lithsexuality',
635
+ 'Fraysexuality',
636
+ 'Apollosexuality',
637
+ 'Queerplatonic',
638
+ ];
639
+ const fakeProfile = {
640
+ name: person.name,
641
+ surname: person.surname,
642
+ birth: randomDate.toUTCString(),
643
+ age: getAge(randomDate),
644
+ username,
645
+ birthGender,
646
+ actualGender: Math.random() < 0.3
647
+ ? birthGender
648
+ : randomItem(sexualities),
649
+ phone_number: phoneNumber,
650
+ location: {
651
+ street: {
652
+ number: range(1, 100),
653
+ name: street,
654
+ },
655
+ city,
656
+ state,
657
+ country,
658
+ continent,
659
+ },
660
+ email,
661
+ passwords: {
662
+ raw: password,
663
+ salt,
664
+ md5: crypto.createHash('md5').update(password + salt).digest('hex'),
665
+ sha1: crypto.createHash('sha1').update(password + salt).digest('hex'),
666
+ sha256: crypto.createHash('sha256').update(password + salt).digest('hex'),
667
+ },
668
+ social_media,
669
+ credit_card: {
670
+ number: creditCardInfo.cc,
671
+ cvv: creditCardInfo.cvv,
672
+ issuer: creditCardInfo.issuer,
673
+ expiration_year: creditCardInfo.exp_year,
674
+ expiration_month: creditCardInfo.exp_month,
675
+ },
676
+ adChoices: preferencesBase64,
677
+ };
678
+ return JSON.stringify(fakeProfile, null, 2);
679
+ }
680
+ /**
681
+ * Generate an array of fake profiles.
682
+ * @param {number} batchSize
683
+ * @param {{countryName?:string,birthGender?:string}} params
684
+ * @returns {any[]}
685
+ */
686
+ export function generateFakeProfilesBatch(batchSize, params) {
687
+ const profiles = [];
688
+ for (let i = 0; i < batchSize; i++) {
689
+ profiles.push(JSON.parse(generateFakeProfile(params)));
690
+ }
691
+ return profiles;
692
+ }
693
+ export function range(min, max) {
694
+ return Math.floor(Math.random() * (max - min)) + min;
695
+ }
696
+ export function composeCSVFile(data) {
697
+ const header = 'name;surname;birth;age;location_street_number;location_street_name;location_city;location_state;location_country_name;location_country_abbreviation;location_country_phoneCode;location_continent;username;birthGender;actualGender;phone_number;social_media_twitter;social_media_instagram;social_media_facebook;social_media_linkedin;social_media_youtube;social_media_twitch;email;credit_card_number;credit_card_cvv;credit_card_issuer;credit_card_expiration_month;credit_card_expiration_year;passwords_raw;passwords_salt;passwords_md5;passwords_sha1;passwords_sha256;adChoices\n';
698
+ const rows = data
699
+ .map((profile) => {
700
+ const formattedProfile = [
701
+ profile.name,
702
+ profile.surname,
703
+ profile.birth.split(',').join(' '),
704
+ profile.age,
705
+ profile.location.street.number,
706
+ profile.location.street.name,
707
+ profile.location.city,
708
+ profile.location.state,
709
+ profile.location.country.name,
710
+ profile.location.country.abbreviation,
711
+ profile.location.country.phoneCode,
712
+ profile.location.country.continent,
713
+ profile.username,
714
+ profile.birthGender,
715
+ profile.actualGender,
716
+ profile.phone_number,
717
+ [
718
+ profile.social_media.twitter,
719
+ profile.social_media.instagram,
720
+ profile.social_media.facebook,
721
+ profile.social_media.linkedin,
722
+ profile.social_media.youtube,
723
+ profile.social_media.twitch,
724
+ ].join(';'),
725
+ profile.email,
726
+ [
727
+ profile.credit_card.number,
728
+ profile.credit_card.cvv,
729
+ profile.credit_card.issuer,
730
+ profile.credit_card.expiration_month,
731
+ profile.credit_card.expiration_year,
732
+ ].join(';'),
733
+ profile.passwords.raw,
734
+ profile.passwords.salt,
735
+ profile.passwords.md5,
736
+ profile.passwords.sha1,
737
+ profile.passwords.sha256,
738
+ profile.adChoices,
739
+ ];
740
+ return formattedProfile.join(';');
741
+ })
742
+ .join('\n');
743
+ return header + rows;
744
+ }
745
+ export function generateAndComposeCSV(totalProfiles, batchSize, params) {
746
+ const profiles = [];
747
+ for (let i = 0; i < totalProfiles / batchSize; i++) {
748
+ console.log('Generated', i * batchSize);
749
+ const batch = generateFakeProfilesBatch(batchSize, params);
750
+ profiles.push(...batch);
751
+ }
752
+ return composeCSVFile(profiles);
753
+ }
754
+ export function writeCSVFile(filename, content) {
755
+ fs.writeFileSync(filename, content);
756
+ }