86 lines
2.3 KiB
TypeScript
86 lines
2.3 KiB
TypeScript
/* 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> = T extends Promise<infer U> ? U : T;
|
|
export type UnwrapArray<T> = T extends Array<infer U> ? 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, unknown>
|
|
): string {
|
|
return `${ctx.path}?${qs.stringify(query_params)}`;
|
|
}
|
|
|
|
export function pickRandom<T>(array: [T, ...T[]]): T {
|
|
return array?.[Math.floor(Math.random() * array.length)] || array[0];
|
|
}
|
|
|
|
export function isNonEmpty<T>(a: Array<T>): a is NonEmptyArray<T> {
|
|
return isNonEmpty.length > 0;
|
|
}
|
|
|
|
export type NonEmptyArray<T> = [T, ...T[]];
|
|
|
|
export function pickN<T>(array: [T, ...T[]], n: number): T[] {
|
|
const s = new Set<T>();
|
|
while (s.size != n) {
|
|
s.add(pickRandom(array));
|
|
}
|
|
|
|
return Array.from(s.values());
|
|
}
|
|
|
|
export function shuffle<T>(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<string, string> =>
|
|
arr.reduce((acc: Record<string, string>, key) => {
|
|
acc[key] = "on";
|
|
return acc;
|
|
}, {});
|
|
|
|
export const fromCheckboxValues = (arr: Record<string, string> | 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");
|
|
};
|