user-agents 2.0.0-alpha.6 → 2.0.0-alpha.600
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.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/user-agents.json +113656 -88659
- package/package.json +5 -3
- package/src/update-data.ts +0 -4
- package/src/user-agent.ts +2 -0
package/dist/index.cjs
CHANGED
@@ -1,3 +1,3 @@
|
|
1
|
-
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } }var _lodashclonedeep = require('lodash.clonedeep'); var _lodashclonedeep2 = _interopRequireDefault(_lodashclonedeep);var _useragentsjson = require('./user-agents.json'); var _useragentsjson2 = _interopRequireDefault(_useragentsjson);var
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } }var _lodashclonedeep = require('lodash.clonedeep'); var _lodashclonedeep2 = _interopRequireDefault(_lodashclonedeep);var _useragentsjson = require('./user-agents.json'); var _useragentsjson2 = _interopRequireDefault(_useragentsjson);var o=_useragentsjson2.default,d=t=>{let a=t.reduce((e,[n])=>e+n,0),r=0;return t.map(([e,n])=>(r+=e/a,[r,n]))},f=o.map(({weight:t},a)=>[t,a]),p=d(f),u=(t,a=r=>r)=>{let r;return typeof t=="function"?r=[t]:t instanceof RegExp?r=[e=>typeof e=="object"&&e&&"userAgent"in e&&e.userAgent?t.test(e.userAgent):t.test(e)]:t instanceof Array?r=t.map(e=>u(e)):typeof t=="object"?r=Object.entries(t).map(([e,n])=>u(n,s=>s[e])):r=[e=>typeof e=="object"&&e&&"userAgent"in e&&e.userAgent?t===e.userAgent:t===e],e=>{try{let n=a(e);return r.every(s=>s(n))}catch (e2){return!1}}},A=t=>{if(!t)return p;let a=u(t),r=[];return o.forEach((e,n)=>{a(e)&&r.push([e.weight,n])}),d(r)},c=(t,a)=>{Object.defineProperty(t,"cumulativeWeightIndexPairs",{configurable:!0,enumerable:!1,writable:!1,value:a})},b,i=class t extends Function{constructor(r){super();this[b]=()=>this.data.userAgent;this.toString=()=>this.data.userAgent;this.random=()=>{let r=new t;return c(r,this.cumulativeWeightIndexPairs),r.randomize(),r};this.randomize=()=>{let r=Math.random(),[,e]=_nullishCoalesce(this.cumulativeWeightIndexPairs.find(([s])=>s>r), () => ([]));if(e==null)throw new Error("Error finding a random user agent.");let n=o[e];this.data=_lodashclonedeep2.default.call(void 0, n)};if(c(this,A(r)),this.cumulativeWeightIndexPairs.length===0)throw new Error("No user agents matched your filters.");return this.randomize(),new Proxy(this,{apply:()=>this.random(),get:(e,n,s)=>{if(e.data&&typeof n=="string"&&Object.prototype.hasOwnProperty.call(e.data,n)&&Object.prototype.propertyIsEnumerable.call(e.data,n)){let l=e.data[n];if(l!==void 0)return l}return Reflect.get(e,n,s)}})}static{b=Symbol.toPrimitive}static{this.random=r=>{try{return new t(r)}catch (e3){return null}}}};var P=i;exports.default = P;
|
2
2
|
|
3
3
|
module.exports = exports.default//# sourceMappingURL=index.cjs.map
|
package/dist/index.cjs.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"sources":["../src/user-agent.ts","../src/index.ts"],"names":["cloneDeep","untypedUserAgents","userAgents","makeCumulativeWeightIndexPairs","weightIndexPairs","totalWeight","sum","weight","index","defaultWeightIndexPairs","defaultCumulativeWeightIndexPairs","constructFilter","filters","accessor","parentObject","childFilters","value","childFilter","key","valueFilter","constructCumulativeWeightIndexPairsFromFilters","filter","rawUserAgent","setCumulativeWeightIndexPairs","userAgent","cumulativeWeightIndexPairs","_a","UserAgent","_UserAgent","randomNumber","cumulativeWeight","target","property","receiver","src_default"],"mappings":"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","sourcesContent":["import cloneDeep from 'lodash.clonedeep';\n\nimport untypedUserAgents from './user-agents.json' assert { type: 'json' };\n\nconst userAgents: UserAgentData[] = untypedUserAgents as UserAgentData[];\n\ntype NestedValueOf<T> = T extends object ? T[keyof T] | NestedValueOf<T[keyof T]> : T;\n\nexport type Filter<T extends UserAgentData | NestedValueOf<UserAgentData> = UserAgentData> =\n | ((parentObject: T) => boolean)\n | RegExp\n | Array<Filter<T>>\n | { [key: string]: Filter<T> }\n | string;\n\nexport interface UserAgentData {\n appName: 'Netscape';\n connection: {\n downlink: number;\n effectiveType: '3g' | '4g';\n rtt: number;\n downlinkMax?: number | null;\n type?: 'cellular' | 'wifi';\n };\n platform:\n | 'iPad'\n | 'iPhone'\n | 'Linux aarch64'\n | 'Linux armv81'\n | 'Linux armv8l'\n | 'Linux x86_64'\n | 'MacIntel'\n | 'Win32';\n pluginsLength: number;\n screenHeight: number;\n screenWidth: number;\n userAgent: string;\n vendor: 'Apple Computer, Inc.' | 'Google Inc.' | '';\n weight: number;\n}\n\ndeclare module './user-agent' {\n export interface UserAgent extends Readonly<UserAgentData> {\n readonly cumulativeWeightIndexPairs: Array<[number, number]>;\n readonly data: UserAgentData;\n (): UserAgent;\n }\n}\n\n// Normalizes the total weight to 1 and constructs a cumulative distribution.\nconst makeCumulativeWeightIndexPairs = (\n weightIndexPairs: Array<[number, number]>,\n): Array<[number, number]> => {\n const totalWeight = weightIndexPairs.reduce((sum, [weight]) => sum + weight, 0);\n let sum = 0;\n return weightIndexPairs.map(([weight, index]) => {\n sum += weight / totalWeight;\n return [sum, index];\n });\n};\n\n// Precompute these so that we can quickly generate unfiltered user agents.\nconst defaultWeightIndexPairs: Array<[number, number]> = userAgents.map(({ weight }, index) => [\n weight,\n index,\n]);\nconst defaultCumulativeWeightIndexPairs = makeCumulativeWeightIndexPairs(defaultWeightIndexPairs);\n\n// Turn the various filter formats into a single filter function that acts on raw user agents.\nconst constructFilter = <T extends UserAgentData | NestedValueOf<UserAgentData>>(\n filters: Filter<T>,\n accessor: (parentObject: T) => T | NestedValueOf<T> = (parentObject: T): T => parentObject,\n): ((profile: T) => boolean) => {\n // WARNING: This type and a lot of the types in here are wrong, but I can't get TypeScript to\n // resolve things correctly so this will have to do for now.\n let childFilters: Array<(parentObject: T) => boolean>;\n if (typeof filters === 'function') {\n childFilters = [filters];\n } else if (filters instanceof RegExp) {\n childFilters = [\n (value: T | NestedValueOf<T>) =>\n typeof value === 'object' && value && 'userAgent' in value && value.userAgent\n ? filters.test(value.userAgent)\n : filters.test(value as string),\n ];\n } else if (filters instanceof Array) {\n childFilters = filters.map((childFilter) => constructFilter(childFilter));\n } else if (typeof filters === 'object') {\n childFilters = Object.entries(filters).map(([key, valueFilter]) =>\n constructFilter(\n valueFilter as Filter<T>,\n (parentObject: T): T | NestedValueOf<T> =>\n (parentObject as unknown as { [key: string]: NestedValueOf<T> })[key] as NestedValueOf<T>,\n ),\n );\n } else {\n childFilters = [\n (value: T | NestedValueOf<T>) =>\n typeof value === 'object' && value && 'userAgent' in value && value.userAgent\n ? filters === value.userAgent\n : filters === value,\n ];\n }\n\n return (parentObject: T) => {\n try {\n const value = accessor(parentObject);\n return childFilters.every((childFilter) => childFilter(value as T));\n } catch (error) {\n // This happens when a user-agent lacks a nested property.\n return false;\n }\n };\n};\n\n// Construct normalized cumulative weight index pairs given the filters.\nconst constructCumulativeWeightIndexPairsFromFilters = (\n filters?: Filter<UserAgentData>,\n): Array<[number, number]> => {\n if (!filters) {\n return defaultCumulativeWeightIndexPairs;\n }\n\n const filter = constructFilter(filters);\n\n const weightIndexPairs: Array<[number, number]> = [];\n userAgents.forEach((rawUserAgent, index) => {\n if (filter(rawUserAgent)) {\n weightIndexPairs.push([rawUserAgent.weight, index]);\n }\n });\n return makeCumulativeWeightIndexPairs(weightIndexPairs);\n};\n\nconst setCumulativeWeightIndexPairs = (\n userAgent: UserAgent,\n cumulativeWeightIndexPairs: Array<[number, number]>,\n) => {\n Object.defineProperty(userAgent, 'cumulativeWeightIndexPairs', {\n configurable: true,\n enumerable: false,\n writable: false,\n value: cumulativeWeightIndexPairs,\n });\n};\n\nexport class UserAgent extends Function {\n constructor(filters?: Filter) {\n super();\n setCumulativeWeightIndexPairs(this, constructCumulativeWeightIndexPairsFromFilters(filters));\n if (this.cumulativeWeightIndexPairs.length === 0) {\n throw new Error('No user agents matched your filters.');\n }\n\n this.randomize();\n\n // eslint-disable-next-line no-constructor-return\n return new Proxy(this, {\n apply: () => this.random(),\n get: (target, property, receiver) => {\n const dataCandidate =\n target.data &&\n typeof property === 'string' &&\n Object.prototype.hasOwnProperty.call(target.data, property) &&\n Object.prototype.propertyIsEnumerable.call(target.data, property);\n if (dataCandidate) {\n const value = target.data[property as keyof UserAgentData];\n if (value !== undefined) {\n return value;\n }\n }\n\n return Reflect.get(target, property, receiver);\n },\n });\n }\n\n static random = (filters: Filter) => {\n try {\n return new UserAgent(filters);\n } catch (error) {\n return null;\n }\n };\n\n //\n // Standard Object Methods\n //\n\n [Symbol.toPrimitive] = (): string => this.data.userAgent;\n\n toString = (): string => this.data.userAgent;\n\n random = (): UserAgent => {\n const userAgent = new UserAgent();\n setCumulativeWeightIndexPairs(userAgent, this.cumulativeWeightIndexPairs);\n userAgent.randomize();\n return userAgent;\n };\n\n randomize = (): void => {\n // Find a random raw random user agent.\n const randomNumber = Math.random();\n const [, index] =\n this.cumulativeWeightIndexPairs.find(\n ([cumulativeWeight]) => cumulativeWeight > randomNumber,\n ) ?? [];\n if (index == null) {\n throw new Error('Error finding a random user agent.');\n }\n const rawUserAgent = userAgents[index];\n\n (this as { data: UserAgentData }).data = cloneDeep(rawUserAgent);\n };\n}\n","import { Filter, UserAgent, UserAgentData } from './user-agent';\n\nexport default UserAgent;\nexport type { Filter, UserAgentData };\n"]}
|
1
|
+
{"version":3,"sources":["../src/user-agent.ts","../src/index.ts"],"names":["cloneDeep","untypedUserAgents","userAgents","makeCumulativeWeightIndexPairs","weightIndexPairs","totalWeight","sum","weight","index","defaultWeightIndexPairs","defaultCumulativeWeightIndexPairs","constructFilter","filters","accessor","parentObject","childFilters","value","childFilter","key","valueFilter","constructCumulativeWeightIndexPairsFromFilters","filter","rawUserAgent","setCumulativeWeightIndexPairs","userAgent","cumulativeWeightIndexPairs","_a","UserAgent","_UserAgent","randomNumber","cumulativeWeight","target","property","receiver","src_default"],"mappings":"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","sourcesContent":["import cloneDeep from 'lodash.clonedeep';\n\nimport untypedUserAgents from './user-agents.json' assert { type: 'json' };\n\nconst userAgents: UserAgentData[] = untypedUserAgents as UserAgentData[];\n\ntype NestedValueOf<T> = T extends object ? T[keyof T] | NestedValueOf<T[keyof T]> : T;\n\nexport type Filter<T extends UserAgentData | NestedValueOf<UserAgentData> = UserAgentData> =\n | ((parentObject: T) => boolean)\n | RegExp\n | Array<Filter<T>>\n | { [key: string]: Filter<T> }\n | string;\n\nexport interface UserAgentData {\n appName: 'Netscape';\n connection: {\n downlink: number;\n effectiveType: '3g' | '4g';\n rtt: number;\n downlinkMax?: number | null;\n type?: 'cellular' | 'wifi';\n };\n language?: string | null;\n oscpu?: string | null;\n platform:\n | 'iPad'\n | 'iPhone'\n | 'Linux aarch64'\n | 'Linux armv81'\n | 'Linux armv8l'\n | 'Linux x86_64'\n | 'MacIntel'\n | 'Win32';\n pluginsLength: number;\n screenHeight: number;\n screenWidth: number;\n userAgent: string;\n vendor: 'Apple Computer, Inc.' | 'Google Inc.' | '';\n weight: number;\n}\n\ndeclare module './user-agent' {\n export interface UserAgent extends Readonly<UserAgentData> {\n readonly cumulativeWeightIndexPairs: Array<[number, number]>;\n readonly data: UserAgentData;\n (): UserAgent;\n }\n}\n\n// Normalizes the total weight to 1 and constructs a cumulative distribution.\nconst makeCumulativeWeightIndexPairs = (\n weightIndexPairs: Array<[number, number]>,\n): Array<[number, number]> => {\n const totalWeight = weightIndexPairs.reduce((sum, [weight]) => sum + weight, 0);\n let sum = 0;\n return weightIndexPairs.map(([weight, index]) => {\n sum += weight / totalWeight;\n return [sum, index];\n });\n};\n\n// Precompute these so that we can quickly generate unfiltered user agents.\nconst defaultWeightIndexPairs: Array<[number, number]> = userAgents.map(({ weight }, index) => [\n weight,\n index,\n]);\nconst defaultCumulativeWeightIndexPairs = makeCumulativeWeightIndexPairs(defaultWeightIndexPairs);\n\n// Turn the various filter formats into a single filter function that acts on raw user agents.\nconst constructFilter = <T extends UserAgentData | NestedValueOf<UserAgentData>>(\n filters: Filter<T>,\n accessor: (parentObject: T) => T | NestedValueOf<T> = (parentObject: T): T => parentObject,\n): ((profile: T) => boolean) => {\n // WARNING: This type and a lot of the types in here are wrong, but I can't get TypeScript to\n // resolve things correctly so this will have to do for now.\n let childFilters: Array<(parentObject: T) => boolean>;\n if (typeof filters === 'function') {\n childFilters = [filters];\n } else if (filters instanceof RegExp) {\n childFilters = [\n (value: T | NestedValueOf<T>) =>\n typeof value === 'object' && value && 'userAgent' in value && value.userAgent\n ? filters.test(value.userAgent)\n : filters.test(value as string),\n ];\n } else if (filters instanceof Array) {\n childFilters = filters.map((childFilter) => constructFilter(childFilter));\n } else if (typeof filters === 'object') {\n childFilters = Object.entries(filters).map(([key, valueFilter]) =>\n constructFilter(\n valueFilter as Filter<T>,\n (parentObject: T): T | NestedValueOf<T> =>\n (parentObject as unknown as { [key: string]: NestedValueOf<T> })[key] as NestedValueOf<T>,\n ),\n );\n } else {\n childFilters = [\n (value: T | NestedValueOf<T>) =>\n typeof value === 'object' && value && 'userAgent' in value && value.userAgent\n ? filters === value.userAgent\n : filters === value,\n ];\n }\n\n return (parentObject: T) => {\n try {\n const value = accessor(parentObject);\n return childFilters.every((childFilter) => childFilter(value as T));\n } catch (error) {\n // This happens when a user-agent lacks a nested property.\n return false;\n }\n };\n};\n\n// Construct normalized cumulative weight index pairs given the filters.\nconst constructCumulativeWeightIndexPairsFromFilters = (\n filters?: Filter<UserAgentData>,\n): Array<[number, number]> => {\n if (!filters) {\n return defaultCumulativeWeightIndexPairs;\n }\n\n const filter = constructFilter(filters);\n\n const weightIndexPairs: Array<[number, number]> = [];\n userAgents.forEach((rawUserAgent, index) => {\n if (filter(rawUserAgent)) {\n weightIndexPairs.push([rawUserAgent.weight, index]);\n }\n });\n return makeCumulativeWeightIndexPairs(weightIndexPairs);\n};\n\nconst setCumulativeWeightIndexPairs = (\n userAgent: UserAgent,\n cumulativeWeightIndexPairs: Array<[number, number]>,\n) => {\n Object.defineProperty(userAgent, 'cumulativeWeightIndexPairs', {\n configurable: true,\n enumerable: false,\n writable: false,\n value: cumulativeWeightIndexPairs,\n });\n};\n\nexport class UserAgent extends Function {\n constructor(filters?: Filter) {\n super();\n setCumulativeWeightIndexPairs(this, constructCumulativeWeightIndexPairsFromFilters(filters));\n if (this.cumulativeWeightIndexPairs.length === 0) {\n throw new Error('No user agents matched your filters.');\n }\n\n this.randomize();\n\n // eslint-disable-next-line no-constructor-return\n return new Proxy(this, {\n apply: () => this.random(),\n get: (target, property, receiver) => {\n const dataCandidate =\n target.data &&\n typeof property === 'string' &&\n Object.prototype.hasOwnProperty.call(target.data, property) &&\n Object.prototype.propertyIsEnumerable.call(target.data, property);\n if (dataCandidate) {\n const value = target.data[property as keyof UserAgentData];\n if (value !== undefined) {\n return value;\n }\n }\n\n return Reflect.get(target, property, receiver);\n },\n });\n }\n\n static random = (filters: Filter) => {\n try {\n return new UserAgent(filters);\n } catch (error) {\n return null;\n }\n };\n\n //\n // Standard Object Methods\n //\n\n [Symbol.toPrimitive] = (): string => this.data.userAgent;\n\n toString = (): string => this.data.userAgent;\n\n random = (): UserAgent => {\n const userAgent = new UserAgent();\n setCumulativeWeightIndexPairs(userAgent, this.cumulativeWeightIndexPairs);\n userAgent.randomize();\n return userAgent;\n };\n\n randomize = (): void => {\n // Find a random raw random user agent.\n const randomNumber = Math.random();\n const [, index] =\n this.cumulativeWeightIndexPairs.find(\n ([cumulativeWeight]) => cumulativeWeight > randomNumber,\n ) ?? [];\n if (index == null) {\n throw new Error('Error finding a random user agent.');\n }\n const rawUserAgent = userAgents[index];\n\n (this as { data: UserAgentData }).data = cloneDeep(rawUserAgent);\n };\n}\n","import { Filter, UserAgent, UserAgentData } from './user-agent';\n\nexport default UserAgent;\nexport type { Filter, UserAgentData };\n"]}
|
package/dist/index.d.cts
CHANGED
@@ -11,6 +11,8 @@ interface UserAgentData {
|
|
11
11
|
downlinkMax?: number | null;
|
12
12
|
type?: 'cellular' | 'wifi';
|
13
13
|
};
|
14
|
+
language?: string | null;
|
15
|
+
oscpu?: string | null;
|
14
16
|
platform: 'iPad' | 'iPhone' | 'Linux aarch64' | 'Linux armv81' | 'Linux armv8l' | 'Linux x86_64' | 'MacIntel' | 'Win32';
|
15
17
|
pluginsLength: number;
|
16
18
|
screenHeight: number;
|
package/dist/index.d.ts
CHANGED
@@ -11,6 +11,8 @@ interface UserAgentData {
|
|
11
11
|
downlinkMax?: number | null;
|
12
12
|
type?: 'cellular' | 'wifi';
|
13
13
|
};
|
14
|
+
language?: string | null;
|
15
|
+
oscpu?: string | null;
|
14
16
|
platform: 'iPad' | 'iPhone' | 'Linux aarch64' | 'Linux armv81' | 'Linux armv8l' | 'Linux x86_64' | 'MacIntel' | 'Win32';
|
15
17
|
pluginsLength: number;
|
16
18
|
screenHeight: number;
|
package/dist/index.js
CHANGED
@@ -1,2 +1,2 @@
|
|
1
|
-
import g from"lodash.clonedeep";import m from"./user-agents.json"assert{type:"json"};var
|
1
|
+
import g from"lodash.clonedeep";import m from"./user-agents.json"assert{type:"json"};var o=m,d=t=>{let a=t.reduce((e,[n])=>e+n,0),r=0;return t.map(([e,n])=>(r+=e/a,[r,n]))},f=o.map(({weight:t},a)=>[t,a]),p=d(f),u=(t,a=r=>r)=>{let r;return typeof t=="function"?r=[t]:t instanceof RegExp?r=[e=>typeof e=="object"&&e&&"userAgent"in e&&e.userAgent?t.test(e.userAgent):t.test(e)]:t instanceof Array?r=t.map(e=>u(e)):typeof t=="object"?r=Object.entries(t).map(([e,n])=>u(n,s=>s[e])):r=[e=>typeof e=="object"&&e&&"userAgent"in e&&e.userAgent?t===e.userAgent:t===e],e=>{try{let n=a(e);return r.every(s=>s(n))}catch{return!1}}},A=t=>{if(!t)return p;let a=u(t),r=[];return o.forEach((e,n)=>{a(e)&&r.push([e.weight,n])}),d(r)},c=(t,a)=>{Object.defineProperty(t,"cumulativeWeightIndexPairs",{configurable:!0,enumerable:!1,writable:!1,value:a})},b,i=class t extends Function{constructor(r){super();this[b]=()=>this.data.userAgent;this.toString=()=>this.data.userAgent;this.random=()=>{let r=new t;return c(r,this.cumulativeWeightIndexPairs),r.randomize(),r};this.randomize=()=>{let r=Math.random(),[,e]=this.cumulativeWeightIndexPairs.find(([s])=>s>r)??[];if(e==null)throw new Error("Error finding a random user agent.");let n=o[e];this.data=g(n)};if(c(this,A(r)),this.cumulativeWeightIndexPairs.length===0)throw new Error("No user agents matched your filters.");return this.randomize(),new Proxy(this,{apply:()=>this.random(),get:(e,n,s)=>{if(e.data&&typeof n=="string"&&Object.prototype.hasOwnProperty.call(e.data,n)&&Object.prototype.propertyIsEnumerable.call(e.data,n)){let l=e.data[n];if(l!==void 0)return l}return Reflect.get(e,n,s)}})}static{b=Symbol.toPrimitive}static{this.random=r=>{try{return new t(r)}catch{return null}}}};var P=i;export{P as default};
|
2
2
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"sources":["../src/user-agent.ts","../src/index.ts"],"sourcesContent":["import cloneDeep from 'lodash.clonedeep';\n\nimport untypedUserAgents from './user-agents.json' assert { type: 'json' };\n\nconst userAgents: UserAgentData[] = untypedUserAgents as UserAgentData[];\n\ntype NestedValueOf<T> = T extends object ? T[keyof T] | NestedValueOf<T[keyof T]> : T;\n\nexport type Filter<T extends UserAgentData | NestedValueOf<UserAgentData> = UserAgentData> =\n | ((parentObject: T) => boolean)\n | RegExp\n | Array<Filter<T>>\n | { [key: string]: Filter<T> }\n | string;\n\nexport interface UserAgentData {\n appName: 'Netscape';\n connection: {\n downlink: number;\n effectiveType: '3g' | '4g';\n rtt: number;\n downlinkMax?: number | null;\n type?: 'cellular' | 'wifi';\n };\n platform:\n | 'iPad'\n | 'iPhone'\n | 'Linux aarch64'\n | 'Linux armv81'\n | 'Linux armv8l'\n | 'Linux x86_64'\n | 'MacIntel'\n | 'Win32';\n pluginsLength: number;\n screenHeight: number;\n screenWidth: number;\n userAgent: string;\n vendor: 'Apple Computer, Inc.' | 'Google Inc.' | '';\n weight: number;\n}\n\ndeclare module './user-agent' {\n export interface UserAgent extends Readonly<UserAgentData> {\n readonly cumulativeWeightIndexPairs: Array<[number, number]>;\n readonly data: UserAgentData;\n (): UserAgent;\n }\n}\n\n// Normalizes the total weight to 1 and constructs a cumulative distribution.\nconst makeCumulativeWeightIndexPairs = (\n weightIndexPairs: Array<[number, number]>,\n): Array<[number, number]> => {\n const totalWeight = weightIndexPairs.reduce((sum, [weight]) => sum + weight, 0);\n let sum = 0;\n return weightIndexPairs.map(([weight, index]) => {\n sum += weight / totalWeight;\n return [sum, index];\n });\n};\n\n// Precompute these so that we can quickly generate unfiltered user agents.\nconst defaultWeightIndexPairs: Array<[number, number]> = userAgents.map(({ weight }, index) => [\n weight,\n index,\n]);\nconst defaultCumulativeWeightIndexPairs = makeCumulativeWeightIndexPairs(defaultWeightIndexPairs);\n\n// Turn the various filter formats into a single filter function that acts on raw user agents.\nconst constructFilter = <T extends UserAgentData | NestedValueOf<UserAgentData>>(\n filters: Filter<T>,\n accessor: (parentObject: T) => T | NestedValueOf<T> = (parentObject: T): T => parentObject,\n): ((profile: T) => boolean) => {\n // WARNING: This type and a lot of the types in here are wrong, but I can't get TypeScript to\n // resolve things correctly so this will have to do for now.\n let childFilters: Array<(parentObject: T) => boolean>;\n if (typeof filters === 'function') {\n childFilters = [filters];\n } else if (filters instanceof RegExp) {\n childFilters = [\n (value: T | NestedValueOf<T>) =>\n typeof value === 'object' && value && 'userAgent' in value && value.userAgent\n ? filters.test(value.userAgent)\n : filters.test(value as string),\n ];\n } else if (filters instanceof Array) {\n childFilters = filters.map((childFilter) => constructFilter(childFilter));\n } else if (typeof filters === 'object') {\n childFilters = Object.entries(filters).map(([key, valueFilter]) =>\n constructFilter(\n valueFilter as Filter<T>,\n (parentObject: T): T | NestedValueOf<T> =>\n (parentObject as unknown as { [key: string]: NestedValueOf<T> })[key] as NestedValueOf<T>,\n ),\n );\n } else {\n childFilters = [\n (value: T | NestedValueOf<T>) =>\n typeof value === 'object' && value && 'userAgent' in value && value.userAgent\n ? filters === value.userAgent\n : filters === value,\n ];\n }\n\n return (parentObject: T) => {\n try {\n const value = accessor(parentObject);\n return childFilters.every((childFilter) => childFilter(value as T));\n } catch (error) {\n // This happens when a user-agent lacks a nested property.\n return false;\n }\n };\n};\n\n// Construct normalized cumulative weight index pairs given the filters.\nconst constructCumulativeWeightIndexPairsFromFilters = (\n filters?: Filter<UserAgentData>,\n): Array<[number, number]> => {\n if (!filters) {\n return defaultCumulativeWeightIndexPairs;\n }\n\n const filter = constructFilter(filters);\n\n const weightIndexPairs: Array<[number, number]> = [];\n userAgents.forEach((rawUserAgent, index) => {\n if (filter(rawUserAgent)) {\n weightIndexPairs.push([rawUserAgent.weight, index]);\n }\n });\n return makeCumulativeWeightIndexPairs(weightIndexPairs);\n};\n\nconst setCumulativeWeightIndexPairs = (\n userAgent: UserAgent,\n cumulativeWeightIndexPairs: Array<[number, number]>,\n) => {\n Object.defineProperty(userAgent, 'cumulativeWeightIndexPairs', {\n configurable: true,\n enumerable: false,\n writable: false,\n value: cumulativeWeightIndexPairs,\n });\n};\n\nexport class UserAgent extends Function {\n constructor(filters?: Filter) {\n super();\n setCumulativeWeightIndexPairs(this, constructCumulativeWeightIndexPairsFromFilters(filters));\n if (this.cumulativeWeightIndexPairs.length === 0) {\n throw new Error('No user agents matched your filters.');\n }\n\n this.randomize();\n\n // eslint-disable-next-line no-constructor-return\n return new Proxy(this, {\n apply: () => this.random(),\n get: (target, property, receiver) => {\n const dataCandidate =\n target.data &&\n typeof property === 'string' &&\n Object.prototype.hasOwnProperty.call(target.data, property) &&\n Object.prototype.propertyIsEnumerable.call(target.data, property);\n if (dataCandidate) {\n const value = target.data[property as keyof UserAgentData];\n if (value !== undefined) {\n return value;\n }\n }\n\n return Reflect.get(target, property, receiver);\n },\n });\n }\n\n static random = (filters: Filter) => {\n try {\n return new UserAgent(filters);\n } catch (error) {\n return null;\n }\n };\n\n //\n // Standard Object Methods\n //\n\n [Symbol.toPrimitive] = (): string => this.data.userAgent;\n\n toString = (): string => this.data.userAgent;\n\n random = (): UserAgent => {\n const userAgent = new UserAgent();\n setCumulativeWeightIndexPairs(userAgent, this.cumulativeWeightIndexPairs);\n userAgent.randomize();\n return userAgent;\n };\n\n randomize = (): void => {\n // Find a random raw random user agent.\n const randomNumber = Math.random();\n const [, index] =\n this.cumulativeWeightIndexPairs.find(\n ([cumulativeWeight]) => cumulativeWeight > randomNumber,\n ) ?? [];\n if (index == null) {\n throw new Error('Error finding a random user agent.');\n }\n const rawUserAgent = userAgents[index];\n\n (this as { data: UserAgentData }).data = cloneDeep(rawUserAgent);\n };\n}\n","import { Filter, UserAgent, UserAgentData } from './user-agent';\n\nexport default UserAgent;\nexport type { Filter, UserAgentData };\n"],"mappings":"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","names":["cloneDeep","untypedUserAgents","userAgents","makeCumulativeWeightIndexPairs","weightIndexPairs","totalWeight","sum","weight","index","defaultWeightIndexPairs","defaultCumulativeWeightIndexPairs","constructFilter","filters","accessor","parentObject","childFilters","value","childFilter","key","valueFilter","constructCumulativeWeightIndexPairsFromFilters","filter","rawUserAgent","setCumulativeWeightIndexPairs","userAgent","cumulativeWeightIndexPairs","_a","UserAgent","_UserAgent","randomNumber","cumulativeWeight","target","property","receiver","src_default","UserAgent"]}
|
1
|
+
{"version":3,"sources":["../src/user-agent.ts","../src/index.ts"],"sourcesContent":["import cloneDeep from 'lodash.clonedeep';\n\nimport untypedUserAgents from './user-agents.json' assert { type: 'json' };\n\nconst userAgents: UserAgentData[] = untypedUserAgents as UserAgentData[];\n\ntype NestedValueOf<T> = T extends object ? T[keyof T] | NestedValueOf<T[keyof T]> : T;\n\nexport type Filter<T extends UserAgentData | NestedValueOf<UserAgentData> = UserAgentData> =\n | ((parentObject: T) => boolean)\n | RegExp\n | Array<Filter<T>>\n | { [key: string]: Filter<T> }\n | string;\n\nexport interface UserAgentData {\n appName: 'Netscape';\n connection: {\n downlink: number;\n effectiveType: '3g' | '4g';\n rtt: number;\n downlinkMax?: number | null;\n type?: 'cellular' | 'wifi';\n };\n language?: string | null;\n oscpu?: string | null;\n platform:\n | 'iPad'\n | 'iPhone'\n | 'Linux aarch64'\n | 'Linux armv81'\n | 'Linux armv8l'\n | 'Linux x86_64'\n | 'MacIntel'\n | 'Win32';\n pluginsLength: number;\n screenHeight: number;\n screenWidth: number;\n userAgent: string;\n vendor: 'Apple Computer, Inc.' | 'Google Inc.' | '';\n weight: number;\n}\n\ndeclare module './user-agent' {\n export interface UserAgent extends Readonly<UserAgentData> {\n readonly cumulativeWeightIndexPairs: Array<[number, number]>;\n readonly data: UserAgentData;\n (): UserAgent;\n }\n}\n\n// Normalizes the total weight to 1 and constructs a cumulative distribution.\nconst makeCumulativeWeightIndexPairs = (\n weightIndexPairs: Array<[number, number]>,\n): Array<[number, number]> => {\n const totalWeight = weightIndexPairs.reduce((sum, [weight]) => sum + weight, 0);\n let sum = 0;\n return weightIndexPairs.map(([weight, index]) => {\n sum += weight / totalWeight;\n return [sum, index];\n });\n};\n\n// Precompute these so that we can quickly generate unfiltered user agents.\nconst defaultWeightIndexPairs: Array<[number, number]> = userAgents.map(({ weight }, index) => [\n weight,\n index,\n]);\nconst defaultCumulativeWeightIndexPairs = makeCumulativeWeightIndexPairs(defaultWeightIndexPairs);\n\n// Turn the various filter formats into a single filter function that acts on raw user agents.\nconst constructFilter = <T extends UserAgentData | NestedValueOf<UserAgentData>>(\n filters: Filter<T>,\n accessor: (parentObject: T) => T | NestedValueOf<T> = (parentObject: T): T => parentObject,\n): ((profile: T) => boolean) => {\n // WARNING: This type and a lot of the types in here are wrong, but I can't get TypeScript to\n // resolve things correctly so this will have to do for now.\n let childFilters: Array<(parentObject: T) => boolean>;\n if (typeof filters === 'function') {\n childFilters = [filters];\n } else if (filters instanceof RegExp) {\n childFilters = [\n (value: T | NestedValueOf<T>) =>\n typeof value === 'object' && value && 'userAgent' in value && value.userAgent\n ? filters.test(value.userAgent)\n : filters.test(value as string),\n ];\n } else if (filters instanceof Array) {\n childFilters = filters.map((childFilter) => constructFilter(childFilter));\n } else if (typeof filters === 'object') {\n childFilters = Object.entries(filters).map(([key, valueFilter]) =>\n constructFilter(\n valueFilter as Filter<T>,\n (parentObject: T): T | NestedValueOf<T> =>\n (parentObject as unknown as { [key: string]: NestedValueOf<T> })[key] as NestedValueOf<T>,\n ),\n );\n } else {\n childFilters = [\n (value: T | NestedValueOf<T>) =>\n typeof value === 'object' && value && 'userAgent' in value && value.userAgent\n ? filters === value.userAgent\n : filters === value,\n ];\n }\n\n return (parentObject: T) => {\n try {\n const value = accessor(parentObject);\n return childFilters.every((childFilter) => childFilter(value as T));\n } catch (error) {\n // This happens when a user-agent lacks a nested property.\n return false;\n }\n };\n};\n\n// Construct normalized cumulative weight index pairs given the filters.\nconst constructCumulativeWeightIndexPairsFromFilters = (\n filters?: Filter<UserAgentData>,\n): Array<[number, number]> => {\n if (!filters) {\n return defaultCumulativeWeightIndexPairs;\n }\n\n const filter = constructFilter(filters);\n\n const weightIndexPairs: Array<[number, number]> = [];\n userAgents.forEach((rawUserAgent, index) => {\n if (filter(rawUserAgent)) {\n weightIndexPairs.push([rawUserAgent.weight, index]);\n }\n });\n return makeCumulativeWeightIndexPairs(weightIndexPairs);\n};\n\nconst setCumulativeWeightIndexPairs = (\n userAgent: UserAgent,\n cumulativeWeightIndexPairs: Array<[number, number]>,\n) => {\n Object.defineProperty(userAgent, 'cumulativeWeightIndexPairs', {\n configurable: true,\n enumerable: false,\n writable: false,\n value: cumulativeWeightIndexPairs,\n });\n};\n\nexport class UserAgent extends Function {\n constructor(filters?: Filter) {\n super();\n setCumulativeWeightIndexPairs(this, constructCumulativeWeightIndexPairsFromFilters(filters));\n if (this.cumulativeWeightIndexPairs.length === 0) {\n throw new Error('No user agents matched your filters.');\n }\n\n this.randomize();\n\n // eslint-disable-next-line no-constructor-return\n return new Proxy(this, {\n apply: () => this.random(),\n get: (target, property, receiver) => {\n const dataCandidate =\n target.data &&\n typeof property === 'string' &&\n Object.prototype.hasOwnProperty.call(target.data, property) &&\n Object.prototype.propertyIsEnumerable.call(target.data, property);\n if (dataCandidate) {\n const value = target.data[property as keyof UserAgentData];\n if (value !== undefined) {\n return value;\n }\n }\n\n return Reflect.get(target, property, receiver);\n },\n });\n }\n\n static random = (filters: Filter) => {\n try {\n return new UserAgent(filters);\n } catch (error) {\n return null;\n }\n };\n\n //\n // Standard Object Methods\n //\n\n [Symbol.toPrimitive] = (): string => this.data.userAgent;\n\n toString = (): string => this.data.userAgent;\n\n random = (): UserAgent => {\n const userAgent = new UserAgent();\n setCumulativeWeightIndexPairs(userAgent, this.cumulativeWeightIndexPairs);\n userAgent.randomize();\n return userAgent;\n };\n\n randomize = (): void => {\n // Find a random raw random user agent.\n const randomNumber = Math.random();\n const [, index] =\n this.cumulativeWeightIndexPairs.find(\n ([cumulativeWeight]) => cumulativeWeight > randomNumber,\n ) ?? [];\n if (index == null) {\n throw new Error('Error finding a random user agent.');\n }\n const rawUserAgent = userAgents[index];\n\n (this as { data: UserAgentData }).data = cloneDeep(rawUserAgent);\n };\n}\n","import { Filter, UserAgent, UserAgentData } from './user-agent';\n\nexport default UserAgent;\nexport type { Filter, UserAgentData };\n"],"mappings":"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","names":["cloneDeep","untypedUserAgents","userAgents","makeCumulativeWeightIndexPairs","weightIndexPairs","totalWeight","sum","weight","index","defaultWeightIndexPairs","defaultCumulativeWeightIndexPairs","constructFilter","filters","accessor","parentObject","childFilters","value","childFilter","key","valueFilter","constructCumulativeWeightIndexPairsFromFilters","filter","rawUserAgent","setCumulativeWeightIndexPairs","userAgent","cumulativeWeightIndexPairs","_a","UserAgent","_UserAgent","randomNumber","cumulativeWeight","target","property","receiver","src_default","UserAgent"]}
|