@imaginerlabs/user-agent-generator
Version:
High-performance, configurable, batch-generating User-Agent spoofing library. Supports multiple browsers, devices, and returns detailed meta information. Perfect for web scraping, automated testing, proxy pools and more.
165 lines (164 loc) • 6.55 kB
JavaScript
;
/**
* Utility Functions Module
* 工具函数模块
*
* This module provides utility functions for the User-Agent generator
* 该模块为 User-Agent 生成器提供工具函数
*/
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.readVersions = readVersions;
exports.pickRandom = pickRandom;
exports.pickWeightedRandom = pickWeightedRandom;
exports.pickWeightedVersionWithSubValue = pickWeightedVersionWithSubValue;
const fs = __importStar(require("fs"));
const path = __importStar(require("path"));
/**
* Read version numbers array from specified data file (supports string or {value, weight})
* 从指定的数据文件中读取版本号数组(支持字符串或 {value, weight} 格式)
*
* @param file Filename (e.g., chrome.json) / 文件名(如 chrome.json)
* @returns Array of version numbers / 版本号数组
*/
function readVersions(file) {
try {
const filePath = path.resolve(__dirname, '../data', file);
const raw = fs.readFileSync(filePath, 'utf-8');
const json = JSON.parse(raw);
return json.versions || [];
}
catch (error) {
throw new Error(`Failed to read versions from file ${file}: ${error}`);
}
}
/**
* Pick a random item from an array
* 从数组中随机选择一个元素
*
* @param array Array to pick from / 要选择的数组
* @param random Optional random number (0-1) / 可选的随机数(0-1)
* @returns Random item from array / 数组中的随机元素
*/
function pickRandom(array, random = Math.random()) {
if (!array || array.length === 0) {
throw new Error('Array is empty or undefined');
}
// Ensure random is within valid range
// 确保随机数在有效范围内
const normalizedRandom = Math.max(0, Math.min(0.999999, random));
return array[Math.floor(normalizedRandom * array.length)];
}
/**
* Pick a random item from a weighted array
* 从带权重的数组中随机选择一个元素
*
* @param array Array of {value, weight} objects / {value, weight} 对象数组
* @param random Optional random number (0-1) / 可选的随机数(0-1)
* @returns Random value based on weights / 基于权重的随机值
*/
function pickWeightedRandom(array, random = Math.random()) {
if (!array || array.length === 0) {
throw new Error('Array is empty or undefined');
}
// Handle single element case
// 处理单元素情况
if (array.length === 1) {
return array[0].value;
}
const totalWeight = array.reduce((sum, item) => sum + Math.max(0, item.weight), 0);
if (totalWeight === 0) {
// When all weights are 0, return the last element
// 所有权重为0时,返回最后一个元素
return array[array.length - 1].value;
}
// Ensure random is within valid range
// 确保随机数在有效范围内
const normalizedRandom = Math.max(0, Math.min(0.999999, random));
// When random=0, return the first element with weight > 0
// random=0时,返回第一个权重大于0的元素
if (normalizedRandom === 0) {
const first = array.find((item) => item.weight > 0);
if (first)
return first.value;
}
let currentWeight = 0;
const targetWeight = normalizedRandom * totalWeight;
for (const item of array) {
if (item.weight > 0) {
currentWeight += item.weight;
if (targetWeight <= currentWeight) {
return item.value;
}
}
}
// Fallback to last element with positive weight
// 回退到最后一个正权重元素
for (let i = array.length - 1; i >= 0; i--) {
if (array[i].weight > 0) {
return array[i].value;
}
}
return array[array.length - 1].value;
}
/**
* Pick a random version from a weighted version array with subValues
* 从带权重的版本数组中随机选择一个版本,并从其 subValue 数组中随机选择具体版本号
*
* @param array Array of {value, weight, subValue} objects / {value, weight, subValue} 对象数组
* @param random Optional random number (0-1) / 可选的随机数(0-1)
* @returns Random subValue based on weights / 基于权重的随机子版本号
*/
function pickWeightedVersionWithSubValue(array, random = Math.random()) {
if (!array || array.length === 0) {
throw new Error('Array is empty or undefined');
}
// First select major version by weight
// 首先按权重选择大版本号
const selectedVersion = pickWeightedRandom(array, random);
// Find the corresponding complete object
// 找到对应的完整对象
const versionObj = array.find((item) => item.value === selectedVersion);
if (!versionObj) {
throw new Error(`Version object not found for value: ${selectedVersion}`);
}
if (!versionObj.subValue || versionObj.subValue.length === 0) {
throw new Error(`SubValue array is empty for version: ${selectedVersion}`);
}
// Randomly select a subValue from the array
// 从数组中随机选择一个 subValue
const subValue = pickRandom(versionObj.subValue, random);
return subValue.value;
}