@rocksky/cli 0.1.1 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +270 -1
- package/TOOLS.md +194 -0
- package/bun.lock +28 -0
- package/dist/drizzle/0000_parallel_paper_doll.sql +220 -0
- package/dist/drizzle/meta/0000_snapshot.json +1559 -0
- package/dist/drizzle/meta/_journal.json +13 -0
- package/dist/index.js +8718 -165
- package/drizzle/0000_parallel_paper_doll.sql +220 -0
- package/drizzle/meta/0000_snapshot.json +1559 -0
- package/drizzle/meta/_journal.json +13 -0
- package/drizzle.config.ts +18 -0
- package/package.json +34 -4
- package/src/client.ts +32 -14
- package/src/cmd/mcp.ts +8 -0
- package/src/cmd/scrobble-api.ts +457 -0
- package/src/cmd/scrobble.ts +14 -61
- package/src/cmd/search.ts +27 -25
- package/src/cmd/sync.ts +812 -0
- package/src/cmd/whoami.ts +36 -7
- package/src/context.ts +24 -0
- package/src/drizzle.ts +53 -0
- package/src/index.ts +72 -23
- package/src/jetstream.ts +285 -0
- package/src/lexicon/index.ts +1321 -0
- package/src/lexicon/lexicons.ts +5453 -0
- package/src/lexicon/types/app/bsky/actor/profile.ts +38 -0
- package/src/lexicon/types/app/rocksky/actor/defs.ts +146 -0
- package/src/lexicon/types/app/rocksky/actor/getActorAlbums.ts +56 -0
- package/src/lexicon/types/app/rocksky/actor/getActorArtists.ts +56 -0
- package/src/lexicon/types/app/rocksky/actor/getActorCompatibility.ts +48 -0
- package/src/lexicon/types/app/rocksky/actor/getActorLovedSongs.ts +52 -0
- package/src/lexicon/types/app/rocksky/actor/getActorNeighbours.ts +48 -0
- package/src/lexicon/types/app/rocksky/actor/getActorPlaylists.ts +52 -0
- package/src/lexicon/types/app/rocksky/actor/getActorScrobbles.ts +52 -0
- package/src/lexicon/types/app/rocksky/actor/getActorSongs.ts +56 -0
- package/src/lexicon/types/app/rocksky/actor/getProfile.ts +43 -0
- package/src/lexicon/types/app/rocksky/album/defs.ts +85 -0
- package/src/lexicon/types/app/rocksky/album/getAlbum.ts +43 -0
- package/src/lexicon/types/app/rocksky/album/getAlbumTracks.ts +48 -0
- package/src/lexicon/types/app/rocksky/album/getAlbums.ts +50 -0
- package/src/lexicon/types/app/rocksky/album.ts +51 -0
- package/src/lexicon/types/app/rocksky/apikey/createApikey.ts +51 -0
- package/src/lexicon/types/app/rocksky/apikey/defs.ts +31 -0
- package/src/lexicon/types/app/rocksky/apikey/getApikeys.ts +50 -0
- package/src/lexicon/types/app/rocksky/apikey/removeApikey.ts +43 -0
- package/src/lexicon/types/app/rocksky/apikey/updateApikey.ts +53 -0
- package/src/lexicon/types/app/rocksky/apikeys/defs.ts +7 -0
- package/src/lexicon/types/app/rocksky/artist/defs.ts +140 -0
- package/src/lexicon/types/app/rocksky/artist/getArtist.ts +43 -0
- package/src/lexicon/types/app/rocksky/artist/getArtistAlbums.ts +48 -0
- package/src/lexicon/types/app/rocksky/artist/getArtistListeners.ts +52 -0
- package/src/lexicon/types/app/rocksky/artist/getArtistTracks.ts +52 -0
- package/src/lexicon/types/app/rocksky/artist/getArtists.ts +52 -0
- package/src/lexicon/types/app/rocksky/artist.ts +41 -0
- package/src/lexicon/types/app/rocksky/charts/defs.ts +44 -0
- package/src/lexicon/types/app/rocksky/charts/getScrobblesChart.ts +49 -0
- package/src/lexicon/types/app/rocksky/dropbox/defs.ts +71 -0
- package/src/lexicon/types/app/rocksky/dropbox/downloadFile.ts +42 -0
- package/src/lexicon/types/app/rocksky/dropbox/getFiles.ts +43 -0
- package/src/lexicon/types/app/rocksky/dropbox/getMetadata.ts +43 -0
- package/src/lexicon/types/app/rocksky/dropbox/getTemporaryLink.ts +43 -0
- package/src/lexicon/types/app/rocksky/feed/defs.ts +182 -0
- package/src/lexicon/types/app/rocksky/feed/describeFeedGenerator.ts +48 -0
- package/src/lexicon/types/app/rocksky/feed/generator.ts +29 -0
- package/src/lexicon/types/app/rocksky/feed/getFeed.ts +47 -0
- package/src/lexicon/types/app/rocksky/feed/getFeedGenerator.ts +48 -0
- package/src/lexicon/types/app/rocksky/feed/getFeedGenerators.ts +43 -0
- package/src/lexicon/types/app/rocksky/feed/getFeedSkeleton.ts +56 -0
- package/src/lexicon/types/app/rocksky/feed/getNowPlayings.ts +43 -0
- package/src/lexicon/types/app/rocksky/feed/search.ts +43 -0
- package/src/lexicon/types/app/rocksky/googledrive/defs.ts +42 -0
- package/src/lexicon/types/app/rocksky/googledrive/downloadFile.ts +42 -0
- package/src/lexicon/types/app/rocksky/googledrive/getFile.ts +43 -0
- package/src/lexicon/types/app/rocksky/googledrive/getFiles.ts +43 -0
- package/src/lexicon/types/app/rocksky/graph/defs.ts +47 -0
- package/src/lexicon/types/app/rocksky/graph/follow.ts +28 -0
- package/src/lexicon/types/app/rocksky/graph/followAccount.ts +50 -0
- package/src/lexicon/types/app/rocksky/graph/getFollowers.ts +56 -0
- package/src/lexicon/types/app/rocksky/graph/getFollows.ts +56 -0
- package/src/lexicon/types/app/rocksky/graph/getKnownFollowers.ts +52 -0
- package/src/lexicon/types/app/rocksky/graph/unfollowAccount.ts +50 -0
- package/src/lexicon/types/app/rocksky/like/dislikeShout.ts +49 -0
- package/src/lexicon/types/app/rocksky/like/dislikeSong.ts +49 -0
- package/src/lexicon/types/app/rocksky/like/likeShout.ts +49 -0
- package/src/lexicon/types/app/rocksky/like/likeSong.ts +49 -0
- package/src/lexicon/types/app/rocksky/like.ts +27 -0
- package/src/lexicon/types/app/rocksky/player/addDirectoryToQueue.ts +40 -0
- package/src/lexicon/types/app/rocksky/player/addItemsToQueue.ts +39 -0
- package/src/lexicon/types/app/rocksky/player/defs.ts +57 -0
- package/src/lexicon/types/app/rocksky/player/getCurrentlyPlaying.ts +44 -0
- package/src/lexicon/types/app/rocksky/player/getPlaybackQueue.ts +42 -0
- package/src/lexicon/types/app/rocksky/player/next.ts +34 -0
- package/src/lexicon/types/app/rocksky/player/pause.ts +34 -0
- package/src/lexicon/types/app/rocksky/player/play.ts +34 -0
- package/src/lexicon/types/app/rocksky/player/playDirectory.ts +38 -0
- package/src/lexicon/types/app/rocksky/player/playFile.ts +35 -0
- package/src/lexicon/types/app/rocksky/player/previous.ts +34 -0
- package/src/lexicon/types/app/rocksky/player/seek.ts +36 -0
- package/src/lexicon/types/app/rocksky/playlist/createPlaylist.ts +37 -0
- package/src/lexicon/types/app/rocksky/playlist/defs.ts +86 -0
- package/src/lexicon/types/app/rocksky/playlist/getPlaylist.ts +43 -0
- package/src/lexicon/types/app/rocksky/playlist/getPlaylists.ts +50 -0
- package/src/lexicon/types/app/rocksky/playlist/insertDirectory.ts +39 -0
- package/src/lexicon/types/app/rocksky/playlist/insertFiles.ts +38 -0
- package/src/lexicon/types/app/rocksky/playlist/removePlaylist.ts +35 -0
- package/src/lexicon/types/app/rocksky/playlist/removeTrack.ts +37 -0
- package/src/lexicon/types/app/rocksky/playlist/startPlaylist.ts +39 -0
- package/src/lexicon/types/app/rocksky/playlist.ts +43 -0
- package/src/lexicon/types/app/rocksky/radio/defs.ts +63 -0
- package/src/lexicon/types/app/rocksky/radio.ts +37 -0
- package/src/lexicon/types/app/rocksky/scrobble/createScrobble.ts +91 -0
- package/src/lexicon/types/app/rocksky/scrobble/defs.ts +93 -0
- package/src/lexicon/types/app/rocksky/scrobble/getScrobble.ts +43 -0
- package/src/lexicon/types/app/rocksky/scrobble/getScrobbles.ts +54 -0
- package/src/lexicon/types/app/rocksky/scrobble.ts +75 -0
- package/src/lexicon/types/app/rocksky/shout/createShout.ts +49 -0
- package/src/lexicon/types/app/rocksky/shout/defs.ts +58 -0
- package/src/lexicon/types/app/rocksky/shout/getAlbumShouts.ts +52 -0
- package/src/lexicon/types/app/rocksky/shout/getArtistShouts.ts +52 -0
- package/src/lexicon/types/app/rocksky/shout/getProfileShouts.ts +52 -0
- package/src/lexicon/types/app/rocksky/shout/getShoutReplies.ts +52 -0
- package/src/lexicon/types/app/rocksky/shout/getTrackShouts.ts +48 -0
- package/src/lexicon/types/app/rocksky/shout/removeShout.ts +43 -0
- package/src/lexicon/types/app/rocksky/shout/replyShout.ts +51 -0
- package/src/lexicon/types/app/rocksky/shout/reportShout.ts +51 -0
- package/src/lexicon/types/app/rocksky/shout.ts +30 -0
- package/src/lexicon/types/app/rocksky/song/createSong.ts +71 -0
- package/src/lexicon/types/app/rocksky/song/defs.ts +103 -0
- package/src/lexicon/types/app/rocksky/song/getSong.ts +43 -0
- package/src/lexicon/types/app/rocksky/song/getSongs.ts +50 -0
- package/src/lexicon/types/app/rocksky/song.ts +74 -0
- package/src/lexicon/types/app/rocksky/spotify/defs.ts +35 -0
- package/src/lexicon/types/app/rocksky/spotify/getCurrentlyPlaying.ts +43 -0
- package/src/lexicon/types/app/rocksky/spotify/next.ts +32 -0
- package/src/lexicon/types/app/rocksky/spotify/pause.ts +32 -0
- package/src/lexicon/types/app/rocksky/spotify/play.ts +32 -0
- package/src/lexicon/types/app/rocksky/spotify/previous.ts +32 -0
- package/src/lexicon/types/app/rocksky/spotify/seek.ts +35 -0
- package/src/lexicon/types/app/rocksky/stats/defs.ts +33 -0
- package/src/lexicon/types/app/rocksky/stats/getStats.ts +43 -0
- package/src/lexicon/types/com/atproto/repo/strongRef.ts +26 -0
- package/src/lexicon/util.ts +13 -0
- package/src/lib/agent.ts +56 -0
- package/src/lib/cleanUpJetstreamLock.ts +66 -0
- package/src/lib/cleanUpSyncLock.ts +56 -0
- package/src/lib/didUnstorageCache.ts +72 -0
- package/src/lib/env.ts +25 -0
- package/src/lib/extractPdsFromDid.ts +33 -0
- package/src/lib/getDidAndHandle.ts +39 -0
- package/src/lib/idResolver.ts +52 -0
- package/src/lib/lastfm.ts +26 -0
- package/src/lib/matchTrack.ts +47 -0
- package/src/logger.ts +18 -0
- package/src/mcp/index.ts +269 -0
- package/src/mcp/tools/albums.ts +13 -0
- package/src/mcp/tools/artists.ts +17 -0
- package/src/mcp/tools/create.ts +27 -0
- package/src/mcp/tools/myscrobbles.ts +42 -0
- package/src/mcp/tools/nowplaying.ts +53 -0
- package/src/mcp/tools/scrobbles.ts +39 -0
- package/src/mcp/tools/search.ts +88 -0
- package/src/mcp/tools/stats.ts +40 -0
- package/src/mcp/tools/tracks.ts +15 -0
- package/src/mcp/tools/whoami.ts +27 -0
- package/src/schema/album-tracks.ts +30 -0
- package/src/schema/albums.ts +29 -0
- package/src/schema/artist-albums.ts +29 -0
- package/src/schema/artist-genres.ts +17 -0
- package/src/schema/artist-tracks.ts +29 -0
- package/src/schema/artists.ts +30 -0
- package/src/schema/auth-session.ts +18 -0
- package/src/schema/genres.ts +18 -0
- package/src/schema/index.ts +33 -0
- package/src/schema/loved-tracks.ts +27 -0
- package/src/schema/scrobbles.ts +30 -0
- package/src/schema/tracks.ts +39 -0
- package/src/schema/user-albums.ts +31 -0
- package/src/schema/user-artists.ts +32 -0
- package/src/schema/user-tracks.ts +31 -0
- package/src/schema/users.ts +21 -0
- package/src/scrobble.ts +410 -0
- package/src/sqliteKv.ts +173 -0
- package/src/types.ts +308 -0
- package/tsconfig.json +26 -29
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { type InferInsertModel, type InferSelectModel, sql } from "drizzle-orm";
|
|
2
|
+
import { integer, sqliteTable, text, unique } from "drizzle-orm/sqlite-core";
|
|
3
|
+
import albums from "./albums";
|
|
4
|
+
import artists from "./artists";
|
|
5
|
+
|
|
6
|
+
const artistAlbums = sqliteTable(
|
|
7
|
+
"artist_albums",
|
|
8
|
+
{
|
|
9
|
+
id: text("id").primaryKey().notNull(),
|
|
10
|
+
artistId: text("artist_id")
|
|
11
|
+
.notNull()
|
|
12
|
+
.references(() => artists.id),
|
|
13
|
+
albumId: text("album_id")
|
|
14
|
+
.notNull()
|
|
15
|
+
.references(() => albums.id),
|
|
16
|
+
createdAt: integer("created_at")
|
|
17
|
+
.notNull()
|
|
18
|
+
.default(sql`(unixepoch())`),
|
|
19
|
+
updatedAt: integer("updated_at")
|
|
20
|
+
.notNull()
|
|
21
|
+
.default(sql`(unixepoch())`),
|
|
22
|
+
},
|
|
23
|
+
(t) => [unique("artist_albums_unique_index").on(t.artistId, t.albumId)],
|
|
24
|
+
);
|
|
25
|
+
|
|
26
|
+
export type SelectArtistAlbum = InferSelectModel<typeof artistAlbums>;
|
|
27
|
+
export type InsertArtistAlbum = InferInsertModel<typeof artistAlbums>;
|
|
28
|
+
|
|
29
|
+
export default artistAlbums;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { type InferInsertModel, type InferSelectModel } from "drizzle-orm";
|
|
2
|
+
import { sqliteTable, text, unique } from "drizzle-orm/sqlite-core";
|
|
3
|
+
|
|
4
|
+
const artistGenres = sqliteTable(
|
|
5
|
+
"artist_genres ",
|
|
6
|
+
{
|
|
7
|
+
id: text("id").primaryKey().notNull(),
|
|
8
|
+
artistId: text("artist_id").notNull(),
|
|
9
|
+
genreId: text("genre_id").notNull(),
|
|
10
|
+
},
|
|
11
|
+
(t) => [unique("artist_genre_unique_index").on(t.artistId, t.genreId)],
|
|
12
|
+
);
|
|
13
|
+
|
|
14
|
+
export type SelectArtistGenre = InferSelectModel<typeof artistGenres>;
|
|
15
|
+
export type InsertArtistGenre = InferInsertModel<typeof artistGenres>;
|
|
16
|
+
|
|
17
|
+
export default artistGenres;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { type InferInsertModel, type InferSelectModel, sql } from "drizzle-orm";
|
|
2
|
+
import { integer, sqliteTable, text, unique } from "drizzle-orm/sqlite-core";
|
|
3
|
+
import artists from "./artists";
|
|
4
|
+
import tracks from "./tracks";
|
|
5
|
+
|
|
6
|
+
const artistTracks = sqliteTable(
|
|
7
|
+
"artist_tracks",
|
|
8
|
+
{
|
|
9
|
+
id: text("id").primaryKey().notNull(),
|
|
10
|
+
artistId: text("artist_id")
|
|
11
|
+
.notNull()
|
|
12
|
+
.references(() => artists.id),
|
|
13
|
+
trackId: text("track_id")
|
|
14
|
+
.notNull()
|
|
15
|
+
.references(() => tracks.id),
|
|
16
|
+
createdAt: integer("created_at", { mode: "timestamp" })
|
|
17
|
+
.notNull()
|
|
18
|
+
.default(sql`(unixepoch())`),
|
|
19
|
+
updatedAt: integer("updated_at", { mode: "timestamp" })
|
|
20
|
+
.notNull()
|
|
21
|
+
.default(sql`(unixepoch())`),
|
|
22
|
+
},
|
|
23
|
+
(t) => [unique("artist_tracks_unique_index").on(t.artistId, t.trackId)],
|
|
24
|
+
);
|
|
25
|
+
|
|
26
|
+
export type SelectArtistTrack = InferSelectModel<typeof artistTracks>;
|
|
27
|
+
export type InsertArtistTrack = InferInsertModel<typeof artistTracks>;
|
|
28
|
+
|
|
29
|
+
export default artistTracks;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { type InferInsertModel, type InferSelectModel, sql } from "drizzle-orm";
|
|
2
|
+
import { integer, sqliteTable, text } from "drizzle-orm/sqlite-core";
|
|
3
|
+
|
|
4
|
+
const artists = sqliteTable("artists", {
|
|
5
|
+
id: text("id").primaryKey().notNull(),
|
|
6
|
+
name: text("name").notNull(),
|
|
7
|
+
biography: text("biography"),
|
|
8
|
+
born: integer("born", { mode: "timestamp" }),
|
|
9
|
+
bornIn: text("born_in"),
|
|
10
|
+
died: integer("died", { mode: "timestamp" }),
|
|
11
|
+
picture: text("picture"),
|
|
12
|
+
uri: text("uri").unique(),
|
|
13
|
+
cid: text("cid").unique().notNull(),
|
|
14
|
+
appleMusicLink: text("apple_music_link"),
|
|
15
|
+
spotifyLink: text("spotify_link"),
|
|
16
|
+
tidalLink: text("tidal_link"),
|
|
17
|
+
youtubeLink: text("youtube_link"),
|
|
18
|
+
genres: text("genres"),
|
|
19
|
+
createdAt: integer("created_at", { mode: "timestamp" })
|
|
20
|
+
.notNull()
|
|
21
|
+
.default(sql`(unixepoch())`),
|
|
22
|
+
updatedAt: integer("updated_at", { mode: "timestamp" })
|
|
23
|
+
.notNull()
|
|
24
|
+
.default(sql`(unixepoch())`),
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
export type SelectArtist = InferSelectModel<typeof artists>;
|
|
28
|
+
export type InsertArtist = InferInsertModel<typeof artists>;
|
|
29
|
+
|
|
30
|
+
export default artists;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { type InferInsertModel, type InferSelectModel, sql } from "drizzle-orm";
|
|
2
|
+
import { integer, sqliteTable, text } from "drizzle-orm/sqlite-core";
|
|
3
|
+
|
|
4
|
+
const authSessions = sqliteTable("auth_sessions", {
|
|
5
|
+
key: text("key").primaryKey().notNull(),
|
|
6
|
+
session: text("session").notNull(),
|
|
7
|
+
createdAt: integer("created_at", { mode: "timestamp" })
|
|
8
|
+
.notNull()
|
|
9
|
+
.default(sql`(unixepoch())`),
|
|
10
|
+
updatedAt: integer("updated_at", { mode: "timestamp" })
|
|
11
|
+
.notNull()
|
|
12
|
+
.default(sql`(unixepoch())`),
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
export type SelectAuthSession = InferSelectModel<typeof authSessions>;
|
|
16
|
+
export type InsertAuthSession = InferInsertModel<typeof authSessions>;
|
|
17
|
+
|
|
18
|
+
export default authSessions;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { type InferInsertModel, type InferSelectModel, sql } from "drizzle-orm";
|
|
2
|
+
import { integer, sqliteTable, text } from "drizzle-orm/sqlite-core";
|
|
3
|
+
|
|
4
|
+
const genres = sqliteTable("genres", {
|
|
5
|
+
id: text("id").primaryKey().notNull(),
|
|
6
|
+
name: text("name").unique().notNull(),
|
|
7
|
+
createdAt: integer("created_at", { mode: "timestamp" })
|
|
8
|
+
.notNull()
|
|
9
|
+
.default(sql`(unixepoch())`),
|
|
10
|
+
updatedAt: integer("updated_at", { mode: "timestamp" })
|
|
11
|
+
.notNull()
|
|
12
|
+
.default(sql`(unixepoch())`),
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
export type SelectGenre = InferSelectModel<typeof genres>;
|
|
16
|
+
export type InsertGenre = InferInsertModel<typeof genres>;
|
|
17
|
+
|
|
18
|
+
export default genres;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import albumTracks from "./album-tracks";
|
|
2
|
+
import albums from "./albums";
|
|
3
|
+
import artistAlbums from "./artist-albums";
|
|
4
|
+
import artistGenres from "./artist-genres";
|
|
5
|
+
import artistTracks from "./artist-tracks";
|
|
6
|
+
import artists from "./artists";
|
|
7
|
+
import authSessions from "./auth-session";
|
|
8
|
+
import genres from "./genres";
|
|
9
|
+
import lovedTracks from "./loved-tracks";
|
|
10
|
+
import scrobbles from "./scrobbles";
|
|
11
|
+
import tracks from "./tracks";
|
|
12
|
+
import userAlbums from "./user-albums";
|
|
13
|
+
import userArtists from "./user-artists";
|
|
14
|
+
import userTracks from "./user-tracks";
|
|
15
|
+
import users from "./users";
|
|
16
|
+
|
|
17
|
+
export default {
|
|
18
|
+
users,
|
|
19
|
+
tracks,
|
|
20
|
+
artists,
|
|
21
|
+
albums,
|
|
22
|
+
albumTracks,
|
|
23
|
+
authSessions,
|
|
24
|
+
artistAlbums,
|
|
25
|
+
artistTracks,
|
|
26
|
+
lovedTracks,
|
|
27
|
+
scrobbles,
|
|
28
|
+
userAlbums,
|
|
29
|
+
userArtists,
|
|
30
|
+
userTracks,
|
|
31
|
+
genres,
|
|
32
|
+
artistGenres,
|
|
33
|
+
};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { type InferInsertModel, type InferSelectModel, sql } from "drizzle-orm";
|
|
2
|
+
import { sqliteTable, integer, text, unique } from "drizzle-orm/sqlite-core";
|
|
3
|
+
import tracks from "./tracks";
|
|
4
|
+
import users from "./users";
|
|
5
|
+
|
|
6
|
+
const lovedTracks = sqliteTable(
|
|
7
|
+
"loved_tracks",
|
|
8
|
+
{
|
|
9
|
+
id: text("id").primaryKey().notNull(),
|
|
10
|
+
userId: text("user_id")
|
|
11
|
+
.notNull()
|
|
12
|
+
.references(() => users.id),
|
|
13
|
+
trackId: text("track_id")
|
|
14
|
+
.notNull()
|
|
15
|
+
.references(() => tracks.id),
|
|
16
|
+
uri: text("uri").unique(),
|
|
17
|
+
createdAt: integer("created_at")
|
|
18
|
+
.notNull()
|
|
19
|
+
.default(sql`(unixepoch())`),
|
|
20
|
+
},
|
|
21
|
+
(t) => [unique("loved_tracks_unique_index").on(t.userId, t.trackId)],
|
|
22
|
+
);
|
|
23
|
+
|
|
24
|
+
export type SelectLovedTrack = InferSelectModel<typeof lovedTracks>;
|
|
25
|
+
export type InsertLovedTrack = InferInsertModel<typeof lovedTracks>;
|
|
26
|
+
|
|
27
|
+
export default lovedTracks;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { type InferInsertModel, type InferSelectModel, sql } from "drizzle-orm";
|
|
2
|
+
import { integer, sqliteTable, text } from "drizzle-orm/sqlite-core";
|
|
3
|
+
import albums from "./albums";
|
|
4
|
+
import artists from "./artists";
|
|
5
|
+
import tracks from "./tracks";
|
|
6
|
+
import users from "./users";
|
|
7
|
+
|
|
8
|
+
const scrobbles = sqliteTable("scrobbles", {
|
|
9
|
+
id: text("xata_id").primaryKey().notNull(),
|
|
10
|
+
userId: text("user_id").references(() => users.id),
|
|
11
|
+
trackId: text("track_id").references(() => tracks.id),
|
|
12
|
+
albumId: text("album_id").references(() => albums.id),
|
|
13
|
+
artistId: text("artist_id").references(() => artists.id),
|
|
14
|
+
uri: text("uri").unique(),
|
|
15
|
+
cid: text("cid").unique(),
|
|
16
|
+
createdAt: integer("created_at", { mode: "timestamp" })
|
|
17
|
+
.notNull()
|
|
18
|
+
.default(sql`(unixepoch())`),
|
|
19
|
+
updatedAt: integer("updated_at", { mode: "timestamp" })
|
|
20
|
+
.notNull()
|
|
21
|
+
.default(sql`(unixepoch())`),
|
|
22
|
+
timestamp: integer("timestamp", { mode: "timestamp" })
|
|
23
|
+
.notNull()
|
|
24
|
+
.default(sql`(unixepoch())`),
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
export type SelectScrobble = InferSelectModel<typeof scrobbles>;
|
|
28
|
+
export type InsertScrobble = InferInsertModel<typeof scrobbles>;
|
|
29
|
+
|
|
30
|
+
export default scrobbles;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { type InferInsertModel, type InferSelectModel, sql } from "drizzle-orm";
|
|
2
|
+
import { integer, sqliteTable, text } from "drizzle-orm/sqlite-core";
|
|
3
|
+
|
|
4
|
+
const tracks = sqliteTable("tracks", {
|
|
5
|
+
id: text("id").primaryKey().notNull(),
|
|
6
|
+
title: text("title").notNull(),
|
|
7
|
+
artist: text("artist").notNull(),
|
|
8
|
+
albumArtist: text("album_artist").notNull(),
|
|
9
|
+
albumArt: text("album_art"),
|
|
10
|
+
album: text("album").notNull(),
|
|
11
|
+
trackNumber: integer("track_number"),
|
|
12
|
+
duration: integer("duration").notNull(),
|
|
13
|
+
mbId: text("mb_id").unique(),
|
|
14
|
+
youtubeLink: text("youtube_link").unique(),
|
|
15
|
+
spotifyLink: text("spotify_link").unique(),
|
|
16
|
+
appleMusicLink: text("apple_music_link").unique(),
|
|
17
|
+
tidalLink: text("tidal_link").unique(),
|
|
18
|
+
discNumber: integer("disc_number"),
|
|
19
|
+
lyrics: text("lyrics"),
|
|
20
|
+
composer: text("composer"),
|
|
21
|
+
genre: text("genre"),
|
|
22
|
+
label: text("label"),
|
|
23
|
+
copyrightMessage: text("copyright_message"),
|
|
24
|
+
uri: text("uri").unique(),
|
|
25
|
+
cid: text("cid").unique().notNull(),
|
|
26
|
+
albumUri: text("album_uri"),
|
|
27
|
+
artistUri: text("artist_uri"),
|
|
28
|
+
createdAt: integer("created_at", { mode: "timestamp" })
|
|
29
|
+
.notNull()
|
|
30
|
+
.default(sql`(unixepoch())`),
|
|
31
|
+
updatedAt: integer("updated_at", { mode: "timestamp" })
|
|
32
|
+
.notNull()
|
|
33
|
+
.default(sql`(unixepoch())`),
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
export type SelectTrack = InferSelectModel<typeof tracks>;
|
|
37
|
+
export type InsertTrack = InferInsertModel<typeof tracks>;
|
|
38
|
+
|
|
39
|
+
export default tracks;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { type InferInsertModel, type InferSelectModel, sql } from "drizzle-orm";
|
|
2
|
+
import { integer, sqliteTable, text, unique } from "drizzle-orm/sqlite-core";
|
|
3
|
+
import albums from "./albums";
|
|
4
|
+
import users from "./users";
|
|
5
|
+
|
|
6
|
+
const userAlbums = sqliteTable(
|
|
7
|
+
"user_albums",
|
|
8
|
+
{
|
|
9
|
+
id: text("id").primaryKey().notNull(),
|
|
10
|
+
userId: text("user_id")
|
|
11
|
+
.notNull()
|
|
12
|
+
.references(() => users.id),
|
|
13
|
+
albumId: text("album_id")
|
|
14
|
+
.notNull()
|
|
15
|
+
.references(() => albums.id),
|
|
16
|
+
createdAt: integer("created_at", { mode: "timestamp" })
|
|
17
|
+
.notNull()
|
|
18
|
+
.default(sql`(unixepoch())`),
|
|
19
|
+
updatedAt: integer("updated_at", { mode: "timestamp" })
|
|
20
|
+
.notNull()
|
|
21
|
+
.default(sql`(unixepoch())`),
|
|
22
|
+
scrobbles: integer("scrobbles"),
|
|
23
|
+
uri: text("uri").unique().notNull(),
|
|
24
|
+
},
|
|
25
|
+
(t) => [unique("user_albums_unique_index").on(t.userId, t.albumId)],
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
export type SelectUserAlbum = InferSelectModel<typeof userAlbums>;
|
|
29
|
+
export type InsertUserAlbum = InferInsertModel<typeof userAlbums>;
|
|
30
|
+
|
|
31
|
+
export default userAlbums;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { type InferInsertModel, type InferSelectModel, sql } from "drizzle-orm";
|
|
2
|
+
import { integer, sqliteTable, text, unique } from "drizzle-orm/sqlite-core";
|
|
3
|
+
import artists from "./artists";
|
|
4
|
+
import users from "./users";
|
|
5
|
+
|
|
6
|
+
const userArtists = sqliteTable(
|
|
7
|
+
"user_artists",
|
|
8
|
+
{
|
|
9
|
+
id: text("id").primaryKey().notNull(),
|
|
10
|
+
userId: text("user_id")
|
|
11
|
+
.notNull()
|
|
12
|
+
.references(() => users.id),
|
|
13
|
+
artistId: text("artist_id")
|
|
14
|
+
.notNull()
|
|
15
|
+
.references(() => artists.id),
|
|
16
|
+
createdAt: integer("created_at", { mode: "timestamp" })
|
|
17
|
+
.notNull()
|
|
18
|
+
.default(sql`(unixepoch())`),
|
|
19
|
+
updatedAt: integer("updated_at", { mode: "timestamp" })
|
|
20
|
+
.notNull()
|
|
21
|
+
.default(sql`(unixepoch())`),
|
|
22
|
+
scrobbles: integer("scrobbles"),
|
|
23
|
+
uri: text("uri").unique().notNull(),
|
|
24
|
+
},
|
|
25
|
+
|
|
26
|
+
(t) => [unique("user_artists_unique_index").on(t.userId, t.artistId)],
|
|
27
|
+
);
|
|
28
|
+
|
|
29
|
+
export type SelectUserArtist = InferSelectModel<typeof userArtists>;
|
|
30
|
+
export type InsertUserArtist = InferInsertModel<typeof userArtists>;
|
|
31
|
+
|
|
32
|
+
export default userArtists;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { type InferInsertModel, type InferSelectModel, sql } from "drizzle-orm";
|
|
2
|
+
import { integer, sqliteTable, text, unique } from "drizzle-orm/sqlite-core";
|
|
3
|
+
import tracks from "./tracks";
|
|
4
|
+
import users from "./users";
|
|
5
|
+
|
|
6
|
+
const userTracks = sqliteTable(
|
|
7
|
+
"user_tracks",
|
|
8
|
+
{
|
|
9
|
+
id: text("id").primaryKey().notNull(),
|
|
10
|
+
userId: text("user_id")
|
|
11
|
+
.notNull()
|
|
12
|
+
.references(() => users.id),
|
|
13
|
+
trackId: text("track_id")
|
|
14
|
+
.notNull()
|
|
15
|
+
.references(() => tracks.id),
|
|
16
|
+
createdAt: integer("created_at", { mode: "timestamp" })
|
|
17
|
+
.notNull()
|
|
18
|
+
.default(sql`(unixepoch())`),
|
|
19
|
+
updatedAt: integer("updated_at", { mode: "timestamp" })
|
|
20
|
+
.notNull()
|
|
21
|
+
.default(sql`(unixepoch())`),
|
|
22
|
+
scrobbles: integer("scrobbles"),
|
|
23
|
+
uri: text("uri").unique().notNull(),
|
|
24
|
+
},
|
|
25
|
+
(t) => [unique("user_tracks_unique_index").on(t.userId, t.trackId)],
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
export type SelectUser = InferSelectModel<typeof userTracks>;
|
|
29
|
+
export type InsertUserTrack = InferInsertModel<typeof userTracks>;
|
|
30
|
+
|
|
31
|
+
export default userTracks;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { type InferSelectModel, sql } from "drizzle-orm";
|
|
2
|
+
import { integer, sqliteTable, text } from "drizzle-orm/sqlite-core";
|
|
3
|
+
|
|
4
|
+
const users = sqliteTable("users", {
|
|
5
|
+
id: text("id").primaryKey().notNull(),
|
|
6
|
+
did: text("did").unique().notNull(),
|
|
7
|
+
displayName: text("display_name"),
|
|
8
|
+
handle: text("handle").unique().notNull(),
|
|
9
|
+
avatar: text("avatar").notNull(),
|
|
10
|
+
createdAt: integer("created_at", { mode: "timestamp" })
|
|
11
|
+
.notNull()
|
|
12
|
+
.default(sql`(unixepoch())`),
|
|
13
|
+
updatedAt: integer("updated_at", { mode: "timestamp" })
|
|
14
|
+
.notNull()
|
|
15
|
+
.default(sql`(unixepoch())`),
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
export type SelectUser = InferSelectModel<typeof users>;
|
|
19
|
+
export type InsertUser = InferSelectModel<typeof users>;
|
|
20
|
+
|
|
21
|
+
export default users;
|