52 lines
No EOL
1.5 KiB
TypeScript
52 lines
No EOL
1.5 KiB
TypeScript
/**
|
|
* TGKey — branded type for TG session identifiers.
|
|
* Format: "YYYY-MM-DD-SLOT" e.g. "2026-06-11-20"
|
|
*
|
|
* Usage:
|
|
* import { TGKey } from "@systems/tg-key";
|
|
*
|
|
* const key = TGKey.current({ slot: 20 })
|
|
* const key = TGKey.from({ date: "2026-06-11", slot: 20 })
|
|
* TGKey.parse(key) // { date: "2026-06-11", slot: 20 }
|
|
* TGKey.toHistoryPath(key) // ".../tg-history/2026-06-11-20.json"
|
|
*/
|
|
|
|
import { Paths } from "@paths";
|
|
|
|
export type TGKey = string & { readonly __brand: "TGKey" };
|
|
|
|
export const TGKey = {
|
|
from({ date, slot }: { date: Date | string; slot: number }): TGKey {
|
|
const d = date instanceof Date ? date.toISOString().slice(0, 10) : date;
|
|
const s = String(slot).padStart(2, "0");
|
|
return `${d}-${s}` as TGKey;
|
|
},
|
|
|
|
current({ slot }: { slot: number }): TGKey {
|
|
return TGKey.from({ date: new Date(), slot });
|
|
},
|
|
|
|
parse(key: TGKey): { date: string; slot: number } {
|
|
const parts = key.split("-");
|
|
return {
|
|
date: parts.slice(0, 3).join("-"), // "YYYY-MM-DD"
|
|
slot: parseInt(parts[3], 10),
|
|
};
|
|
},
|
|
|
|
toHistoryPath(key: TGKey): string {
|
|
return Paths.data("tg-history", `${key}.json`);
|
|
},
|
|
|
|
/** Format for display: "11/06/2026 · 20:00" */
|
|
toDisplay(key: TGKey): string {
|
|
const { date, slot } = TGKey.parse(key);
|
|
const [year, month, day] = date.split("-");
|
|
return `${day}/${month}/${year} · ${slot}:00`;
|
|
},
|
|
|
|
/** Check if a string is a valid TGKey */
|
|
isValid(key: string): key is TGKey {
|
|
return /^\d{4}-\d{2}-\d{2}-\d{1,2}$/.test(key);
|
|
},
|
|
}; |