mirror of
https://github.com/kennethnym/aris.git
synced 2026-03-24 19:01:17 +00:00
80 lines
2.4 KiB
TypeScript
80 lines
2.4 KiB
TypeScript
|
|
import { and, eq } from "drizzle-orm"
|
||
|
|
|
||
|
|
import type { Database } from "../db/index.ts"
|
||
|
|
|
||
|
|
import { userSources } from "../db/schema.ts"
|
||
|
|
import { SourceNotFoundError } from "./errors.ts"
|
||
|
|
|
||
|
|
export function sources(db: Database, userId: string) {
|
||
|
|
return {
|
||
|
|
/** Returns all enabled sources for the user. */
|
||
|
|
async enabled() {
|
||
|
|
return db
|
||
|
|
.select()
|
||
|
|
.from(userSources)
|
||
|
|
.where(and(eq(userSources.userId, userId), eq(userSources.enabled, true)))
|
||
|
|
},
|
||
|
|
|
||
|
|
/** Returns a specific source by ID, or undefined. */
|
||
|
|
async find(sourceId: string) {
|
||
|
|
const rows = await db
|
||
|
|
.select()
|
||
|
|
.from(userSources)
|
||
|
|
.where(and(eq(userSources.userId, userId), eq(userSources.sourceId, sourceId)))
|
||
|
|
.limit(1)
|
||
|
|
|
||
|
|
return rows[0]
|
||
|
|
},
|
||
|
|
|
||
|
|
/** Enables a source for the user. Throws if the source row doesn't exist. */
|
||
|
|
async enableSource(sourceId: string) {
|
||
|
|
const rows = await db
|
||
|
|
.update(userSources)
|
||
|
|
.set({ enabled: true, updatedAt: new Date() })
|
||
|
|
.where(and(eq(userSources.userId, userId), eq(userSources.sourceId, sourceId)))
|
||
|
|
.returning({ id: userSources.id })
|
||
|
|
|
||
|
|
if (rows.length === 0) {
|
||
|
|
throw new SourceNotFoundError(sourceId, userId)
|
||
|
|
}
|
||
|
|
},
|
||
|
|
|
||
|
|
/** Disables a source for the user. Throws if the source row doesn't exist. */
|
||
|
|
async disableSource(sourceId: string) {
|
||
|
|
const rows = await db
|
||
|
|
.update(userSources)
|
||
|
|
.set({ enabled: false, updatedAt: new Date() })
|
||
|
|
.where(and(eq(userSources.userId, userId), eq(userSources.sourceId, sourceId)))
|
||
|
|
.returning({ id: userSources.id })
|
||
|
|
|
||
|
|
if (rows.length === 0) {
|
||
|
|
throw new SourceNotFoundError(sourceId, userId)
|
||
|
|
}
|
||
|
|
},
|
||
|
|
|
||
|
|
/** Creates or updates the config for a source. */
|
||
|
|
async upsertConfig(sourceId: string, config: Record<string, unknown>) {
|
||
|
|
await db
|
||
|
|
.insert(userSources)
|
||
|
|
.values({ userId, sourceId, config })
|
||
|
|
.onConflictDoUpdate({
|
||
|
|
target: [userSources.userId, userSources.sourceId],
|
||
|
|
set: { config, updatedAt: new Date() },
|
||
|
|
})
|
||
|
|
},
|
||
|
|
|
||
|
|
/** Updates the encrypted credentials for a source. Throws if the source row doesn't exist. */
|
||
|
|
async updateCredentials(sourceId: string, credentials: Buffer) {
|
||
|
|
const rows = await db
|
||
|
|
.update(userSources)
|
||
|
|
.set({ credentials, updatedAt: new Date() })
|
||
|
|
.where(and(eq(userSources.userId, userId), eq(userSources.sourceId, sourceId)))
|
||
|
|
.returning({ id: userSources.id })
|
||
|
|
|
||
|
|
if (rows.length === 0) {
|
||
|
|
throw new SourceNotFoundError(sourceId, userId)
|
||
|
|
}
|
||
|
|
},
|
||
|
|
}
|
||
|
|
}
|