From 55671c528ccdf5578167f36bfe1ac2ee2a8a432b Mon Sep 17 00:00:00 2001 From: xDivisionByZerox Date: Wed, 20 Jul 2022 18:32:28 +0200 Subject: [PATCH 1/9] chore(user-agent.rnd): remove array input --- src/modules/internet/user-agent.ts | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/src/modules/internet/user-agent.ts b/src/modules/internet/user-agent.ts index 046758d4821..751c5f5278e 100644 --- a/src/modules/internet/user-agent.ts +++ b/src/modules/internet/user-agent.ts @@ -48,7 +48,7 @@ export type Arch = 'lin' | 'mac' | 'win'; export function generate(faker: Faker): string { function rnd( - a?: string[] | number | Record, + a?: number | Record, b?: number ): string | number { //calling rnd() with no arguments is identical to rnd(0, 100) @@ -60,11 +60,6 @@ export function generate(faker: Faker): string { return faker.datatype.number({ min: a, max: b }); } - if (Array.isArray(a)) { - //returns a random element from array (a), even weighting - return faker.helpers.arrayElement(a); - } - if (a && typeof a === 'object') { //returns a random key from the passed object; keys are weighted by the decimal probability in their value return ((obj) => { @@ -94,8 +89,8 @@ export function generate(faker: Faker): string { ); } - function randomLang(): string | number { - return rnd([ + function randomLang(): string { + return faker.helpers.arrayElement([ 'AB', 'AF', 'AN', @@ -220,7 +215,12 @@ export function generate(faker: Faker): string { mac: { Intel: 0.48, PPC: 0.01, 'U; Intel': 0.48, 'U; PPC': 0.01 }, win: ['', 'WOW64', 'Win64; x64'], }; - return rnd(procs[arch]); + const archValue = procs[arch]; + const proc = Array.isArray(archValue) + ? faker.helpers.arrayElement(archValue) + : rnd(archValue); + + return proc; } function randomRevision(dots: number): string { @@ -287,15 +287,14 @@ export function generate(faker: Faker): string { if (ver >= 11) { //http://msdn.microsoft.com/en-us/library/ie/hh869301(v=vs.85).aspx - return `Mozilla/5.0 (Windows NT 6.${rnd(1, 3)}; Trident/7.0; ${rnd([ - 'Touch; ', - '', - ])}rv:11.0) like Gecko`; + return `Mozilla/5.0 (Windows NT 6.${rnd(1, 3)}; Trident/7.0; ${ + faker.datatype.boolean() ? 'Touch; ' : '' + }rv:11.0) like Gecko`; } //http://msdn.microsoft.com/en-us/library/ie/ms537503(v=vs.85).aspx return `Mozilla/5.0 (compatible; MSIE ${ver}.0; Windows NT ${version_string.nt()}; Trident/${version_string.trident()}${ - rnd(0, 1) === 1 ? `; .NET CLR ${version_string.net()}` : '' + faker.datatype.boolean() ? `; .NET CLR ${version_string.net()}` : '' })`; }, From 75700c21ab7f9c801c70835174097ff519fbd55f Mon Sep 17 00:00:00 2001 From: xDivisionByZerox Date: Wed, 20 Jul 2022 18:50:19 +0200 Subject: [PATCH 2/9] chore(user-agent.rnd): remove number input --- src/modules/internet/user-agent.ts | 126 +++++++++++++++++------------ 1 file changed, 75 insertions(+), 51 deletions(-) diff --git a/src/modules/internet/user-agent.ts b/src/modules/internet/user-agent.ts index 751c5f5278e..d1fe2c6400a 100644 --- a/src/modules/internet/user-agent.ts +++ b/src/modules/internet/user-agent.ts @@ -47,46 +47,25 @@ import type { Faker } from '../..'; export type Arch = 'lin' | 'mac' | 'win'; export function generate(faker: Faker): string { - function rnd( - a?: number | Record, - b?: number - ): string | number { - //calling rnd() with no arguments is identical to rnd(0, 100) - a = a || 0; - b = b || 100; + function rnd(obj: Record): string { + //returns a random key from the passed object; keys are weighted by the decimal probability in their value + const rand = faker.datatype.number({ min: 0, max: 100 }) / 100; + let min = 0; + let max = 0; + let return_val: string; - if (typeof b === 'number' && typeof a === 'number') { - // 9/2018 - Added faker random to ensure mersenne and seed - return faker.datatype.number({ min: a, max: b }); - } - - if (a && typeof a === 'object') { - //returns a random key from the passed object; keys are weighted by the decimal probability in their value - return ((obj) => { - const rand = (rnd(0, 100) as number) / 100; - let min = 0; - let max = 0; - let return_val: string; - - for (const key in obj) { - if (Object.prototype.hasOwnProperty.call(obj, key)) { - max = obj[key] + min; - return_val = key; - if (rand >= min && rand <= max) { - break; - } - min = min + obj[key]; - } + for (const key in obj) { + if (Object.prototype.hasOwnProperty.call(obj, key)) { + max = obj[key] + min; + return_val = key; + if (rand >= min && rand <= max) { + break; } - - return return_val; - })(a); + min = min + obj[key]; + } } - throw new TypeError( - // eslint-disable-next-line @typescript-eslint/restrict-template-expressions - `Invalid arguments passed to rnd. (${b ? `${a}, ${b}` : a})` - ); + return return_val; } function randomLang(): string { @@ -228,45 +207,72 @@ export function generate(faker: Faker): string { //generate a random revision //dots = 2 returns .x.y where x & y are between 0 and 9 for (let x = 0; x < dots; x++) { - return_val += `.${rnd(0, 9)}`; + return_val += `.${faker.datatype.number({ min: 0, max: 9 })}`; } return return_val; } const version_string = { net() { - return [rnd(1, 4), rnd(0, 9), rnd(10000, 99999), rnd(0, 9)].join('.'); + return [ + faker.datatype.number({ min: 1, max: 4 }), + faker.datatype.number({ min: 0, max: 9 }), + faker.datatype.number({ min: 10000, max: 99999 }), + faker.datatype.number({ min: 0, max: 9 }), + ].join('.'); }, nt() { - return `${rnd(5, 6)}.${rnd(0, 3)}`; + return [ + faker.datatype.number({ min: 5, max: 6 }), + faker.datatype.number({ min: 0, max: 3 }), + ].join('.'); }, ie() { - return rnd(7, 11); + return faker.datatype.number({ min: 7, max: 11 }); }, trident() { - return `${rnd(3, 7)}.${rnd(0, 1)}`; + return [ + faker.datatype.number({ min: 3, max: 7 }), + faker.datatype.number({ min: 0, max: 1 }), + ].join('.'); }, osx(delim?: string) { - return [10, rnd(5, 10), rnd(0, 9)].join(delim || '.'); + return [ + 10, + faker.datatype.number({ min: 5, max: 10 }), + faker.datatype.number({ min: 0, max: 9 }), + ].join(delim || '.'); }, chrome() { - return [rnd(13, 39), 0, rnd(800, 899), 0].join('.'); + return [ + faker.datatype.number({ min: 13, max: 39 }), + 0, + faker.datatype.number({ min: 800, max: 899 }), + 0, + ].join('.'); }, presto() { - return `2.9.${rnd(160, 190)}`; + return `2.9.${faker.datatype.number({ min: 160, max: 190 })}`; }, presto2() { - return `${rnd(10, 12)}.00`; + return `${faker.datatype.number({ min: 10, max: 12 })}.00`; }, safari() { - return `${rnd(531, 538)}.${rnd(0, 2)}.${rnd(0, 2)}`; + return [ + faker.datatype.number({ min: 531, max: 538 }), + faker.datatype.number({ min: 0, max: 2 }), + faker.datatype.number({ min: 0, max: 2 }), + ].join('.'); }, }; const browser = { firefox(arch: Arch): string { //https://developer.mozilla.org/en-US/docs/Gecko_user_agent_string_reference - const firefox_ver = `${rnd(5, 15)}${randomRevision(2)}`, + const firefox_ver = `${faker.datatype.number({ + min: 5, + max: 15, + })}${randomRevision(2)}`, gecko_ver = `Gecko/20100101 Firefox/${firefox_ver}`, proc = randomProc(arch), os_ver = @@ -287,7 +293,10 @@ export function generate(faker: Faker): string { if (ver >= 11) { //http://msdn.microsoft.com/en-us/library/ie/hh869301(v=vs.85).aspx - return `Mozilla/5.0 (Windows NT 6.${rnd(1, 3)}; Trident/7.0; ${ + return `Mozilla/5.0 (Windows NT 6.${faker.datatype.number({ + min: 1, + max: 3, + })}; Trident/7.0; ${ faker.datatype.boolean() ? 'Touch; ' : '' }rv:11.0) like Gecko`; } @@ -308,17 +317,32 @@ export function generate(faker: Faker): string { ? `(X11; Linux ${randomProc(arch)}; U; ${randomLang()}${presto_ver}` : `(Macintosh; Intel Mac OS X ${version_string.osx()} U; ${randomLang()} Presto/${version_string.presto()} Version/${version_string.presto2()})`; - return `Opera/${rnd(9, 14)}.${rnd(0, 99)} ${os_ver}`; + return `Opera/${faker.datatype.number({ + min: 9, + max: 14, + })}.${faker.datatype.number({ + min: 0, + max: 99, + })} ${os_ver}`; }, safari(arch: Arch): string { const safari = version_string.safari(), - ver = `${rnd(4, 7)}.${rnd(0, 1)}.${rnd(0, 10)}`, + ver = `${faker.datatype.number({ + min: 4, + max: 7, + })}.${faker.datatype.number({ + min: 0, + max: 1, + })}.${faker.datatype.number({ min: 0, max: 10 })}`, os_ver = arch === 'mac' ? `(Macintosh; ${randomProc('mac')} Mac OS X ${version_string.osx( '_' - )} rv:${rnd(2, 6)}.0; ${randomLang()}) ` + )} rv:${faker.datatype.number({ + min: 2, + max: 6, + })}.0; ${randomLang()}) ` : `(Windows; U; Windows NT ${version_string.nt()})`; return `Mozilla/5.0 ${os_ver}AppleWebKit/${safari} (KHTML, like Gecko) Version/${ver} Safari/${safari}`; From f6204a78e17df00bfd4d65356035803ca1ee15db Mon Sep 17 00:00:00 2001 From: xDivisionByZerox Date: Wed, 20 Jul 2022 18:59:20 +0200 Subject: [PATCH 3/9] chore(user-agent): stricten types --- src/modules/internet/user-agent.ts | 32 +++++++++++++++++------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/src/modules/internet/user-agent.ts b/src/modules/internet/user-agent.ts index d1fe2c6400a..d2bfe0bffdf 100644 --- a/src/modules/internet/user-agent.ts +++ b/src/modules/internet/user-agent.ts @@ -46,8 +46,10 @@ import type { Faker } from '../..'; export type Arch = 'lin' | 'mac' | 'win'; +type Browser = 'chrome' | 'iexplorer' | 'firefox' | 'safari' | 'opera'; + export function generate(faker: Faker): string { - function rnd(obj: Record): string { + function rnd>(obj: T): keyof T { //returns a random key from the passed object; keys are weighted by the decimal probability in their value const rand = faker.datatype.number({ min: 0, max: 100 }) / 100; let min = 0; @@ -169,23 +171,25 @@ export function generate(faker: Faker): string { ]); } - function randomBrowserAndOS(): Array { - const browser = rnd({ + function randomBrowserAndOS(): [Browser, Arch] { + const browser: Browser = rnd({ chrome: 0.45132810566, iexplorer: 0.27477061836, firefox: 0.19384170608, safari: 0.06186781118, opera: 0.01574236955, }); - const os = { - chrome: { win: 0.89, mac: 0.09, lin: 0.02 }, - firefox: { win: 0.83, mac: 0.16, lin: 0.01 }, - opera: { win: 0.91, mac: 0.03, lin: 0.06 }, - safari: { win: 0.04, mac: 0.96 }, - iexplorer: ['win'], - }; + const os: Arch = rnd( + { + chrome: { win: 0.89, mac: 0.09, lin: 0.02 }, + firefox: { win: 0.83, mac: 0.16, lin: 0.01 }, + opera: { win: 0.91, mac: 0.03, lin: 0.06 }, + safari: { win: 0.04, mac: 0.96 }, + iexplorer: { win: 1 }, + }[browser] + ); - return [browser, rnd(os[browser])]; + return [browser, os]; } function randomProc(arch: Arch): string | number { @@ -266,7 +270,7 @@ export function generate(faker: Faker): string { }, }; - const browser = { + const browserMap = { firefox(arch: Arch): string { //https://developer.mozilla.org/en-US/docs/Gecko_user_agent_string_reference const firefox_ver = `${faker.datatype.number({ @@ -363,6 +367,6 @@ export function generate(faker: Faker): string { }, }; - const random = randomBrowserAndOS(); - return browser[random[0]](random[1]); + const [browser, arch] = randomBrowserAndOS(); + return browserMap[browser](arch); } From 9b3a4829a365e4f15a1aaf43f848f1ed67054dfb Mon Sep 17 00:00:00 2001 From: xDivisionByZerox Date: Wed, 20 Jul 2022 19:00:55 +0200 Subject: [PATCH 4/9] chore(user-agent.rnd): rename to weightedKeyFromObject --- src/modules/internet/user-agent.ts | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/modules/internet/user-agent.ts b/src/modules/internet/user-agent.ts index d2bfe0bffdf..1befc27a6f4 100644 --- a/src/modules/internet/user-agent.ts +++ b/src/modules/internet/user-agent.ts @@ -49,7 +49,9 @@ export type Arch = 'lin' | 'mac' | 'win'; type Browser = 'chrome' | 'iexplorer' | 'firefox' | 'safari' | 'opera'; export function generate(faker: Faker): string { - function rnd>(obj: T): keyof T { + function weightedKeyFromObject>( + obj: T + ): keyof T { //returns a random key from the passed object; keys are weighted by the decimal probability in their value const rand = faker.datatype.number({ min: 0, max: 100 }) / 100; let min = 0; @@ -172,14 +174,14 @@ export function generate(faker: Faker): string { } function randomBrowserAndOS(): [Browser, Arch] { - const browser: Browser = rnd({ + const browser: Browser = weightedKeyFromObject({ chrome: 0.45132810566, iexplorer: 0.27477061836, firefox: 0.19384170608, safari: 0.06186781118, opera: 0.01574236955, }); - const os: Arch = rnd( + const os: Arch = weightedKeyFromObject( { chrome: { win: 0.89, mac: 0.09, lin: 0.02 }, firefox: { win: 0.83, mac: 0.16, lin: 0.01 }, @@ -201,7 +203,7 @@ export function generate(faker: Faker): string { const archValue = procs[arch]; const proc = Array.isArray(archValue) ? faker.helpers.arrayElement(archValue) - : rnd(archValue); + : weightedKeyFromObject(archValue); return proc; } From ba7fd823eb4186636ca21d951142b50fab30dbad Mon Sep 17 00:00:00 2001 From: xDivisionByZerox Date: Wed, 20 Jul 2022 19:02:38 +0200 Subject: [PATCH 5/9] chore(user-agent): convert functions to const with function reference --- src/modules/internet/user-agent.ts | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/modules/internet/user-agent.ts b/src/modules/internet/user-agent.ts index 1befc27a6f4..344b9ec17d6 100644 --- a/src/modules/internet/user-agent.ts +++ b/src/modules/internet/user-agent.ts @@ -49,9 +49,9 @@ export type Arch = 'lin' | 'mac' | 'win'; type Browser = 'chrome' | 'iexplorer' | 'firefox' | 'safari' | 'opera'; export function generate(faker: Faker): string { - function weightedKeyFromObject>( + const weightedKeyFromObject = >( obj: T - ): keyof T { + ): keyof T => { //returns a random key from the passed object; keys are weighted by the decimal probability in their value const rand = faker.datatype.number({ min: 0, max: 100 }) / 100; let min = 0; @@ -70,9 +70,9 @@ export function generate(faker: Faker): string { } return return_val; - } + }; - function randomLang(): string { + const randomLang = (): string => { return faker.helpers.arrayElement([ 'AB', 'AF', @@ -171,9 +171,9 @@ export function generate(faker: Faker): string { 'YI', 'ZH', ]); - } + }; - function randomBrowserAndOS(): [Browser, Arch] { + const randomBrowserAndOS = (): [Browser, Arch] => { const browser: Browser = weightedKeyFromObject({ chrome: 0.45132810566, iexplorer: 0.27477061836, @@ -192,9 +192,9 @@ export function generate(faker: Faker): string { ); return [browser, os]; - } + }; - function randomProc(arch: Arch): string | number { + const randomProc = (arch: Arch): string => { const procs = { lin: ['i686', 'x86_64'], mac: { Intel: 0.48, PPC: 0.01, 'U; Intel': 0.48, 'U; PPC': 0.01 }, @@ -206,9 +206,9 @@ export function generate(faker: Faker): string { : weightedKeyFromObject(archValue); return proc; - } + }; - function randomRevision(dots: number): string { + const randomRevision = (dots: number): string => { let return_val = ''; //generate a random revision //dots = 2 returns .x.y where x & y are between 0 and 9 @@ -216,7 +216,7 @@ export function generate(faker: Faker): string { return_val += `.${faker.datatype.number({ min: 0, max: 9 })}`; } return return_val; - } + }; const version_string = { net() { From e1960e6f0cf47b3fcdd60b97036939191e015a86 Mon Sep 17 00:00:00 2001 From: xDivisionByZerox Date: Wed, 20 Jul 2022 19:07:26 +0200 Subject: [PATCH 6/9] chore(user-agen): fix linter warnings --- src/modules/internet/user-agent.ts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/modules/internet/user-agent.ts b/src/modules/internet/user-agent.ts index 344b9ec17d6..ced2227cb31 100644 --- a/src/modules/internet/user-agent.ts +++ b/src/modules/internet/user-agent.ts @@ -44,10 +44,17 @@ import type { Faker } from '../..'; +// I don't think this should be exposed, since it can potentially be imported via: +// import { Arch } from '@faker-js/faker/modules/internet/user-agent'; export type Arch = 'lin' | 'mac' | 'win'; type Browser = 'chrome' | 'iexplorer' | 'firefox' | 'safari' | 'opera'; +/** + * Generates a random user-agent. + * + * @param faker An existing faker instance. + */ export function generate(faker: Faker): string { const weightedKeyFromObject = >( obj: T From 5b33f5a1b4126453d4ad0c1400cf72b380e29589 Mon Sep 17 00:00:00 2001 From: xDivisionByZerox Date: Thu, 21 Jul 2022 23:43:28 +0200 Subject: [PATCH 7/9] chore(user-agent.randomLang): fix arrow style --- src/modules/internet/user-agent.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/modules/internet/user-agent.ts b/src/modules/internet/user-agent.ts index ced2227cb31..3b0765bdfd0 100644 --- a/src/modules/internet/user-agent.ts +++ b/src/modules/internet/user-agent.ts @@ -79,8 +79,8 @@ export function generate(faker: Faker): string { return return_val; }; - const randomLang = (): string => { - return faker.helpers.arrayElement([ + const randomLang = (): string => + faker.helpers.arrayElement([ 'AB', 'AF', 'AN', @@ -178,7 +178,6 @@ export function generate(faker: Faker): string { 'YI', 'ZH', ]); - }; const randomBrowserAndOS = (): [Browser, Arch] => { const browser: Browser = weightedKeyFromObject({ From bf30a9fa9db214be24e6921897d7cff766a2b608 Mon Sep 17 00:00:00 2001 From: xDivisionByZerox Date: Thu, 21 Jul 2022 23:44:48 +0200 Subject: [PATCH 8/9] chore(user-agent): remove type export --- src/modules/internet/user-agent.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/modules/internet/user-agent.ts b/src/modules/internet/user-agent.ts index 3b0765bdfd0..8657465020c 100644 --- a/src/modules/internet/user-agent.ts +++ b/src/modules/internet/user-agent.ts @@ -44,9 +44,7 @@ import type { Faker } from '../..'; -// I don't think this should be exposed, since it can potentially be imported via: -// import { Arch } from '@faker-js/faker/modules/internet/user-agent'; -export type Arch = 'lin' | 'mac' | 'win'; +type Arch = 'lin' | 'mac' | 'win'; type Browser = 'chrome' | 'iexplorer' | 'firefox' | 'safari' | 'opera'; From f6699e4e31792521287785cb6ca606a1ba773412 Mon Sep 17 00:00:00 2001 From: xDivisionByZerox Date: Mon, 25 Jul 2022 22:52:28 +0200 Subject: [PATCH 9/9] chore(user-agent): rename type Arch to OS --- src/modules/internet/user-agent.ts | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/modules/internet/user-agent.ts b/src/modules/internet/user-agent.ts index 8657465020c..972b25741e8 100644 --- a/src/modules/internet/user-agent.ts +++ b/src/modules/internet/user-agent.ts @@ -44,7 +44,7 @@ import type { Faker } from '../..'; -type Arch = 'lin' | 'mac' | 'win'; +type OS = 'lin' | 'mac' | 'win'; type Browser = 'chrome' | 'iexplorer' | 'firefox' | 'safari' | 'opera'; @@ -177,7 +177,7 @@ export function generate(faker: Faker): string { 'ZH', ]); - const randomBrowserAndOS = (): [Browser, Arch] => { + const randomBrowserAndOS = (): [Browser, OS] => { const browser: Browser = weightedKeyFromObject({ chrome: 0.45132810566, iexplorer: 0.27477061836, @@ -185,7 +185,7 @@ export function generate(faker: Faker): string { safari: 0.06186781118, opera: 0.01574236955, }); - const os: Arch = weightedKeyFromObject( + const os: OS = weightedKeyFromObject( { chrome: { win: 0.89, mac: 0.09, lin: 0.02 }, firefox: { win: 0.83, mac: 0.16, lin: 0.01 }, @@ -198,7 +198,7 @@ export function generate(faker: Faker): string { return [browser, os]; }; - const randomProc = (arch: Arch): string => { + const randomProc = (arch: OS): string => { const procs = { lin: ['i686', 'x86_64'], mac: { Intel: 0.48, PPC: 0.01, 'U; Intel': 0.48, 'U; PPC': 0.01 }, @@ -277,7 +277,7 @@ export function generate(faker: Faker): string { }; const browserMap = { - firefox(arch: Arch): string { + firefox(arch: OS): string { //https://developer.mozilla.org/en-US/docs/Gecko_user_agent_string_reference const firefox_ver = `${faker.datatype.number({ min: 5, @@ -317,7 +317,7 @@ export function generate(faker: Faker): string { })`; }, - opera(arch: Arch): string { + opera(arch: OS): string { //http://www.opera.com/docs/history/ const presto_ver = ` Presto/${version_string.presto()} Version/${version_string.presto2()})`, os_ver = @@ -336,7 +336,7 @@ export function generate(faker: Faker): string { })} ${os_ver}`; }, - safari(arch: Arch): string { + safari(arch: OS): string { const safari = version_string.safari(), ver = `${faker.datatype.number({ min: 4, @@ -358,7 +358,7 @@ export function generate(faker: Faker): string { return `Mozilla/5.0 ${os_ver}AppleWebKit/${safari} (KHTML, like Gecko) Version/${ver} Safari/${safari}`; }, - chrome(arch: Arch): string { + chrome(arch: OS): string { const safari = version_string.safari(), os_ver = arch === 'mac'