A decentralized music tracking and discovery platform built on AT Protocol 馃幍 rocksky.app
spotify atproto lastfm musicbrainz scrobbling listenbrainz
at feat/scrobble-user-avatar 94 lines 2.3 kB view raw
1import SqliteDb from "better-sqlite3"; 2import { 3 Kysely, 4 type Migration, 5 type MigrationProvider, 6 Migrator, 7 SqliteDialect, 8} from "kysely"; 9 10// Types 11 12export type DatabaseSchema = { 13 status: Status; 14 auth_session: AuthSession; 15 auth_state: AuthState; 16}; 17 18export type Status = { 19 uri: string; 20 authorDid: string; 21 status: string; 22 createdAt: string; 23 indexedAt: string; 24}; 25 26export type AuthSession = { 27 key: string; 28 session: AuthSessionJson; 29}; 30 31export type AuthState = { 32 key: string; 33 state: AuthStateJson; 34}; 35 36type AuthStateJson = string; 37 38type AuthSessionJson = string; 39 40// Migrations 41 42const migrations: Record<string, Migration> = {}; 43 44const migrationProvider: MigrationProvider = { 45 async getMigrations() { 46 return migrations; 47 }, 48}; 49 50migrations["001"] = { 51 async up(db: Kysely<unknown>) { 52 await db.schema 53 .createTable("status") 54 .addColumn("uri", "varchar", (col) => col.primaryKey()) 55 .addColumn("authorDid", "varchar", (col) => col.notNull()) 56 .addColumn("status", "varchar", (col) => col.notNull()) 57 .addColumn("createdAt", "varchar", (col) => col.notNull()) 58 .addColumn("indexedAt", "varchar", (col) => col.notNull()) 59 .execute(); 60 await db.schema 61 .createTable("auth_session") 62 .addColumn("key", "varchar", (col) => col.primaryKey()) 63 .addColumn("session", "varchar", (col) => col.notNull()) 64 .execute(); 65 await db.schema 66 .createTable("auth_state") 67 .addColumn("key", "varchar", (col) => col.primaryKey()) 68 .addColumn("state", "varchar", (col) => col.notNull()) 69 .execute(); 70 }, 71 async down(db: Kysely<unknown>) { 72 await db.schema.dropTable("auth_state").execute(); 73 await db.schema.dropTable("auth_session").execute(); 74 await db.schema.dropTable("status").execute(); 75 }, 76}; 77 78// APIs 79 80export const createDb = (location: string): Database => { 81 return new Kysely<DatabaseSchema>({ 82 dialect: new SqliteDialect({ 83 database: new SqliteDb(location), 84 }), 85 }); 86}; 87 88export const migrateToLatest = async (db: Database) => { 89 const migrator = new Migrator({ db, provider: migrationProvider }); 90 const { error } = await migrator.migrateToLatest(); 91 if (error) throw error; 92}; 93 94export type Database = Kysely<DatabaseSchema>;