umami/scripts/seed/utils.ts
Arthur Sepiol b7807ed466 feat(dev): add sample data generator script
Adds a CLI tool to generate realistic analytics data for local development and testing.
Creates two demo websites with varying traffic patterns and realistic user behavior distributions.
2025-12-02 13:43:59 +03:00

85 lines
2.2 KiB
TypeScript

import { v4 as uuidv4 } from 'uuid';
export interface WeightedOption<T> {
value: T;
weight: number;
}
export function weightedRandom<T>(options: WeightedOption<T>[]): T {
const totalWeight = options.reduce((sum, opt) => sum + opt.weight, 0);
let random = Math.random() * totalWeight;
for (const option of options) {
random -= option.weight;
if (random <= 0) {
return option.value;
}
}
return options[options.length - 1].value;
}
export function randomInt(min: number, max: number): number {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
export function randomFloat(min: number, max: number): number {
return Math.random() * (max - min) + min;
}
export function pickRandom<T>(array: T[]): T {
return array[Math.floor(Math.random() * array.length)];
}
export function shuffleArray<T>(array: T[]): T[] {
const result = [...array];
for (let i = result.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[result[i], result[j]] = [result[j], result[i]];
}
return result;
}
export function uuid(): string {
return uuidv4();
}
export function generateDatesBetween(startDate: Date, endDate: Date): Date[] {
const dates: Date[] = [];
const current = new Date(startDate);
current.setHours(0, 0, 0, 0);
while (current <= endDate) {
dates.push(new Date(current));
current.setDate(current.getDate() + 1);
}
return dates;
}
export function addHours(date: Date, hours: number): Date {
return new Date(date.getTime() + hours * 60 * 60 * 1000);
}
export function addMinutes(date: Date, minutes: number): Date {
return new Date(date.getTime() + minutes * 60 * 1000);
}
export function addSeconds(date: Date, seconds: number): Date {
return new Date(date.getTime() + seconds * 1000);
}
export function subDays(date: Date, days: number): Date {
return new Date(date.getTime() - days * 24 * 60 * 60 * 1000);
}
export function formatNumber(num: number): string {
return num.toLocaleString();
}
export function progressBar(current: number, total: number, width = 30): string {
const percent = current / total;
const filled = Math.round(width * percent);
const empty = width - filled;
return `[${'█'.repeat(filled)}${'░'.repeat(empty)}] ${Math.round(percent * 100)}%`;
}