diff options
author | Yuqian Yang <crupest@crupest.life> | 2025-04-10 15:12:46 +0800 |
---|---|---|
committer | Yuqian Yang <crupest@crupest.life> | 2025-05-31 03:11:53 +0800 |
commit | 8cad2ca7812d654016dd7af2ee1695e81778b7db (patch) | |
tree | 9f996532b4bf3b0ebd5ace82f540565bc9f4e8d8 /services/docker/mail-server/relay/util.ts | |
parent | cbeeaf281f400230e4161f08cfef2fe4715f3773 (diff) | |
download | crupest-8cad2ca7812d654016dd7af2ee1695e81778b7db.tar.gz crupest-8cad2ca7812d654016dd7af2ee1695e81778b7db.tar.bz2 crupest-8cad2ca7812d654016dd7af2ee1695e81778b7db.zip |
HALF WORK!
Diffstat (limited to 'services/docker/mail-server/relay/util.ts')
-rw-r--r-- | services/docker/mail-server/relay/util.ts | 60 |
1 files changed, 60 insertions, 0 deletions
diff --git a/services/docker/mail-server/relay/util.ts b/services/docker/mail-server/relay/util.ts new file mode 100644 index 0000000..29cda8b --- /dev/null +++ b/services/docker/mail-server/relay/util.ts @@ -0,0 +1,60 @@ +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<T extends object, N>( + 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<T>( + 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, + ]; +} + +export function withDefaults<T extends object>( + partial: Partial<T> | null | undefined, + defaults: T, +): T { + const result: Record<PropertyKey, unknown> = {}; + for (const [key, value] of Object.entries(defaults)) { + result[key] = partial?.[key as keyof T] ?? value; + } + return result as T; +} |