@snwfdhmp/soundcloud-downloader
Version:
Download Soundcloud audio with Node.js, this is a forked version, the original script was written by @zackradisic and forked by @nasheedstation
101 lines (87 loc) • 2.73 kB
text/typescript
import { AxiosInstance } from "axios";
import { TrackInfo } from "./info";
import { appendURL, kindMismatchError, PaginatedQuery } from "./util";
const baseURL = "https://api-v2.soundcloud.com/users/";
export interface Like {
// eslint-disable-next-line camelcase
created_at: string;
kind: string;
track: TrackInfo;
}
export interface GetLikesOptions {
profileUrl?: string;
id?: number;
limit?: number; // -1 indicates no limit
offset?: number;
nextHref?: string;
}
/** @internal */
export const getLikes = async (
options: GetLikesOptions,
clientID: string,
axiosInstance: AxiosInstance
): Promise<PaginatedQuery<Like>> => {
let u = "";
if (!options.nextHref) {
if (!options.limit) options.limit = -1;
if (!options.offset) options.offset = 0;
u = appendURL(
`https://api-v2.soundcloud.com/users/${options.id}/likes`,
"client_id",
clientID,
"limit",
"" + (options.limit === -1 ? 200 : options.limit),
"offset",
"" + options.offset
);
} else {
u = appendURL(options.nextHref, "client_id", clientID);
}
let response: PaginatedQuery<Like>;
let nextHref = "start";
// If options.limit > 0, query each page of likes until we have collected
// `options.limit` liked tracks.
// If options.limit === -1, query every page of likes
if (!options) {
throw new Error("Options are required");
}
if (!options.limit) {
options.limit = -1; // assume default if not provided
}
while (nextHref && (options.limit > 0 || options.limit === -1)) {
const { data } = await axiosInstance.get(u);
const query = data as PaginatedQuery<Like>;
if (!query.collection) throw new Error("Invalid JSON response received");
if (query.collection.length === 0) return data;
if (query.collection[0].kind !== "like")
throw kindMismatchError("like", query.collection[0].kind);
// Only add tracks (for now)
query.collection = query.collection.reduce<Like[]>(
(prev, curr) => (curr.track ? prev.concat(curr) : prev),
[]
);
if (!response!) {
response = query;
} else {
response.collection.push(...query.collection);
}
if (options.limit !== -1) {
options.limit -= query.collection.length;
// We have collected enough likes
if (options.limit <= 0) break;
}
nextHref = query.next_href;
if (nextHref) {
if (options.limit !== -1) {
const url = new URL(nextHref);
url.searchParams.set("limit", "" + options.limit);
nextHref = url.toString();
}
u = appendURL(nextHref, "client_id", clientID);
}
}
if (!response!) {
throw new Error("No response received");
}
return response;
};