import { eq, or, sql } from "drizzle-orm"; import { TokenAlreadyExistsError } from "~/libs/errors/TokenAlreadyExists"; import type { Env } from "~/types/env"; import { getDb } from "./db"; import { deviceTokensTable } from "./schema"; export function saveToken( env: Env, deviceId: string, token: string, username: string | null, ) { return getDb(env) .select() .from(deviceTokensTable) .where( or( eq(deviceTokensTable.deviceId, deviceId), eq(deviceTokensTable.token, token), ), ) .then((existingTokens) => { const existingToken = existingTokens.find( ({ token: existingToken, deviceId: existingDeviceId }) => existingToken === token || existingDeviceId === deviceId, ); if (!existingToken) { return insertToken(env, deviceId, token, username); } if ( existingToken.token === token && !existingToken.username && !username ) { throw new TokenAlreadyExistsError(); } return updateToken(env, deviceId, token, username); }); } function insertToken( env: Env, deviceId: string, token: string, username: string | null, ) { return getDb(env) .insert(deviceTokensTable) .values({ deviceId, token, username }) .run(); } function updateToken( env: Env, deviceId: string, token: string, username: string | null, ) { return getDb(env) .update(deviceTokensTable) .set({ token, username }) .where(eq(deviceTokensTable.deviceId, deviceId)) .run(); } export function updateDeviceLastConnectedAt(env: Env, deviceId: string) { return getDb(env) .update(deviceTokensTable) .set({ lastConnectedAt: sql`(CURRENT_TIMESTAMP)` }) .where(eq(deviceTokensTable.deviceId, deviceId)) .run(); }