/* eslint-disable @typescript-eslint/no-unnecessary-type-assertion */ /* eslint-disable @typescript-eslint/consistent-type-assertions */ import type { Context } from "koa"; import qs from "qs"; import { promises as fs } from "node:fs"; import _locreq from "locreq"; const locreq = _locreq(import.meta.dirname); export async function sleep(time: number) { return new Promise((resolve) => setTimeout(resolve, time)); } export type Awaited = T extends Promise ? U : T; export type UnwrapArray = T extends Array ? U : T; export function* naturalNumbers(min: number, max: number) { for (let i = min; i <= max; i++) { yield i; } } export function UrlWithNewParams( ctx: Context, query_params: Record ): string { return `${ctx.path}?${qs.stringify(query_params)}`; } export function pickRandom(array: [T, ...T[]]): T { return array?.[Math.floor(Math.random() * array.length)] || array[0]; } export function isNonEmpty(a: Array): a is NonEmptyArray { return isNonEmpty.length > 0; } export type NonEmptyArray = [T, ...T[]]; export function pickN(array: [T, ...T[]], n: number): T[] { const s = new Set(); while (s.size != n) { s.add(pickRandom(array)); } return Array.from(s.values()); } export function shuffle(array: T[]): T[] { const array_copy = [...array]; let currentIndex = array_copy.length; // While there remain elements to shuffle... while (currentIndex != 0) { // Pick a remaining element... const randomIndex = Math.floor(Math.random() * currentIndex); currentIndex--; // And swap it with the current element. [array_copy[currentIndex], array_copy[randomIndex]] = [ array_copy[randomIndex] as T, array_copy[currentIndex] as T, ]; } return array_copy; } export const toCheckboxValues = (arr: string[]): Record => arr.reduce((acc: Record, key) => { acc[key] = "on"; return acc; }, {}); export const fromCheckboxValues = (arr: Record | null): string[] => { if (!arr) { return []; } return Object.entries(arr) .filter(([, value]) => value === "on") .map(([key]) => key); }; export const get_css_clump_content = function (clump_name: string) { const path = locreq.resolve(`public/dist/${clump_name}.entrypoint.css`); return fs.readFile(path, "utf-8"); };