···1+import chalk from "chalk";
2+import { RockskyClient } from "client";
3+4+export async function search(
5+ query: string,
6+ { limit = 20, albums = false, artists = false, tracks = false, users = false }
7+) {
8+ const client = new RockskyClient();
9+ const results = await client.search(query, { size: limit });
10+ if (results.records.length === 0) {
11+ console.log(`No results found for ${chalk.magenta(query)}.`);
12+ return;
13+ }
14+15+ // merge all results into one array with type and sort by xata_scrore
16+ let mergedResults = results.records.map((record) => ({
17+ ...record,
18+ type: record.table,
19+ }));
20+ mergedResults.sort((a, b) => b.xata_score - a.xata_score);
21+22+ if (albums) {
23+ mergedResults = mergedResults.filter((record) => record.table === "albums");
24+ }
25+26+ if (artists) {
27+ mergedResults = mergedResults.filter(
28+ (record) => record.table === "artists"
29+ );
30+ }
31+32+ if (tracks) {
33+ mergedResults = mergedResults.filter(({ table }) => table === "tracks");
34+ }
35+36+ if (users) {
37+ mergedResults = mergedResults.filter(({ table }) => table === "users");
38+ }
39+40+ for (const { table, record } of mergedResults) {
41+ if (table === "users") {
42+ console.log(
43+ `${chalk.bold.magenta(record.handle)} ${
44+ record.display_name
45+ } ${chalk.yellow(`https://rocksky.app/profile/${record.did}`)}`
46+ );
47+ }
48+49+ if (table === "albums") {
50+ const link = record.uri
51+ ? `https://rocksky.app/${record.uri?.split("at://")[1]}`
52+ : "";
53+ console.log(
54+ `${chalk.bold.magenta(record.title)} ${record.artist} ${chalk.yellow(
55+ link
56+ )}`
57+ );
58+ }
59+60+ if (table === "tracks") {
61+ const link = record.uri
62+ ? `https://rocksky.app/${record.uri?.split("at://")[1]}`
63+ : "";
64+ console.log(
65+ `${chalk.bold.magenta(record.title)} ${record.artist} ${chalk.yellow(
66+ link
67+ )}`
68+ );
69+ }
70+ }
71+}
+14
src/index.ts
···23import { nowplaying } from "cmd/nowplaying";
4import { scrobbles } from "cmd/scrobbles";
05import { whoami } from "cmd/whoami";
6import { Command } from "commander";
7import version from "../package.json" assert { type: "json" };
···43 .argument("[did]", "The DID or handle of the user to get the scrobbles for.")
44 .description("Display recently played tracks.")
45 .action(scrobbles);
00000000000004647program.parse(process.argv);
···23import { nowplaying } from "cmd/nowplaying";
4import { scrobbles } from "cmd/scrobbles";
5+import { search } from "cmd/search";
6import { whoami } from "cmd/whoami";
7import { Command } from "commander";
8import version from "../package.json" assert { type: "json" };
···44 .argument("[did]", "The DID or handle of the user to get the scrobbles for.")
45 .description("Display recently played tracks.")
46 .action(scrobbles);
47+48+program
49+ .command("search")
50+ .option("-a, --albums", "Search for albums")
51+ .option("-t, --tracks", "Search for tracks")
52+ .option("-u, --users", "Search for users")
53+ .option("-l, --limit <number>", "Number of results to limit")
54+ .argument(
55+ "<query>",
56+ "The search query, e.g., artist, album, title or account"
57+ )
58+ .description("Search for tracks, albums, or accounts.")
59+ .action(search);
6061program.parse(process.argv);