function getZonedDateTime(instant?: Temporal.Instant | Date) { if (instant == null) { instant = Temporal.Now.instant(); } else if (instant instanceof Date) { instant = instant.toTemporalInstant(); } return instant.toZonedDateTimeISO("UTC"); } export function generateTimeStringForFileName( instant?: Temporal.Instant | Date, dateOnly: boolean = false, ): string { const time = getZonedDateTime(instant); if (dateOnly) { return time.toPlainDate().toString(); } else { return time.toPlainDateTime().toString().replaceAll(/:|\./g, "-"); } } export function transformProperties( object: T, transformer: (value: T[keyof T], key: keyof T) => N, ): { [k in keyof T]: N } { return Object.fromEntries( Object.entries(object).map(( [k, v], ) => [k, transformer(v, k as keyof T)]), ) as { [k in keyof T]: N }; } export function createSingleton( name: string, ): [() => T, (v: T | null) => void] { let singleton: T | null = null; return [ () => { if (singleton == null) { throw new Error(`Singleton ${name} is not set now.`); } return singleton; }, (newValue: T | null) => singleton = newValue, ]; }