Files
ghostwriter/server/utils/strava-client.ts
2025-04-11 22:39:56 +03:00

69 lines
1.8 KiB
TypeScript

import { get, isEmpty, tryit } from "radash";
import { isAfter } from "@formkit/tempo";
import { eq } from "drizzle-orm";
import { URLSearchParams } from "url";
const refreshStravaToken = async (refreshToken: string) => {
const config = useRuntimeConfig();
const tokensResponse = await $fetch("https://www.strava.com/oauth/token", {
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
body: new URLSearchParams({
client_id: config.oauth.strava.clientId,
client_secret: config.oauth.strava.clientSecret,
grant_type: "refresh_token",
refresh_token: refreshToken,
}),
});
return {
refreshToken: get(tokensResponse, "refresh_token"),
accessToken: get(tokensResponse, "access_token"),
expiresAt: new Date(get(tokensResponse, "expires_at", 0) * 1000),
needsUpdate: true,
};
};
export const useStrava = async (userId: number) => {
const db = useDrizzle();
const now = new Date();
const user = await db.query.users.findFirst({
where: (f, o) => o.eq(f.id, userId),
with: {
tokens: true,
},
});
if (isEmpty(user)) {
console.error("No user found.");
return;
}
const tokens = isAfter(now, user?.tokens?.expiresAt!)
? await refreshStravaToken(user?.tokens?.refreshToken!)
: user?.tokens;
if (get(tokens, "needsUpdate", false)) {
db.update(tables.tokens)
.set({
refreshToken: tokens?.refreshToken as string,
accessToken: tokens?.accessToken as string,
expiresAt: tokens?.expiresAt,
})
.where(eq(tables.tokens.userId, userId));
}
return tryit(
$fetch.create({
baseURL: "https://www.strava.com/api/v3/",
onRequest({ options }) {
options.headers.set("Authorization", `Bearer ${tokens?.accessToken}`);
},
}),
);
};