Files
authentik/web/e2e/utils/generators.ts
2025-09-16 08:37:26 -04:00

82 lines
2.2 KiB
TypeScript

import { readFileSync } from "node:fs";
import { join } from "node:path";
import { fileURLToPath } from "node:url";
import { IDGenerator } from "@goauthentik/core/id";
import { capitalCase } from "change-case";
const __dirname = fileURLToPath(new URL(".", import.meta.url));
const dictionaries = join(__dirname, "dictionaries");
function simpleHash(seed: string) {
let hash = 0;
for (let i = 0; i < seed.length; i++) {
hash = (hash * 31 + seed.charCodeAt(i)) | 0; // keep it 32-bit
}
return Math.abs(hash);
}
class LazyDictionary {
#entries: string[] = [];
#filePath: string;
#loaded = false;
constructor(filePath: string) {
this.#filePath = filePath;
}
public load() {
if (this.#loaded) return;
this.#entries = readFileSync(this.#filePath, "utf8").split("\n").filter(Boolean);
this.#loaded = true;
return this.#entries;
}
public random(seed: string) {
this.load();
// We use modulo to ensure that the seed is always within the range of the dictionary
const index = Math.floor(simpleHash(seed) % this.#entries.length);
return this.#entries[index];
}
}
const Adjectives = new LazyDictionary(join(dictionaries, "adjectives.txt"));
const Colors = new LazyDictionary(join(dictionaries, "colors.txt"));
/**
* Generate a random phrase consisting of an two adjectives and a color.
*
* @param seeds Seeds to use for the random number generator.
*/
export function randomPhrases(...seeds: string[]) {
const [
adjectiveSeed1 = IDGenerator.randomID(),
adjectiveSeed2 = IDGenerator.randomID(),
// Ensure a pairing of the first adjective and color is always used
// allow for a more predictable result.
colorSeed = adjectiveSeed1,
] = seeds;
const adjective1 = Adjectives.random(adjectiveSeed1);
const adjective2 = Adjectives.random(adjectiveSeed2);
const color = Colors.random(colorSeed);
return [adjective1, adjective2, color];
}
/**
* Generate a random name consisting of an adjective, a color, and a phrase.
*
* @param seeds Seeds to use for the random number generator.
*/
export function randomName(...seeds: string[]) {
return capitalCase(randomPhrases(...seeds).join(" "));
}