@rocksky/sdk 0.6.0 → 0.7.1
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/dist/agent.d.ts +19 -2
- package/dist/agent.d.ts.map +1 -1
- package/dist/agent.test.d.ts +2 -0
- package/dist/agent.test.d.ts.map +1 -0
- package/dist/client.d.ts +9 -1
- package/dist/client.d.ts.map +1 -1
- package/dist/generated/types.d.ts +433 -76
- package/dist/generated/types.d.ts.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +193 -0
- package/dist/library.d.ts +165 -0
- package/dist/library.d.ts.map +1 -0
- package/package.json +1 -1
- package/src/agent.test.ts +166 -0
- package/src/agent.ts +47 -2
- package/src/client.ts +18 -1
- package/src/generated/types.ts +578 -85
- package/src/index.ts +1 -0
- package/src/library.ts +241 -0
package/src/index.ts
CHANGED
package/src/library.ts
ADDED
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
import type { Client } from "@atcute/client";
|
|
2
|
+
|
|
3
|
+
import { RockskyError } from "./errors.js";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Authenticated client for the `app.rocksky.library.*` API — the Subsonic /
|
|
7
|
+
* navidrome-compatible surface over a user's uploaded music.
|
|
8
|
+
*
|
|
9
|
+
* Every method requires auth, so this is only reachable via
|
|
10
|
+
* {@link RockskyClient.library}, which throws unless the client was built with
|
|
11
|
+
* a token. Outputs are the AppView's raw JSON payloads (the library lexicons
|
|
12
|
+
* are intentionally loose).
|
|
13
|
+
*/
|
|
14
|
+
export class RockskyLibrary {
|
|
15
|
+
constructor(private readonly rpc: Client) {}
|
|
16
|
+
|
|
17
|
+
private async query<T>(nsid: string, params: Record<string, unknown>): Promise<T> {
|
|
18
|
+
const clean: Record<string, unknown> = {};
|
|
19
|
+
for (const [k, v] of Object.entries(params)) {
|
|
20
|
+
if (v !== undefined && v !== "") clean[k] = v;
|
|
21
|
+
}
|
|
22
|
+
const res = await this.rpc.get(nsid as never, { params: clean } as never);
|
|
23
|
+
if (!res.ok) throw new RockskyError(res.data);
|
|
24
|
+
return res.data as T;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
private async procedure<T>(nsid: string, input: Record<string, unknown>): Promise<T> {
|
|
28
|
+
const clean: Record<string, unknown> = {};
|
|
29
|
+
for (const [k, v] of Object.entries(input)) {
|
|
30
|
+
if (v !== undefined && v !== "") clean[k] = v;
|
|
31
|
+
}
|
|
32
|
+
const res = await this.rpc.post(nsid as never, { input: clean } as never);
|
|
33
|
+
if (!res.ok) throw new RockskyError(res.data);
|
|
34
|
+
return res.data as T;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/** `app.rocksky.library.ping` — requires auth. */
|
|
38
|
+
ping(): Promise<unknown> {
|
|
39
|
+
return this.query<unknown>("app.rocksky.library.ping", {});
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/** `app.rocksky.library.getLicense` — requires auth. */
|
|
43
|
+
getLicense(): Promise<unknown> {
|
|
44
|
+
return this.query<unknown>("app.rocksky.library.getLicense", {});
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/** `app.rocksky.library.getMusicFolders` — requires auth. */
|
|
48
|
+
getMusicFolders(): Promise<unknown> {
|
|
49
|
+
return this.query<unknown>("app.rocksky.library.getMusicFolders", {});
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/** `app.rocksky.library.getScanStatus` — requires auth. */
|
|
53
|
+
getScanStatus(): Promise<unknown> {
|
|
54
|
+
return this.query<unknown>("app.rocksky.library.getScanStatus", {});
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/** `app.rocksky.library.startScan` — requires auth. */
|
|
58
|
+
startScan(): Promise<unknown> {
|
|
59
|
+
return this.query<unknown>("app.rocksky.library.startScan", {});
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/** `app.rocksky.library.getUser` — requires auth. */
|
|
63
|
+
getUser(): Promise<unknown> {
|
|
64
|
+
return this.query<unknown>("app.rocksky.library.getUser", {});
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/** `app.rocksky.library.getArtists` — requires auth. */
|
|
68
|
+
getArtists(): Promise<unknown> {
|
|
69
|
+
return this.query<unknown>("app.rocksky.library.getArtists", {});
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/** `app.rocksky.library.getIndexes` — requires auth. */
|
|
73
|
+
getIndexes(): Promise<unknown> {
|
|
74
|
+
return this.query<unknown>("app.rocksky.library.getIndexes", {});
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/** `app.rocksky.library.getArtist` — requires auth. */
|
|
78
|
+
getArtist(id: string): Promise<unknown> {
|
|
79
|
+
return this.query<unknown>("app.rocksky.library.getArtist", { id });
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/** `app.rocksky.library.getArtistInfo` — requires auth. */
|
|
83
|
+
getArtistInfo(id: string): Promise<unknown> {
|
|
84
|
+
return this.query<unknown>("app.rocksky.library.getArtistInfo", { id });
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/** `app.rocksky.library.getAlbum` — requires auth. */
|
|
88
|
+
getAlbum(id: string): Promise<unknown> {
|
|
89
|
+
return this.query<unknown>("app.rocksky.library.getAlbum", { id });
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/** `app.rocksky.library.getAlbumList` — requires auth. */
|
|
93
|
+
getAlbumList(type: string, opts: { size?: number; offset?: number; fromYear?: number; toYear?: number; genre?: string } = {}): Promise<unknown> {
|
|
94
|
+
return this.query<unknown>("app.rocksky.library.getAlbumList", { type, ...opts });
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/** `app.rocksky.library.getAlbumInfo` — requires auth. */
|
|
98
|
+
getAlbumInfo(id: string): Promise<unknown> {
|
|
99
|
+
return this.query<unknown>("app.rocksky.library.getAlbumInfo", { id });
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/** `app.rocksky.library.getSong` — requires auth. */
|
|
103
|
+
getSong(id: string): Promise<unknown> {
|
|
104
|
+
return this.query<unknown>("app.rocksky.library.getSong", { id });
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/** `app.rocksky.library.getRandomSongs` — requires auth. */
|
|
108
|
+
getRandomSongs(opts: { size?: number; genre?: string; fromYear?: number; toYear?: number } = {}): Promise<unknown> {
|
|
109
|
+
return this.query<unknown>("app.rocksky.library.getRandomSongs", { ...opts });
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/** `app.rocksky.library.getSongsByGenre` — requires auth. */
|
|
113
|
+
getSongsByGenre(genre: string, opts: { count?: number; offset?: number } = {}): Promise<unknown> {
|
|
114
|
+
return this.query<unknown>("app.rocksky.library.getSongsByGenre", { genre, ...opts });
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/** `app.rocksky.library.getSimilarSongs` — requires auth. */
|
|
118
|
+
getSimilarSongs(id: string, opts: { count?: number } = {}): Promise<unknown> {
|
|
119
|
+
return this.query<unknown>("app.rocksky.library.getSimilarSongs", { id, ...opts });
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/** `app.rocksky.library.getTopSongs` — requires auth. */
|
|
123
|
+
getTopSongs(artist: string, opts: { count?: number } = {}): Promise<unknown> {
|
|
124
|
+
return this.query<unknown>("app.rocksky.library.getTopSongs", { artist, ...opts });
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/** `app.rocksky.library.getLyrics` — requires auth. */
|
|
128
|
+
getLyrics(opts: { artist?: string; title?: string } = {}): Promise<unknown> {
|
|
129
|
+
return this.query<unknown>("app.rocksky.library.getLyrics", { ...opts });
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/** `app.rocksky.library.getMusicDirectory` — requires auth. */
|
|
133
|
+
getMusicDirectory(id: string): Promise<unknown> {
|
|
134
|
+
return this.query<unknown>("app.rocksky.library.getMusicDirectory", { id });
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/** `app.rocksky.library.getGenres` — requires auth. */
|
|
138
|
+
getGenres(): Promise<unknown> {
|
|
139
|
+
return this.query<unknown>("app.rocksky.library.getGenres", {});
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/** `app.rocksky.library.search` — requires auth. */
|
|
143
|
+
search(query: string, opts: { artistCount?: number; artistOffset?: number; albumCount?: number; albumOffset?: number; songCount?: number; songOffset?: number } = {}): Promise<unknown> {
|
|
144
|
+
return this.query<unknown>("app.rocksky.library.search", { query, ...opts });
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/** `app.rocksky.library.getStarred` — requires auth. */
|
|
148
|
+
getStarred(): Promise<unknown> {
|
|
149
|
+
return this.query<unknown>("app.rocksky.library.getStarred", {});
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/** `app.rocksky.library.star` — requires auth. */
|
|
153
|
+
star(id: string, opts: { albumId?: string; artistId?: string } = {}): Promise<unknown> {
|
|
154
|
+
return this.procedure<unknown>("app.rocksky.library.star", { id, ...opts });
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/** `app.rocksky.library.unstar` — requires auth. */
|
|
158
|
+
unstar(id: string, opts: { albumId?: string; artistId?: string } = {}): Promise<unknown> {
|
|
159
|
+
return this.procedure<unknown>("app.rocksky.library.unstar", { id, ...opts });
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/** `app.rocksky.library.getPlaylists` — requires auth. */
|
|
163
|
+
getPlaylists(): Promise<unknown> {
|
|
164
|
+
return this.query<unknown>("app.rocksky.library.getPlaylists", {});
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/** `app.rocksky.library.getPlaylist` — requires auth. */
|
|
168
|
+
getPlaylist(id: string): Promise<unknown> {
|
|
169
|
+
return this.query<unknown>("app.rocksky.library.getPlaylist", { id });
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/** `app.rocksky.library.createPlaylist` — requires auth. */
|
|
173
|
+
createPlaylist(name: string): Promise<unknown> {
|
|
174
|
+
return this.procedure<unknown>("app.rocksky.library.createPlaylist", { name });
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/** `app.rocksky.library.updatePlaylist` — requires auth. */
|
|
178
|
+
updatePlaylist(playlistId: string, opts: { name?: string; comment?: string; songIdToAdd?: string; songIndexToRemove?: number } = {}): Promise<unknown> {
|
|
179
|
+
return this.procedure<unknown>("app.rocksky.library.updatePlaylist", { playlistId, ...opts });
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/** `app.rocksky.library.deletePlaylist` — requires auth. */
|
|
183
|
+
deletePlaylist(id: string): Promise<{ status: string; deleted: number }> {
|
|
184
|
+
return this.procedure<{ status: string; deleted: number }>("app.rocksky.library.deletePlaylist", { id });
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/** `app.rocksky.library.deleteSong` — requires auth. */
|
|
188
|
+
deleteSong(id: string): Promise<{ status: string; deleted: number }> {
|
|
189
|
+
return this.procedure<{ status: string; deleted: number }>("app.rocksky.library.deleteSong", { id });
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/** `app.rocksky.library.deleteAlbum` — requires auth. */
|
|
193
|
+
deleteAlbum(id: string): Promise<{ status: string; deleted: number }> {
|
|
194
|
+
return this.procedure<{ status: string; deleted: number }>("app.rocksky.library.deleteAlbum", { id });
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/** `app.rocksky.library.scrobble` — requires auth. */
|
|
198
|
+
scrobble(id: string, opts: { time?: number; submission?: boolean } = {}): Promise<unknown> {
|
|
199
|
+
return this.procedure<unknown>("app.rocksky.library.scrobble", { id, ...opts });
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/** `app.rocksky.library.updateNowPlaying` — requires auth. */
|
|
203
|
+
updateNowPlaying(id: string): Promise<unknown> {
|
|
204
|
+
return this.procedure<unknown>("app.rocksky.library.updateNowPlaying", { id });
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
/** `app.rocksky.library.getNowPlaying` — requires auth. */
|
|
208
|
+
getNowPlaying(): Promise<unknown> {
|
|
209
|
+
return this.query<unknown>("app.rocksky.library.getNowPlaying", {});
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/** `app.rocksky.library.getPlayQueue` — requires auth. */
|
|
213
|
+
getPlayQueue(): Promise<unknown> {
|
|
214
|
+
return this.query<unknown>("app.rocksky.library.getPlayQueue", {});
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
/** `app.rocksky.library.savePlayQueue` — requires auth. */
|
|
218
|
+
savePlayQueue(opts: { id?: string; current?: string; position?: number } = {}): Promise<unknown> {
|
|
219
|
+
return this.procedure<unknown>("app.rocksky.library.savePlayQueue", { ...opts });
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/** `app.rocksky.library.getStreamUrl` — requires auth. */
|
|
223
|
+
getStreamUrl(id: string, opts: { maxBitRate?: number; format?: string } = {}): Promise<{ url: string }> {
|
|
224
|
+
return this.query<{ url: string }>("app.rocksky.library.getStreamUrl", { id, ...opts });
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/** `app.rocksky.library.getDownloadUrl` — requires auth. */
|
|
228
|
+
getDownloadUrl(id: string): Promise<{ url: string }> {
|
|
229
|
+
return this.query<{ url: string }>("app.rocksky.library.getDownloadUrl", { id });
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
/** `app.rocksky.library.getCoverArtUrl` — requires auth. */
|
|
233
|
+
getCoverArtUrl(id: string, opts: { size?: number } = {}): Promise<{ url: string }> {
|
|
234
|
+
return this.query<{ url: string }>("app.rocksky.library.getCoverArtUrl", { id, ...opts });
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
/** `app.rocksky.library.getInternetRadioStations` — requires auth. */
|
|
238
|
+
getInternetRadioStations(): Promise<unknown> {
|
|
239
|
+
return this.query<unknown>("app.rocksky.library.getInternetRadioStations", {});
|
|
240
|
+
}
|
|
241
|
+
}
|