user-agents 1.1.9 → 2.0.0-alpha.4
Sign up to get free protection for your applications and to get access to all the features.
- package/dist/index.cjs +3 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +38 -0
- package/dist/index.d.ts +38 -0
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/user-agents.json +151323 -0
- package/package.json +49 -28
- package/src/{gunzip-data.js → gunzip-data.ts} +4 -5
- package/src/index.ts +4 -0
- package/src/{update-data.js → update-data.ts} +36 -36
- package/src/user-agent.ts +215 -0
- package/.babelrc +0 -31
- package/.circleci/config.yml +0 -207
- package/.clabot +0 -7
- package/.eslintrc +0 -15
- package/.github/pull_request_template.md +0 -7
- package/CLA.md +0 -126
- package/CONTRIBUTING.md +0 -8
- package/media/ycombinator.png +0 -0
- package/src/index.js +0 -4
- package/src/user-agent.js +0 -154
- package/src/user-agents.json.gz +0 -0
- package/test/test-user-agent.js +0 -113
- package/webpack.config.js +0 -49
package/dist/index.cjs
ADDED
@@ -0,0 +1,3 @@
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }var _lodashclonedeep = require('lodash.clonedeep'); var _lodashclonedeep2 = _interopRequireDefault(_lodashclonedeep);var _useragentsjson = require('./user-agents.json'); var _useragentsjson2 = _interopRequireDefault(_useragentsjson);var d=_useragentsjson2.default,m=r=>{let a=r.reduce((e,[n])=>e+n,0),t=0;return r.map(([e,n])=>(t+=e/a,[t,n]))},b=d.map(({weight:r},a)=>[r,a]),A=m(b),u=(r,a=t=>t)=>{let t;return typeof r=="function"?t=[r]:r instanceof RegExp?t=[e=>typeof e=="object"&&e&&"userAgent"in e&&e.userAgent?r.test(e.userAgent):r.test(e)]:r instanceof Array?t=r.map(e=>u(e)):typeof r=="object"?t=Object.entries(r).map(([e,n])=>u(n,s=>s[e])):t=[e=>typeof e=="object"&&e&&"userAgent"in e&&e.userAgent?r===e.userAgent:r===e],e=>{try{let n=a(e);return t.every(s=>s(n))}catch(n){return!1}}},h=r=>{if(!r)return A;let a=u(r),t=[];return d.forEach((e,n)=>{a(e)&&t.push([e.weight,n])}),m(t)},g=(r,a)=>{Object.defineProperty(r,"cumulativeWeightIndexPairs",{configurable:!0,enumerable:!1,writable:!1,value:a})},y,i=class i extends Function{constructor(t){super();this[y]=()=>this.data.userAgent;this.toString=()=>this.data.userAgent;this.random=()=>{let t=new i;return g(t,this.cumulativeWeightIndexPairs),t.randomize(),t};this.randomize=()=>{var s;let t=Math.random(),[,e]=(s=this.cumulativeWeightIndexPairs.find(([c])=>c>t))!=null?s:[];if(e==null)throw new Error("Error finding a random user agent.");let n=d[e];this.data=_lodashclonedeep2.default.call(void 0, n)};if(g(this,h(t)),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)}})}};y=Symbol.toPrimitive,i.random=t=>{try{return new i(t)}catch(e){return null}};var o=i;var w=o;exports.default = w;
|
2
|
+
|
3
|
+
module.exports = exports.default//# sourceMappingURL=index.cjs.map
|
@@ -0,0 +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","error","constructCumulativeWeightIndexPairsFromFilters","filter","rawUserAgent","setCumulativeWeightIndexPairs","userAgent","cumulativeWeightIndexPairs","_a","_UserAgent","randomNumber","cumulativeWeight","target","property","receiver","UserAgent","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"]}
|
package/dist/index.d.cts
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
type NestedValueOf<T> = T extends object ? T[keyof T] | NestedValueOf<T[keyof T]> : T;
|
2
|
+
type Filter<T extends UserAgentData | NestedValueOf<UserAgentData> = UserAgentData> = ((parentObject: T) => boolean) | RegExp | Array<Filter<T>> | {
|
3
|
+
[key: string]: Filter<T>;
|
4
|
+
} | string;
|
5
|
+
interface UserAgentData {
|
6
|
+
appName: 'Netscape';
|
7
|
+
connection: {
|
8
|
+
downlink: number;
|
9
|
+
effectiveType: '3g' | '4g';
|
10
|
+
rtt: number;
|
11
|
+
downlinkMax?: number | null;
|
12
|
+
type?: 'cellular' | 'wifi';
|
13
|
+
};
|
14
|
+
platform: 'iPad' | 'iPhone' | 'Linux aarch64' | 'Linux armv81' | 'Linux armv8l' | 'Linux x86_64' | 'MacIntel' | 'Win32';
|
15
|
+
pluginsLength: number;
|
16
|
+
screenHeight: number;
|
17
|
+
screenWidth: number;
|
18
|
+
userAgent: string;
|
19
|
+
vendor: 'Apple Computer, Inc.' | 'Google Inc.' | '';
|
20
|
+
weight: number;
|
21
|
+
}
|
22
|
+
declare module './user-agent' {
|
23
|
+
interface UserAgent extends Readonly<UserAgentData> {
|
24
|
+
readonly cumulativeWeightIndexPairs: Array<[number, number]>;
|
25
|
+
readonly data: UserAgentData;
|
26
|
+
(): UserAgent;
|
27
|
+
}
|
28
|
+
}
|
29
|
+
declare class UserAgent extends Function {
|
30
|
+
constructor(filters?: Filter);
|
31
|
+
static random: (filters: Filter) => UserAgent | null;
|
32
|
+
[Symbol.toPrimitive]: () => string;
|
33
|
+
toString: () => string;
|
34
|
+
random: () => UserAgent;
|
35
|
+
randomize: () => void;
|
36
|
+
}
|
37
|
+
|
38
|
+
export { Filter, UserAgentData, UserAgent as default };
|
package/dist/index.d.ts
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
type NestedValueOf<T> = T extends object ? T[keyof T] | NestedValueOf<T[keyof T]> : T;
|
2
|
+
type Filter<T extends UserAgentData | NestedValueOf<UserAgentData> = UserAgentData> = ((parentObject: T) => boolean) | RegExp | Array<Filter<T>> | {
|
3
|
+
[key: string]: Filter<T>;
|
4
|
+
} | string;
|
5
|
+
interface UserAgentData {
|
6
|
+
appName: 'Netscape';
|
7
|
+
connection: {
|
8
|
+
downlink: number;
|
9
|
+
effectiveType: '3g' | '4g';
|
10
|
+
rtt: number;
|
11
|
+
downlinkMax?: number | null;
|
12
|
+
type?: 'cellular' | 'wifi';
|
13
|
+
};
|
14
|
+
platform: 'iPad' | 'iPhone' | 'Linux aarch64' | 'Linux armv81' | 'Linux armv8l' | 'Linux x86_64' | 'MacIntel' | 'Win32';
|
15
|
+
pluginsLength: number;
|
16
|
+
screenHeight: number;
|
17
|
+
screenWidth: number;
|
18
|
+
userAgent: string;
|
19
|
+
vendor: 'Apple Computer, Inc.' | 'Google Inc.' | '';
|
20
|
+
weight: number;
|
21
|
+
}
|
22
|
+
declare module './user-agent' {
|
23
|
+
interface UserAgent extends Readonly<UserAgentData> {
|
24
|
+
readonly cumulativeWeightIndexPairs: Array<[number, number]>;
|
25
|
+
readonly data: UserAgentData;
|
26
|
+
(): UserAgent;
|
27
|
+
}
|
28
|
+
}
|
29
|
+
declare class UserAgent extends Function {
|
30
|
+
constructor(filters?: Filter);
|
31
|
+
static random: (filters: Filter) => UserAgent | null;
|
32
|
+
[Symbol.toPrimitive]: () => string;
|
33
|
+
toString: () => string;
|
34
|
+
random: () => UserAgent;
|
35
|
+
randomize: () => void;
|
36
|
+
}
|
37
|
+
|
38
|
+
export { Filter, UserAgentData, UserAgent as default };
|