@rocksky/sdk 0.5.0 → 0.7.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 +7 -2
- package/dist/agent.d.ts +14 -1
- package/dist/agent.d.ts.map +1 -1
- 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 +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +171 -1
- package/dist/library.d.ts +165 -0
- package/dist/library.d.ts.map +1 -0
- package/package.json +1 -1
- package/src/agent.ts +17 -8
- package/src/client.ts +18 -1
- package/src/generated/types.ts +578 -85
- package/src/index.ts +9 -1
- package/src/library.ts +241 -0
package/src/agent.ts
CHANGED
|
@@ -52,6 +52,19 @@ function nowISO(): string {
|
|
|
52
52
|
// Write inputs: `createdAt` is optional (the SDK defaults it to now).
|
|
53
53
|
/** Input for {@link Agent.scrobble} (createdAt defaults to now). */
|
|
54
54
|
export type ScrobbleInput = Omit<ScrobbleRecord, "createdAt"> & { createdAt?: string };
|
|
55
|
+
/** Input for {@link Agent.scrobbleMatch} — `title`/`artist` required, rest optional. */
|
|
56
|
+
export interface ScrobbleMatchInput {
|
|
57
|
+
title: string;
|
|
58
|
+
artist: string;
|
|
59
|
+
/** Overrides the matched album. */
|
|
60
|
+
album?: string;
|
|
61
|
+
/** MusicBrainz recording id — anchors the match. */
|
|
62
|
+
mbId?: string;
|
|
63
|
+
/** ISRC — anchors the match. */
|
|
64
|
+
isrc?: string;
|
|
65
|
+
/** Scrobbled-at Unix seconds; omitted = now. */
|
|
66
|
+
timestamp?: number;
|
|
67
|
+
}
|
|
55
68
|
/** Input for {@link Agent.createSong}. */
|
|
56
69
|
export type SongInput = Omit<SongRecord, "createdAt"> & { createdAt?: string };
|
|
57
70
|
/** Input for {@link Agent.createAlbum} (`artist` is the album artist). */
|
|
@@ -157,14 +170,8 @@ export class Agent {
|
|
|
157
170
|
* `mbId`/`isrc` anchors): resolve full metadata via `matchSong`, then write.
|
|
158
171
|
* Matching uses the public AppView unless `appview` is given; an empty match
|
|
159
172
|
* falls back to a minimal record. */
|
|
160
|
-
async scrobbleMatch(
|
|
161
|
-
title
|
|
162
|
-
artist: string,
|
|
163
|
-
album?: string,
|
|
164
|
-
mbId?: string,
|
|
165
|
-
isrc?: string,
|
|
166
|
-
appview?: string,
|
|
167
|
-
): Promise<string> {
|
|
173
|
+
async scrobbleMatch(input: ScrobbleMatchInput, appview?: string): Promise<string> {
|
|
174
|
+
const { title, artist, album, mbId, isrc, timestamp } = input;
|
|
168
175
|
const { RockskyClient } = await import("./client.js");
|
|
169
176
|
const m = (await new RockskyClient(appview).matchSong(title, artist, mbId, isrc)) as Record<
|
|
170
177
|
string,
|
|
@@ -196,6 +203,8 @@ export class Agent {
|
|
|
196
203
|
appleMusicLink: s("appleMusicLink"),
|
|
197
204
|
}
|
|
198
205
|
: { title, artist, album: album ?? "", albumArtist: artist, duration: 0 };
|
|
206
|
+
// "Scrobbled at" — Unix seconds; omitted -> scrobble() defaults to now.
|
|
207
|
+
if (timestamp !== undefined) rec.createdAt = new Date(timestamp * 1000).toISOString();
|
|
199
208
|
return this.scrobble(rec);
|
|
200
209
|
}
|
|
201
210
|
|
package/src/client.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Client, simpleFetchHandler } from "@atcute/client";
|
|
2
2
|
|
|
3
3
|
import { RockskyError } from "./errors.js";
|
|
4
|
+
import { RockskyLibrary } from "./library.js";
|
|
4
5
|
import type {
|
|
5
6
|
ActorProfileViewBasic,
|
|
6
7
|
ActorProfileViewDetailed,
|
|
@@ -58,14 +59,16 @@ export const DEFAULT_APPVIEW = "https://api.rocksky.app";
|
|
|
58
59
|
/** Unauthenticated read client over the public Rocksky AppView XRPC. */
|
|
59
60
|
export class RockskyClient {
|
|
60
61
|
private rpc: Client;
|
|
62
|
+
private token?: string;
|
|
61
63
|
|
|
62
64
|
/**
|
|
63
65
|
* Build a read client against an AppView base URL (defaults to
|
|
64
66
|
* {@link DEFAULT_APPVIEW}). Pass `token` to send it as
|
|
65
67
|
* `Authorization: Bearer <token>` on every read — needed only for auth-gated
|
|
66
|
-
* queries.
|
|
68
|
+
* queries and the whole {@link RockskyClient.library} surface.
|
|
67
69
|
*/
|
|
68
70
|
constructor(appview: string = DEFAULT_APPVIEW, token?: string) {
|
|
71
|
+
this.token = token;
|
|
69
72
|
let handler = simpleFetchHandler({ service: appview });
|
|
70
73
|
if (token) {
|
|
71
74
|
const inner = handler;
|
|
@@ -78,6 +81,20 @@ export class RockskyClient {
|
|
|
78
81
|
this.rpc = new Client({ handler });
|
|
79
82
|
}
|
|
80
83
|
|
|
84
|
+
/**
|
|
85
|
+
* The authenticated `app.rocksky.library.*` (uploaded-music) API. Every
|
|
86
|
+
* library method requires auth, so this throws unless the client was built
|
|
87
|
+
* with a token.
|
|
88
|
+
*/
|
|
89
|
+
library(): RockskyLibrary {
|
|
90
|
+
if (!this.token) {
|
|
91
|
+
throw new Error(
|
|
92
|
+
"app.rocksky.library.* requires an access token; construct RockskyClient(appview, token) first",
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
return new RockskyLibrary(this.rpc);
|
|
96
|
+
}
|
|
97
|
+
|
|
81
98
|
private async query<T>(nsid: string, params: Record<string, unknown>): Promise<T> {
|
|
82
99
|
const clean: Record<string, unknown> = {};
|
|
83
100
|
for (const [k, v] of Object.entries(params)) {
|