53 lines
1.7 KiB
TypeScript
53 lines
1.7 KiB
TypeScript
import type { GarminConnect } from "garmin-connect";
|
|
|
|
export type DayWellness = {
|
|
date: string;
|
|
sleepDurationMin?: number;
|
|
sleepScore?: number;
|
|
deepSleepMin?: number;
|
|
remSleepMin?: number;
|
|
avgOvernightHrv?: number;
|
|
hrvStatus?: string;
|
|
restingHr?: number;
|
|
bodyBatteryChange?: number;
|
|
};
|
|
|
|
export async function fetchRecentWellness(
|
|
client: GarminConnect,
|
|
days: number
|
|
): Promise<DayWellness[]> {
|
|
const today = new Date();
|
|
|
|
const dates = Array.from({ length: days }, (_, i) => {
|
|
const d = new Date(today);
|
|
d.setDate(d.getDate() - i);
|
|
return d;
|
|
});
|
|
|
|
const results = await Promise.allSettled(
|
|
dates.map((date) => client.getSleepData(date))
|
|
);
|
|
|
|
return results
|
|
.map((result, i) => {
|
|
const dateStr = dates[i].toISOString().slice(0, 10);
|
|
if (result.status === "rejected" || !result.value?.dailySleepDTO) {
|
|
return { date: dateStr };
|
|
}
|
|
const { value: data } = result;
|
|
const dto = data.dailySleepDTO;
|
|
return {
|
|
date: dateStr,
|
|
sleepDurationMin: dto.sleepTimeSeconds ? Math.round(dto.sleepTimeSeconds / 60) : undefined,
|
|
sleepScore: dto.sleepScores?.overall?.value ?? undefined,
|
|
deepSleepMin: dto.deepSleepSeconds ? Math.round(dto.deepSleepSeconds / 60) : undefined,
|
|
remSleepMin: dto.remSleepSeconds ? Math.round(dto.remSleepSeconds / 60) : undefined,
|
|
avgOvernightHrv: data.avgOvernightHrv || undefined,
|
|
hrvStatus: data.hrvStatus || undefined,
|
|
restingHr: data.restingHeartRate || undefined,
|
|
bodyBatteryChange: typeof data.bodyBatteryChange === "number" ? data.bodyBatteryChange : undefined,
|
|
};
|
|
})
|
|
.sort((a, b) => a.date.localeCompare(b.date));
|
|
}
|