soundcloud-api-ts 1.13.2 → 1.13.3

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.
@@ -559,13 +559,13 @@ var SoundCloudClient = class _SoundCloudClient {
559
559
  * @see https://developers.soundcloud.com/docs/api/explorer/open-api#/oauth2/post_oauth2_token
560
560
  */
561
561
  async getClientToken() {
562
+ const credentials = Buffer.from(`${this.config.clientId}:${this.config.clientSecret}`).toString("base64");
562
563
  return this.fetch({
563
564
  path: "/oauth/token",
564
565
  method: "POST",
566
+ headers: { Authorization: `Basic ${credentials}` },
565
567
  body: new URLSearchParams({
566
- grant_type: "client_credentials",
567
- client_id: this.config.clientId,
568
- client_secret: this.config.clientSecret
568
+ grant_type: "client_credentials"
569
569
  })
570
570
  });
571
571
  }
@@ -2033,5 +2033,5 @@ var unrepostPlaylist = async (token, playlistId) => {
2033
2033
  var getSoundCloudWidgetUrl = (trackId) => `https%3A//api.soundcloud.com/tracks/${trackId}&show_teaser=false&color=%2300a99d&inverse=false&show_user=false&sharing=false&buying=false&liking=false&show_artwork=false&show_name=false`;
2034
2034
 
2035
2035
  export { IMPLEMENTED_OPERATIONS, InFlightDeduper, RawClient, SoundCloudClient, createPlaylist, createTrackComment, deletePlaylist, deleteTrack, fetchAll, followUser, generateCodeChallenge, generateCodeVerifier, getAuthorizationUrl, getClientToken, getFollowers, getFollowings, getMe, getMeActivities, getMeActivitiesOwn, getMeActivitiesTracks, getMeConnections, getMeFollowers, getMeFollowings, getMeFollowingsTracks, getMeLikesPlaylists, getMeLikesTracks, getMePlaylists, getMeTracks, getPlaylist, getPlaylistReposts, getPlaylistTracks, getRelatedTracks, getSoundCloudWidgetUrl, getTrack, getTrackComments, getTrackLikes, getTrackReposts, getTrackStreams, getTracks, getUser, getUserLikesPlaylists, getUserLikesTracks, getUserPlaylists, getUserToken, getUserTracks, getUserWebProfiles, likePlaylist, likeTrack, paginate, paginateItems, refreshUserToken, repostPlaylist, repostTrack, resolveUrl, scFetch, scFetchUrl, searchPlaylists, searchTracks, searchUsers, signOut, unfollowUser, unlikePlaylist, unlikeTrack, unrepostPlaylist, unrepostTrack, updatePlaylist, updateTrack };
2036
- //# sourceMappingURL=chunk-DCZIPG5T.mjs.map
2037
- //# sourceMappingURL=chunk-DCZIPG5T.mjs.map
2036
+ //# sourceMappingURL=chunk-QNL6UJL5.mjs.map
2037
+ //# sourceMappingURL=chunk-QNL6UJL5.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/client/http.ts","../src/client/paginate.ts","../src/client/raw.ts","../src/client/SoundCloudClient.ts","../src/client/dedupe.ts","../src/client/registry.ts","../src/auth/getClientToken.ts","../src/auth/getUserToken.ts","../src/auth/refreshUserToken.ts","../src/auth/signOut.ts","../src/auth/getAuthorizationUrl.ts","../src/auth/pkce.ts","../src/users/getMe.ts","../src/users/getUser.ts","../src/users/getFollowers.ts","../src/users/getFollowings.ts","../src/users/getTracks.ts","../src/users/getPlaylists.ts","../src/users/getLikesTracks.ts","../src/users/getLikesPlaylists.ts","../src/users/getWebProfiles.ts","../src/tracks/getTrack.ts","../src/tracks/getTracks.ts","../src/tracks/getComments.ts","../src/tracks/createComment.ts","../src/tracks/getLikes.ts","../src/tracks/getReposts.ts","../src/tracks/getRelated.ts","../src/tracks/getStreams.ts","../src/tracks/likeTrack.ts","../src/tracks/unlikeTrack.ts","../src/tracks/updateTrack.ts","../src/tracks/deleteTrack.ts","../src/playlists/getPlaylist.ts","../src/playlists/getTracks.ts","../src/playlists/getReposts.ts","../src/playlists/createPlaylist.ts","../src/playlists/updatePlaylist.ts","../src/playlists/deletePlaylist.ts","../src/search/searchTracks.ts","../src/search/searchUsers.ts","../src/search/searchPlaylists.ts","../src/resolve/resolveUrl.ts","../src/me/activities.ts","../src/me/likes.ts","../src/me/followings.ts","../src/me/followers.ts","../src/me/playlists.ts","../src/me/tracks.ts","../src/me/connections.ts","../src/likes/index.ts","../src/reposts/index.ts","../src/utils/widget.ts"],"names":["body","err","SoundCloudClient"],"mappings":"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","file":"chunk-QNL6UJL5.mjs","sourcesContent":["import { SoundCloudError, type SoundCloudErrorBody } from \"../errors.js\";\n\nconst BASE_URL = \"https://api.soundcloud.com\";\nconst AUTH_BASE_URL = \"https://secure.soundcloud.com\";\n\n/**\n * Options for making a request to the SoundCloud API via {@link scFetch}.\n */\nexport interface RequestOptions {\n /** API path relative to `https://api.soundcloud.com` (e.g. \"/tracks/123\"). Paths starting with `/oauth` are routed to `https://secure.soundcloud.com`. */\n path: string;\n /** HTTP method */\n method: \"GET\" | \"POST\" | \"PUT\" | \"DELETE\";\n /** OAuth access token to include in the Authorization header */\n token?: string;\n /** Request body — automatically serialized based on type */\n body?: Record<string, unknown> | FormData | URLSearchParams;\n /** Additional headers to include in the request */\n headers?: Record<string, string>;\n /** Override the Content-Type header (defaults to \"application/json\" for object bodies) */\n contentType?: string;\n}\n\n/**\n * Structured telemetry emitted after every API request.\n */\nexport interface SCRequestTelemetry {\n /** HTTP method used */\n method: \"GET\" | \"POST\" | \"PUT\" | \"DELETE\";\n /** API path or full URL */\n path: string;\n /** Total duration including retries, in milliseconds */\n durationMs: number;\n /** Final HTTP status code */\n status: number;\n /** Number of retries performed (0 = succeeded on first attempt) */\n retryCount: number;\n /** Error message if the request ultimately failed */\n error?: string;\n}\n\n/**\n * Information passed to the `onRetry` callback on each retry attempt.\n */\nexport interface RetryInfo {\n /** Which retry attempt this is (1-based) */\n attempt: number;\n /** Delay in milliseconds before this retry fires */\n delayMs: number;\n /** Human-readable reason (e.g. \"429 Too Many Requests\") */\n reason: string;\n /** HTTP status that triggered the retry, if applicable */\n status?: number;\n /** The URL that was requested */\n url: string;\n}\n\n/**\n * Configuration for automatic retry with exponential backoff on transient errors.\n */\nexport interface RetryConfig {\n /** Maximum number of retries on 429/5xx responses (default: 3) */\n maxRetries: number;\n /** Base delay in milliseconds for exponential backoff (default: 1000) */\n retryBaseDelay: number;\n /** Optional callback for debug logging of retry attempts */\n onDebug?: (message: string) => void;\n /** Optional callback fired before each retry with structured retry info */\n onRetry?: (info: RetryInfo) => void;\n}\n\n/**\n * Context for automatic token refresh when a request returns 401 Unauthorized.\n * Used internally by {@link SoundCloudClient} to transparently refresh expired tokens.\n */\nexport interface AutoRefreshContext {\n /** Returns the current stored access token */\n getToken: () => string | undefined;\n /** Called to obtain fresh tokens; if absent, 401 errors are thrown directly */\n onTokenRefresh?: () => Promise<{ access_token: string; refresh_token?: string }>;\n /** Callback to store the new tokens after a successful refresh */\n setToken: (accessToken: string, refreshToken?: string) => void;\n /** Retry configuration for this context */\n retry?: RetryConfig;\n /** Called after every API request with structured telemetry */\n onRequest?: (telemetry: SCRequestTelemetry) => void;\n}\n\nconst DEFAULT_RETRY: RetryConfig = { maxRetries: 3, retryBaseDelay: 1000 };\n\n/**\n * Creates a promise that resolves after the specified delay.\n *\n * @param ms - Delay duration in milliseconds\n * @returns A promise that resolves after `ms` milliseconds\n */\nexport function delay(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nfunction isRetryable(status: number): boolean {\n return status === 429 || (status >= 500 && status <= 599);\n}\n\nfunction getRetryDelay(\n response: { status: number; headers: { get(key: string): string | null } },\n attempt: number,\n config: RetryConfig,\n): number {\n if (response.status === 429) {\n const retryAfter = response.headers.get(\"retry-after\");\n if (retryAfter) {\n const seconds = Number(retryAfter);\n if (!Number.isNaN(seconds)) return Math.min(seconds * 1000, 60000);\n }\n }\n // Exponential backoff with jitter\n const base = config.retryBaseDelay * Math.pow(2, attempt);\n return base + Math.random() * base * 0.1;\n}\n\nasync function parseErrorBody(response: { json(): Promise<unknown> }): Promise<unknown> {\n try {\n return await response.json();\n } catch {\n return undefined;\n }\n}\n\n/**\n * Make a request to the SoundCloud API using native `fetch`.\n *\n * Handles JSON serialization, OAuth headers, automatic retries on 429/5xx,\n * and optional automatic token refresh on 401. For 302 redirects, returns\n * the `Location` header value. For 204 responses, returns `undefined`.\n *\n * @param options - Request configuration (path, method, token, body)\n * @param refreshCtx - Optional auto-refresh context for transparent token renewal\n * @returns Parsed JSON response, redirect URL, or undefined for empty responses\n * @throws {SoundCloudError} When the API returns a non-retryable error status\n *\n * @example\n * ```ts\n * import { scFetch } from 'soundcloud-api-ts';\n *\n * const track = await scFetch<SoundCloudTrack>({\n * path: '/tracks/123456',\n * method: 'GET',\n * token: 'your-access-token',\n * });\n * ```\n *\n * @see https://developers.soundcloud.com/docs/api/explorer/open-api\n */\nexport async function scFetch<T>(\n options: RequestOptions,\n refreshCtx?: AutoRefreshContext,\n onRequest?: (telemetry: SCRequestTelemetry) => void,\n): Promise<T> {\n const retryConfig = refreshCtx?.retry ?? DEFAULT_RETRY;\n const telemetryCallback = onRequest ?? refreshCtx?.onRequest;\n const startTime = Date.now();\n let retryCount = 0;\n let finalStatus = 0;\n\n const emitTelemetry = (error?: string) => {\n if (!telemetryCallback) return;\n telemetryCallback({\n method: options.method,\n path: options.path,\n durationMs: Date.now() - startTime,\n status: finalStatus,\n retryCount,\n ...(error ? { error } : {}),\n });\n };\n\n const execute = async (tokenOverride?: string): Promise<T> => {\n const isAuthPath = options.path.startsWith(\"/oauth\");\n const url = `${isAuthPath ? AUTH_BASE_URL : BASE_URL}${options.path}`;\n const headers: Record<string, string> = {\n Accept: \"application/json\",\n ...options.headers,\n };\n\n const token = tokenOverride ?? options.token;\n if (token && !headers[\"Authorization\"]) {\n headers[\"Authorization\"] = `OAuth ${token}`;\n }\n\n let fetchBody: string | FormData | URLSearchParams | undefined;\n if (options.body) {\n if (options.body instanceof URLSearchParams) {\n fetchBody = options.body;\n headers[\"Content-Type\"] = \"application/x-www-form-urlencoded\";\n } else if (options.body instanceof FormData) {\n fetchBody = options.body;\n } else {\n headers[\"Content-Type\"] = options.contentType ?? \"application/json\";\n fetchBody = JSON.stringify(options.body);\n }\n } else if (options.contentType) {\n headers[\"Content-Type\"] = options.contentType;\n }\n\n let lastResponse: Awaited<ReturnType<typeof fetch>> | undefined;\n\n for (let attempt = 0; attempt <= retryConfig.maxRetries; attempt++) {\n const response = await fetch(url, {\n method: options.method,\n headers,\n body: fetchBody,\n redirect: \"manual\",\n });\n\n finalStatus = response.status;\n\n if (response.status === 302) {\n const location = response.headers.get(\"location\");\n if (location) {\n emitTelemetry();\n return location as T;\n }\n }\n\n if (response.status === 204 || response.headers.get(\"content-length\") === \"0\") {\n emitTelemetry();\n return undefined as T;\n }\n\n if (response.ok) {\n const data = await response.json();\n // Attach non-enumerable _meta so callers can access status/headers without breaking toEqual checks\n if (typeof data === \"object\" && data !== null) {\n const metaHeaders: Record<string, string> = {};\n if (typeof response.headers.forEach === \"function\") {\n response.headers.forEach((value: string, key: string) => {\n metaHeaders[key] = value;\n });\n }\n try {\n Object.defineProperty(data, \"_meta\", {\n value: { status: response.status, headers: metaHeaders },\n enumerable: false,\n configurable: true,\n writable: true,\n });\n } catch {\n // frozen objects — skip\n }\n }\n emitTelemetry();\n return data as T;\n }\n\n // Don't retry 401 (handled by token refresh) or non-retryable 4xx\n if (!isRetryable(response.status)) {\n const body = await parseErrorBody(response);\n const err = new SoundCloudError(response.status, response.statusText, body as SoundCloudErrorBody);\n emitTelemetry(err.message);\n throw err;\n }\n\n lastResponse = response;\n\n if (attempt < retryConfig.maxRetries) {\n retryCount = attempt + 1;\n const delayMs = getRetryDelay(response, attempt, retryConfig);\n retryConfig.onDebug?.(\n `Retry ${attempt + 1}/${retryConfig.maxRetries} after ${Math.round(delayMs)}ms (status ${response.status})`,\n );\n retryConfig.onRetry?.({\n attempt: retryCount,\n delayMs,\n reason: `${response.status} ${response.statusText}`,\n status: response.status,\n url,\n });\n await delay(delayMs);\n }\n }\n\n // All retries exhausted\n const body = await parseErrorBody(lastResponse!);\n const err = new SoundCloudError(lastResponse!.status, lastResponse!.statusText, body as SoundCloudErrorBody);\n emitTelemetry(err.message);\n throw err;\n };\n\n try {\n return await execute();\n } catch (err) {\n // Auto-refresh on 401\n if (\n refreshCtx?.onTokenRefresh &&\n err instanceof SoundCloudError &&\n err.status === 401\n ) {\n const newToken = await refreshCtx.onTokenRefresh();\n refreshCtx.setToken(newToken.access_token, newToken.refresh_token);\n return execute(newToken.access_token);\n }\n throw err;\n }\n}\n\n/**\n * Fetch an absolute URL (e.g. `next_href` from paginated responses).\n *\n * Used internally for pagination — follows the same retry logic as {@link scFetch}.\n *\n * @param url - Absolute URL to fetch (typically a `next_href` value)\n * @param token - OAuth access token to include in the Authorization header\n * @param retryConfig - Optional retry configuration override\n * @returns Parsed JSON response\n * @throws {SoundCloudError} When the API returns a non-retryable error status\n *\n * @example\n * ```ts\n * import { scFetchUrl } from 'soundcloud-api-ts';\n *\n * const nextPage = await scFetchUrl<SoundCloudPaginatedResponse<SoundCloudTrack>>(\n * response.next_href,\n * 'your-access-token',\n * );\n * ```\n */\nexport async function scFetchUrl<T>(\n url: string,\n token?: string,\n retryConfig?: RetryConfig,\n onRequest?: (telemetry: SCRequestTelemetry) => void,\n): Promise<T> {\n const config = retryConfig ?? DEFAULT_RETRY;\n const headers: Record<string, string> = { Accept: \"application/json\" };\n if (token) headers[\"Authorization\"] = `OAuth ${token}`;\n\n const startTime = Date.now();\n let retryCount = 0;\n let finalStatus = 0;\n\n const emitTelemetry = (error?: string) => {\n if (!onRequest) return;\n onRequest({\n method: \"GET\",\n path: url,\n durationMs: Date.now() - startTime,\n status: finalStatus,\n retryCount,\n ...(error ? { error } : {}),\n });\n };\n\n let lastResponse: Awaited<ReturnType<typeof fetch>> | undefined;\n\n for (let attempt = 0; attempt <= config.maxRetries; attempt++) {\n const response = await fetch(url, { method: \"GET\", headers, redirect: \"manual\" });\n\n finalStatus = response.status;\n\n if (response.status === 302) {\n const location = response.headers.get(\"location\");\n if (location) {\n emitTelemetry();\n return location as T;\n }\n }\n\n if (response.status === 204 || response.headers.get(\"content-length\") === \"0\") {\n emitTelemetry();\n return undefined as T;\n }\n\n if (response.ok) {\n const data = await response.json();\n if (typeof data === \"object\" && data !== null) {\n const metaHeaders: Record<string, string> = {};\n if (typeof response.headers.forEach === \"function\") {\n response.headers.forEach((value: string, key: string) => {\n metaHeaders[key] = value;\n });\n }\n try {\n Object.defineProperty(data, \"_meta\", {\n value: { status: response.status, headers: metaHeaders },\n enumerable: false,\n configurable: true,\n writable: true,\n });\n } catch {\n // frozen objects — skip\n }\n }\n emitTelemetry();\n return data as T;\n }\n\n if (!isRetryable(response.status)) {\n const body = await parseErrorBody(response);\n const err = new SoundCloudError(response.status, response.statusText, body as SoundCloudErrorBody);\n emitTelemetry(err.message);\n throw err;\n }\n\n lastResponse = response;\n\n if (attempt < config.maxRetries) {\n retryCount = attempt + 1;\n const delayMs = getRetryDelay(response, attempt, config);\n config.onDebug?.(\n `Retry ${attempt + 1}/${config.maxRetries} after ${Math.round(delayMs)}ms (status ${response.status})`,\n );\n config.onRetry?.({\n attempt: retryCount,\n delayMs,\n reason: `${response.status} ${response.statusText}`,\n status: response.status,\n url,\n });\n await delay(delayMs);\n }\n }\n\n const body = await parseErrorBody(lastResponse!);\n const err = new SoundCloudError(lastResponse!.status, lastResponse!.statusText, body as SoundCloudErrorBody);\n emitTelemetry(err.message);\n throw err;\n}\n","import type { SoundCloudPaginatedResponse } from \"../types/api.js\";\n\n/**\n * Async generator that automatically follows `next_href` pagination,\n * yielding each page's `collection` array.\n *\n * @param firstPage - Function that fetches the first page of results\n * @param fetchNext - Function that fetches subsequent pages given a `next_href` URL\n * @returns An async generator yielding arrays of items (one per page)\n *\n * @example\n * ```ts\n * import { paginate, searchTracks, scFetchUrl } from 'soundcloud-api-ts';\n *\n * const pages = paginate(\n * () => searchTracks(token, 'lofi'),\n * (url) => scFetchUrl(url, token),\n * );\n *\n * for await (const page of pages) {\n * console.log(`Got ${page.length} tracks`);\n * }\n * ```\n *\n * @see https://developers.soundcloud.com/docs/api/explorer/open-api\n */\nexport async function* paginate<T>(\n firstPage: () => Promise<SoundCloudPaginatedResponse<T>>,\n fetchNext: (url: string) => Promise<SoundCloudPaginatedResponse<T>>,\n): AsyncGenerator<T[], void, undefined> {\n let page = await firstPage();\n yield page.collection;\n\n while (page.next_href) {\n page = await fetchNext(page.next_href);\n yield page.collection;\n }\n}\n\n/**\n * Async generator that yields individual items across all pages,\n * automatically following `next_href` pagination.\n *\n * @param firstPage - Function that fetches the first page of results\n * @param fetchNext - Function that fetches subsequent pages given a `next_href` URL\n * @returns An async generator yielding individual items\n *\n * @example\n * ```ts\n * import { paginateItems, searchTracks, scFetchUrl } from 'soundcloud-api-ts';\n *\n * const tracks = paginateItems(\n * () => searchTracks(token, 'lofi'),\n * (url) => scFetchUrl(url, token),\n * );\n *\n * for await (const track of tracks) {\n * console.log(track.title);\n * }\n * ```\n *\n * @see https://developers.soundcloud.com/docs/api/explorer/open-api\n */\nexport async function* paginateItems<T>(\n firstPage: () => Promise<SoundCloudPaginatedResponse<T>>,\n fetchNext: (url: string) => Promise<SoundCloudPaginatedResponse<T>>,\n): AsyncGenerator<T, void, undefined> {\n for await (const page of paginate(firstPage, fetchNext)) {\n for (const item of page) {\n yield item;\n }\n }\n}\n\n/**\n * Collects all pages into a single flat array, with an optional maximum item limit.\n *\n * @param firstPage - Function that fetches the first page of results\n * @param fetchNext - Function that fetches subsequent pages given a `next_href` URL\n * @param options - Optional configuration\n * @param options.maxItems - Maximum number of items to collect (defaults to all)\n * @returns A promise that resolves to a flat array of all collected items\n *\n * @example\n * ```ts\n * import { fetchAll, searchTracks, scFetchUrl } from 'soundcloud-api-ts';\n *\n * const allTracks = await fetchAll(\n * () => searchTracks(token, 'lofi'),\n * (url) => scFetchUrl(url, token),\n * { maxItems: 100 },\n * );\n * console.log(`Fetched ${allTracks.length} tracks`);\n * ```\n *\n * @see https://developers.soundcloud.com/docs/api/explorer/open-api\n */\nexport async function fetchAll<T>(\n firstPage: () => Promise<SoundCloudPaginatedResponse<T>>,\n fetchNext: (url: string) => Promise<SoundCloudPaginatedResponse<T>>,\n options?: { maxItems?: number },\n): Promise<T[]> {\n const result: T[] = [];\n const max = options?.maxItems ?? Infinity;\n\n for await (const page of paginate(firstPage, fetchNext)) {\n for (const item of page) {\n result.push(item);\n if (result.length >= max) return result;\n }\n }\n\n return result;\n}\n","/**\n * Raw response from the SoundCloud API, including status code and headers.\n */\nexport type RawResponse<T = unknown> = {\n /** Parsed response body */\n data: T;\n /** HTTP status code */\n status: number;\n /** Response headers as a plain object */\n headers: Record<string, string>;\n};\n\n/**\n * Low-level HTTP client that returns raw responses without throwing on non-2xx status codes.\n * Useful when you need access to status codes, headers, or want to handle errors manually.\n *\n * @example\n * ```ts\n * const raw = sc.raw;\n * const res = await raw.get('/tracks/123456');\n * console.log(res.status, res.headers, res.data);\n * ```\n */\nexport class RawClient {\n constructor(\n private baseUrl: string,\n private getToken: () => string | undefined,\n private fetchFn: typeof fetch,\n ) {}\n\n /**\n * Make a raw HTTP request. Path template placeholders like `{id}` are substituted\n * from matching keys in `query` before the remaining query params are appended to\n * the URL as search parameters.\n */\n async request<T = unknown>({\n method,\n path,\n query,\n body,\n token,\n }: {\n method: string;\n path: string;\n query?: Record<string, string | number | boolean | undefined>;\n body?: unknown;\n token?: string;\n }): Promise<RawResponse<T>> {\n // Path templating: substitute {param} placeholders from query params\n let resolvedPath = path;\n const remainingQuery: Record<string, string> = {};\n\n if (query) {\n for (const [key, value] of Object.entries(query)) {\n if (value === undefined) continue;\n const placeholder = `{${key}}`;\n if (resolvedPath.includes(placeholder)) {\n resolvedPath = resolvedPath.replace(new RegExp(`\\\\{${key}\\\\}`, \"g\"), String(value));\n } else {\n remainingQuery[key] = String(value);\n }\n }\n }\n\n // Build URL with remaining query params\n const fullUrl = resolvedPath.startsWith(\"http\")\n ? new URL(resolvedPath)\n : new URL(resolvedPath, this.baseUrl);\n for (const [key, value] of Object.entries(remainingQuery)) {\n fullUrl.searchParams.set(key, value);\n }\n\n const headers: Record<string, string> = {\n Accept: \"application/json\",\n };\n\n const authToken = token ?? this.getToken();\n if (authToken) {\n headers[\"Authorization\"] = `OAuth ${authToken}`;\n }\n\n let fetchBody: string | undefined;\n if (body !== undefined) {\n headers[\"Content-Type\"] = \"application/json\";\n fetchBody = JSON.stringify(body);\n }\n\n const response = await this.fetchFn(fullUrl.toString(), {\n method,\n headers,\n body: fetchBody,\n });\n\n // Collect response headers\n const responseHeaders: Record<string, string> = {};\n if (typeof response.headers.forEach === \"function\") {\n response.headers.forEach((value: string, key: string) => {\n responseHeaders[key] = value;\n });\n }\n\n // Parse body\n let data: T;\n const contentLength = response.headers.get(\"content-length\");\n if (response.status === 204 || contentLength === \"0\") {\n data = undefined as T;\n } else {\n try {\n data = (await response.json()) as T;\n } catch {\n data = undefined as T;\n }\n }\n\n return { data, status: response.status, headers: responseHeaders };\n }\n\n /** GET shorthand */\n get<T = unknown>(\n path: string,\n params?: Record<string, string | number | boolean | undefined>,\n ): Promise<RawResponse<T>> {\n return this.request<T>({ method: \"GET\", path, query: params });\n }\n\n /** POST shorthand */\n post<T = unknown>(path: string, body?: unknown): Promise<RawResponse<T>> {\n return this.request<T>({ method: \"POST\", path, body });\n }\n\n /** PUT shorthand */\n put<T = unknown>(path: string, body?: unknown): Promise<RawResponse<T>> {\n return this.request<T>({ method: \"PUT\", path, body });\n }\n\n /** DELETE shorthand */\n delete<T = unknown>(path: string): Promise<RawResponse<T>> {\n return this.request<T>({ method: \"DELETE\", path });\n }\n}\n","import { scFetch, scFetchUrl, type AutoRefreshContext, type RetryConfig, type RetryInfo, type SCRequestTelemetry } from \"./http.js\";\nimport { paginate, paginateItems, fetchAll } from \"./paginate.js\";\nimport { RawClient } from \"./raw.js\";\nimport type { SoundCloudCache } from \"./cache.js\";\nimport type {\n SoundCloudToken,\n SoundCloudUser,\n SoundCloudMe,\n SoundCloudTrack,\n SoundCloudPlaylist,\n SoundCloudComment,\n SoundCloudStreams,\n SoundCloudWebProfile,\n SoundCloudActivitiesResponse,\n SoundCloudPaginatedResponse,\n SoundCloudConnection,\n} from \"../types/api.js\";\nimport type { UpdateTrackParams } from \"../tracks/updateTrack.js\";\nimport type { CreatePlaylistParams } from \"../playlists/createPlaylist.js\";\nimport type { UpdatePlaylistParams } from \"../playlists/updatePlaylist.js\";\n\n/**\n * Configuration options for creating a {@link SoundCloudClient} instance.\n */\nexport interface SoundCloudClientConfig {\n /** Your SoundCloud application's OAuth client ID */\n clientId: string;\n /** Your SoundCloud application's OAuth client secret */\n clientSecret: string;\n /** OAuth redirect URI registered with your SoundCloud application (required for user auth flows) */\n redirectUri?: string;\n /**\n * Called automatically when a request returns 401 Unauthorized.\n * Return new tokens to transparently retry the failed request.\n */\n onTokenRefresh?: (client: SoundCloudClient) => Promise<SoundCloudToken>;\n /** Maximum number of retries on 429 (rate limit) and 5xx (server error) responses (default: 3) */\n maxRetries?: number;\n /** Base delay in milliseconds for exponential backoff between retries (default: 1000) */\n retryBaseDelay?: number;\n /** Optional debug logger callback for retry attempts and other internal events */\n onDebug?: (message: string) => void;\n /** Called after every API request with structured telemetry (timing, status, retries) */\n onRequest?: (telemetry: SCRequestTelemetry) => void;\n /** Custom fetch implementation (defaults to `globalThis.fetch`) */\n fetch?: typeof globalThis.fetch;\n /** Deduplicate concurrent identical requests (default: true) */\n dedupe?: boolean;\n /** Optional cache backend for API responses */\n cache?: SoundCloudCache;\n /** Default TTL in milliseconds for cached responses (default: 60000) */\n cacheTtlMs?: number;\n /** Called before each retry attempt with structured retry info */\n onRetry?: (info: RetryInfo) => void;\n}\n\n/**\n * Optional token override that can be passed as the last parameter to client methods.\n * When provided, the explicit token is used instead of the client's stored token.\n */\nexport interface TokenOption {\n /** OAuth access token to use for this specific request */\n token?: string;\n}\n\n/** Resolve a token: use explicit override, fall back to stored, or throw. */\ntype TokenGetter = () => string | undefined;\n\nfunction resolveToken(tokenGetter: TokenGetter, explicit?: string): string {\n const t = explicit ?? tokenGetter();\n if (!t) throw new Error(\"No access token available. Call client.setToken() or pass a token explicitly.\");\n return t;\n}\n\n/**\n * High-level SoundCloud API client with namespaced methods for all API areas.\n *\n * Provides automatic token management, retry with exponential backoff,\n * optional automatic token refresh on 401, and built-in pagination helpers.\n *\n * @example\n * ```ts\n * import { SoundCloudClient } from 'soundcloud-api-ts';\n *\n * const sc = new SoundCloudClient({\n * clientId: 'YOUR_CLIENT_ID',\n * clientSecret: 'YOUR_CLIENT_SECRET',\n * redirectUri: 'https://example.com/callback',\n * });\n *\n * // Authenticate\n * const token = await sc.auth.getClientToken();\n * sc.setToken(token.access_token);\n *\n * // Use the API\n * const track = await sc.tracks.getTrack(123456);\n * console.log(track.title);\n *\n * // Search with pagination\n * for await (const track of sc.paginateItems(() => sc.search.tracks('lofi'))) {\n * console.log(track.title);\n * }\n * ```\n *\n * @see https://developers.soundcloud.com/docs/api/explorer/open-api\n */\nexport class SoundCloudClient {\n private config: SoundCloudClientConfig;\n private _accessToken?: string;\n private _refreshToken?: string;\n\n /** Authentication methods (OAuth token grants, sign out) */\n public auth: SoundCloudClient.Auth;\n /** Authenticated user endpoints (/me) */\n public me: SoundCloudClient.Me;\n /** User profile endpoints (/users) */\n public users: SoundCloudClient.Users;\n /** Track endpoints (/tracks) */\n public tracks: SoundCloudClient.Tracks;\n /** Playlist endpoints (/playlists) */\n public playlists: SoundCloudClient.Playlists;\n /** Search endpoints */\n public search: SoundCloudClient.Search;\n /** URL resolution endpoint (/resolve) */\n public resolve: SoundCloudClient.Resolve;\n /** Like/unlike actions (/likes) */\n public likes: SoundCloudClient.Likes;\n /** Repost/unrepost actions (/reposts) */\n public reposts: SoundCloudClient.Reposts;\n /** Low-level raw HTTP client — returns status/headers without throwing on non-2xx */\n public raw: RawClient;\n\n /**\n * Creates a new SoundCloudClient instance.\n *\n * @param config - Client configuration including OAuth credentials and optional settings\n */\n constructor(config: SoundCloudClientConfig) {\n this.config = config;\n const getToken: TokenGetter = () => this._accessToken;\n const retryConfig: RetryConfig = {\n maxRetries: config.maxRetries ?? 3,\n retryBaseDelay: config.retryBaseDelay ?? 1000,\n onDebug: config.onDebug,\n onRetry: config.onRetry,\n };\n const refreshCtx: AutoRefreshContext = config.onTokenRefresh\n ? {\n getToken,\n onTokenRefresh: async () => {\n const result = await config.onTokenRefresh!(this);\n return result;\n },\n setToken: (a, r) => this.setToken(a, r),\n retry: retryConfig,\n onRequest: config.onRequest,\n }\n : {\n getToken,\n setToken: /* v8 ignore next */ (a, r) => this.setToken(a, r),\n retry: retryConfig,\n onRequest: config.onRequest,\n };\n\n this.auth = new SoundCloudClient.Auth(this.config);\n this.me = new SoundCloudClient.Me(getToken, refreshCtx!);\n this.users = new SoundCloudClient.Users(getToken, refreshCtx!);\n this.tracks = new SoundCloudClient.Tracks(getToken, refreshCtx!);\n this.playlists = new SoundCloudClient.Playlists(getToken, refreshCtx!);\n this.search = new SoundCloudClient.Search(getToken, refreshCtx!);\n this.resolve = new SoundCloudClient.Resolve(getToken, refreshCtx!);\n this.likes = new SoundCloudClient.Likes(getToken, refreshCtx!);\n this.reposts = new SoundCloudClient.Reposts(getToken, refreshCtx!);\n this.raw = new RawClient(\"https://api.soundcloud.com\", getToken, config.fetch ?? globalThis.fetch);\n }\n\n /**\n * Store an access token (and optionally refresh token) on this client instance.\n *\n * @param accessToken - The OAuth access token to store\n * @param refreshToken - Optional refresh token for automatic token renewal\n */\n setToken(accessToken: string, refreshToken?: string): void {\n this._accessToken = accessToken;\n if (refreshToken !== undefined) this._refreshToken = refreshToken;\n }\n\n /** Clear all stored tokens from this client instance. */\n clearToken(): void {\n this._accessToken = undefined;\n this._refreshToken = undefined;\n }\n\n /** Get the currently stored access token, or `undefined` if none is set. */\n get accessToken(): string | undefined {\n return this._accessToken;\n }\n\n /** Get the currently stored refresh token, or `undefined` if none is set. */\n get refreshToken(): string | undefined {\n return this._refreshToken;\n }\n\n /**\n * Async generator that follows `next_href` automatically, yielding each page's `collection`.\n *\n * @param firstPage - Function that fetches the first page\n * @returns An async generator yielding arrays of items (one per page)\n *\n * @example\n * ```ts\n * for await (const page of sc.paginate(() => sc.search.tracks('lofi'))) {\n * console.log(page); // SoundCloudTrack[]\n * }\n * ```\n */\n paginate<T>(firstPage: () => Promise<SoundCloudPaginatedResponse<T>>): AsyncGenerator<T[], void, undefined> {\n const token = this._accessToken;\n const onReq = this.config.onRequest;\n return paginate(firstPage, (url) => scFetchUrl<SoundCloudPaginatedResponse<T>>(url, token, undefined, onReq));\n }\n\n /**\n * Async generator that yields individual items across all pages.\n *\n * @param firstPage - Function that fetches the first page\n * @returns An async generator yielding individual items\n *\n * @example\n * ```ts\n * for await (const track of sc.paginateItems(() => sc.search.tracks('lofi'))) {\n * console.log(track.title); // single SoundCloudTrack\n * }\n * ```\n */\n paginateItems<T>(firstPage: () => Promise<SoundCloudPaginatedResponse<T>>): AsyncGenerator<T, void, undefined> {\n const token = this._accessToken;\n const onReq = this.config.onRequest;\n return paginateItems(firstPage, (url) => scFetchUrl<SoundCloudPaginatedResponse<T>>(url, token, undefined, onReq));\n }\n\n /**\n * Collects all pages into a single flat array.\n *\n * @param firstPage - Function that fetches the first page\n * @param options - Optional configuration\n * @param options.maxItems - Maximum number of items to collect\n * @returns A promise resolving to a flat array of all items\n *\n * @example\n * ```ts\n * const allTracks = await sc.fetchAll(() => sc.search.tracks('lofi'), { maxItems: 100 });\n * console.log(allTracks.length);\n * ```\n */\n fetchAll<T>(firstPage: () => Promise<SoundCloudPaginatedResponse<T>>, options?: { maxItems?: number }): Promise<T[]> {\n const token = this._accessToken;\n const onReq = this.config.onRequest;\n return fetchAll(firstPage, (url) => scFetchUrl<SoundCloudPaginatedResponse<T>>(url, token, undefined, onReq), options);\n }\n}\n\nexport namespace SoundCloudClient {\n /**\n * Authentication namespace — OAuth token grants and session management.\n *\n * @example\n * ```ts\n * const token = await sc.auth.getClientToken();\n * sc.setToken(token.access_token);\n * ```\n */\n export class Auth {\n constructor(private config: SoundCloudClientConfig) {}\n private fetch<T>(opts: Parameters<typeof scFetch>[0]) { return scFetch<T>(opts, undefined, this.config.onRequest); }\n\n /**\n * Build the authorization URL to redirect users to SoundCloud's OAuth login page.\n *\n * @param options - Optional parameters for the authorization request\n * @param options.state - Opaque state value for CSRF protection\n * @param options.codeChallenge - PKCE S256 code challenge for enhanced security\n * @returns The full authorization URL to redirect the user to\n * @throws {Error} If `redirectUri` was not provided in the client config\n *\n * @example\n * ```ts\n * const url = sc.auth.getAuthorizationUrl({ state: 'random-state' });\n * // Redirect user to `url`\n * ```\n *\n * @see https://developers.soundcloud.com/docs/api/explorer/open-api#/oauth2\n */\n getAuthorizationUrl(options?: { state?: string; codeChallenge?: string }): string {\n if (!this.config.redirectUri) throw new Error(\"redirectUri is required for getAuthorizationUrl\");\n const params = new URLSearchParams({\n client_id: this.config.clientId,\n redirect_uri: this.config.redirectUri,\n response_type: \"code\",\n });\n if (options?.state) params.set(\"state\", options.state);\n if (options?.codeChallenge) {\n params.set(\"code_challenge\", options.codeChallenge);\n params.set(\"code_challenge_method\", \"S256\");\n }\n return `https://secure.soundcloud.com/authorize?${params}`;\n }\n\n /**\n * Exchange client credentials for an access token (machine-to-machine auth).\n *\n * @returns The OAuth token response\n * @throws {SoundCloudError} When authentication fails\n *\n * @example\n * ```ts\n * const token = await sc.auth.getClientToken();\n * sc.setToken(token.access_token);\n * ```\n *\n * @see https://developers.soundcloud.com/docs/api/explorer/open-api#/oauth2/post_oauth2_token\n */\n async getClientToken(): Promise<SoundCloudToken> {\n // SC OAuth 2.1: client_credentials grant ONLY supports Basic Auth header.\n // Sending client_id/client_secret in the request body is no longer accepted\n // and will return 401 invalid_client.\n // See: https://developers.soundcloud.com/docs/api/guide#client-creds\n const credentials = Buffer.from(`${this.config.clientId}:${this.config.clientSecret}`).toString(\"base64\");\n return this.fetch<SoundCloudToken>({\n path: \"/oauth/token\",\n method: \"POST\",\n headers: { Authorization: `Basic ${credentials}` },\n body: new URLSearchParams({\n grant_type: \"client_credentials\",\n }),\n });\n }\n\n /**\n * Exchange an authorization code for user tokens (authorization_code grant).\n *\n * @param code - The authorization code received from the OAuth callback\n * @param codeVerifier - PKCE code verifier if a code challenge was used\n * @returns The OAuth token response including access and refresh tokens\n * @throws {SoundCloudError} When the code is invalid or expired\n *\n * @example\n * ```ts\n * const token = await sc.auth.getUserToken(code, codeVerifier);\n * sc.setToken(token.access_token, token.refresh_token);\n * ```\n *\n * @see https://developers.soundcloud.com/docs/api/explorer/open-api#/oauth2/post_oauth2_token\n */\n async getUserToken(code: string, codeVerifier?: string): Promise<SoundCloudToken> {\n const params: Record<string, string> = {\n grant_type: \"authorization_code\",\n client_id: this.config.clientId,\n client_secret: this.config.clientSecret,\n redirect_uri: this.config.redirectUri!,\n code,\n };\n if (codeVerifier) params.code_verifier = codeVerifier;\n return this.fetch<SoundCloudToken>({\n path: \"/oauth/token\",\n method: \"POST\",\n body: new URLSearchParams(params),\n });\n }\n\n /**\n * Refresh an expired access token using a refresh token.\n *\n * @param refreshToken - The refresh token from a previous token response\n * @returns A new OAuth token response with fresh access and refresh tokens\n * @throws {SoundCloudError} When the refresh token is invalid or expired\n *\n * @example\n * ```ts\n * const newToken = await sc.auth.refreshUserToken(sc.refreshToken!);\n * sc.setToken(newToken.access_token, newToken.refresh_token);\n * ```\n *\n * @see https://developers.soundcloud.com/docs/api/explorer/open-api#/oauth2/post_oauth2_token\n */\n async refreshUserToken(refreshToken: string): Promise<SoundCloudToken> {\n return this.fetch<SoundCloudToken>({\n path: \"/oauth/token\",\n method: \"POST\",\n body: new URLSearchParams({\n grant_type: \"refresh_token\",\n client_id: this.config.clientId,\n client_secret: this.config.clientSecret,\n redirect_uri: this.config.redirectUri!,\n refresh_token: refreshToken,\n }),\n });\n }\n\n /**\n * Invalidate the session associated with an access token.\n *\n * **Note:** This hits `https://secure.soundcloud.com`, NOT the regular\n * `api.soundcloud.com` host used by all other endpoints.\n *\n * @param accessToken - The access token to invalidate\n * @throws {Error} When the sign-out request fails\n *\n * @example\n * ```ts\n * await sc.auth.signOut(sc.accessToken!);\n * sc.clearToken();\n * ```\n */\n async signOut(accessToken: string): Promise<void> {\n const res = await fetch(\"https://secure.soundcloud.com/sign-out\", {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ access_token: accessToken }),\n });\n if (!res.ok) throw new Error(`Sign-out failed: ${res.status}`);\n }\n }\n\n /**\n * Authenticated user namespace — endpoints for the currently logged-in user (/me).\n *\n * @see https://developers.soundcloud.com/docs/api/explorer/open-api#/me\n */\n export class Me {\n constructor(private getToken: TokenGetter, private refreshCtx?: AutoRefreshContext) {}\n private fetch<T>(opts: Parameters<typeof scFetch>[0]) { return scFetch<T>(opts, this.refreshCtx); }\n\n /**\n * Get the authenticated user's profile.\n *\n * @param options - Optional token override\n * @returns The authenticated user's full profile\n * @throws {SoundCloudError} When the API returns an error\n *\n * @example\n * ```ts\n * const me = await sc.me.getMe();\n * console.log(me.username, me.followers_count);\n * ```\n *\n * @see https://developers.soundcloud.com/docs/api/explorer/open-api#/me/get_me\n */\n async getMe(options?: TokenOption): Promise<SoundCloudMe> {\n const t = resolveToken(this.getToken, options?.token);\n return this.fetch<SoundCloudMe>({ path: \"/me\", method: \"GET\", token: t });\n }\n\n /**\n * Get the authenticated user's activity feed.\n *\n * @param limit - Maximum number of activities per page\n * @param options - Optional token override\n * @returns Paginated activities response with `future_href` for polling\n * @throws {SoundCloudError} When the API returns an error\n *\n * @example\n * ```ts\n * const activities = await sc.me.getActivities(25);\n * activities.collection.forEach(a => console.log(a.type, a.created_at));\n * ```\n *\n * @see https://developers.soundcloud.com/docs/api/explorer/open-api#/me/get_me_activities\n */\n async getActivities(limit?: number, options?: TokenOption): Promise<SoundCloudActivitiesResponse> {\n const t = resolveToken(this.getToken, options?.token);\n return this.fetch({ path: `/me/activities?${limit ? `limit=${limit}&` : \"\"}linked_partitioning=true`, method: \"GET\", token: t });\n }\n\n /**\n * Get the authenticated user's own activities (uploads, reposts).\n *\n * @param limit - Maximum number of activities per page\n * @param options - Optional token override\n * @returns Paginated activities response\n * @throws {SoundCloudError} When the API returns an error\n *\n * @see https://developers.soundcloud.com/docs/api/explorer/open-api#/me/get_me_activities_all_own\n */\n async getActivitiesOwn(limit?: number, options?: TokenOption): Promise<SoundCloudActivitiesResponse> {\n const t = resolveToken(this.getToken, options?.token);\n return this.fetch({ path: `/me/activities/all/own?${limit ? `limit=${limit}&` : \"\"}linked_partitioning=true`, method: \"GET\", token: t });\n }\n\n /**\n * Get track-related activities in the authenticated user's feed.\n *\n * @param limit - Maximum number of activities per page\n * @param options - Optional token override\n * @returns Paginated activities response filtered to track activities\n * @throws {SoundCloudError} When the API returns an error\n *\n * @see https://developers.soundcloud.com/docs/api/explorer/open-api#/me/get_me_activities_tracks\n */\n async getActivitiesTracks(limit?: number, options?: TokenOption): Promise<SoundCloudActivitiesResponse> {\n const t = resolveToken(this.getToken, options?.token);\n return this.fetch({ path: `/me/activities/tracks?${limit ? `limit=${limit}&` : \"\"}linked_partitioning=true`, method: \"GET\", token: t });\n }\n\n /**\n * Get tracks liked by the authenticated user.\n *\n * @param limit - Maximum number of tracks per page\n * @param options - Optional token override\n * @returns Paginated list of liked tracks\n * @throws {SoundCloudError} When the API returns an error\n *\n * @example\n * ```ts\n * const likes = await sc.me.getLikesTracks(50);\n * likes.collection.forEach(t => console.log(t.title));\n * ```\n *\n * @see https://developers.soundcloud.com/docs/api/explorer/open-api#/me/get_me_likes_tracks\n */\n async getLikesTracks(limit?: number, options?: TokenOption): Promise<SoundCloudPaginatedResponse<SoundCloudTrack>> {\n const t = resolveToken(this.getToken, options?.token);\n return this.fetch({ path: `/me/likes/tracks?${limit ? `limit=${limit}&` : \"\"}linked_partitioning=true`, method: \"GET\", token: t });\n }\n\n /**\n * Get playlists liked by the authenticated user.\n *\n * @param limit - Maximum number of playlists per page\n * @param options - Optional token override\n * @returns Paginated list of liked playlists\n * @throws {SoundCloudError} When the API returns an error\n *\n * @see https://developers.soundcloud.com/docs/api/explorer/open-api#/me/get_me_likes_playlists\n */\n async getLikesPlaylists(limit?: number, options?: TokenOption): Promise<SoundCloudPaginatedResponse<SoundCloudPlaylist>> {\n const t = resolveToken(this.getToken, options?.token);\n return this.fetch({ path: `/me/likes/playlists?${limit ? `limit=${limit}&` : \"\"}linked_partitioning=true`, method: \"GET\", token: t });\n }\n\n /**\n * Get users the authenticated user is following.\n *\n * @param limit - Maximum number of users per page\n * @param options - Optional token override\n * @returns Paginated list of followed users\n * @throws {SoundCloudError} When the API returns an error\n *\n * @see https://developers.soundcloud.com/docs/api/explorer/open-api#/me/get_me_followings\n */\n async getFollowings(limit?: number, options?: TokenOption): Promise<SoundCloudPaginatedResponse<SoundCloudUser>> {\n const t = resolveToken(this.getToken, options?.token);\n return this.fetch({ path: `/me/followings?${limit ? `limit=${limit}&` : \"\"}linked_partitioning=true`, method: \"GET\", token: t });\n }\n\n /**\n * Get recent tracks from users the authenticated user is following.\n *\n * @param limit - Maximum number of tracks per page\n * @param options - Optional token override\n * @returns Paginated list of tracks from followed users\n * @throws {SoundCloudError} When the API returns an error\n *\n * @see https://developers.soundcloud.com/docs/api/explorer/open-api#/me/get_me_followings_tracks\n */\n async getFollowingsTracks(limit?: number, options?: TokenOption): Promise<SoundCloudPaginatedResponse<SoundCloudTrack>> {\n const t = resolveToken(this.getToken, options?.token);\n return this.fetch({ path: `/me/followings/tracks?${limit ? `limit=${limit}&` : \"\"}linked_partitioning=true`, method: \"GET\", token: t });\n }\n\n /**\n * Follow a user.\n *\n * @param userUrn - The user's ID or URN to follow\n * @param options - Optional token override\n * @throws {SoundCloudError} When the API returns an error\n *\n * @example\n * ```ts\n * await sc.me.follow(123456);\n * ```\n *\n * @see https://developers.soundcloud.com/docs/api/explorer/open-api#/me/put_me_followings__user_id_\n */\n async follow(userUrn: string | number, options?: TokenOption): Promise<void> {\n const t = resolveToken(this.getToken, options?.token);\n return this.fetch<void>({ path: `/me/followings/${userUrn}`, method: \"PUT\", token: t });\n }\n\n /**\n * Unfollow a user.\n *\n * @param userUrn - The user's ID or URN to unfollow\n * @param options - Optional token override\n * @throws {SoundCloudError} When the API returns an error\n *\n * @example\n * ```ts\n * await sc.me.unfollow(123456);\n * ```\n *\n * @see https://developers.soundcloud.com/docs/api/explorer/open-api#/me/delete_me_followings__user_id_\n */\n async unfollow(userUrn: string | number, options?: TokenOption): Promise<void> {\n const t = resolveToken(this.getToken, options?.token);\n return this.fetch<void>({ path: `/me/followings/${userUrn}`, method: \"DELETE\", token: t });\n }\n\n /**\n * Get the authenticated user's followers.\n *\n * @param limit - Maximum number of users per page\n * @param options - Optional token override\n * @returns Paginated list of follower users\n * @throws {SoundCloudError} When the API returns an error\n *\n * @see https://developers.soundcloud.com/docs/api/explorer/open-api#/me/get_me_followers\n */\n async getFollowers(limit?: number, options?: TokenOption): Promise<SoundCloudPaginatedResponse<SoundCloudUser>> {\n const t = resolveToken(this.getToken, options?.token);\n return this.fetch({ path: `/me/followers?${limit ? `limit=${limit}&` : \"\"}linked_partitioning=true`, method: \"GET\", token: t });\n }\n\n /**\n * Get the authenticated user's playlists.\n *\n * @param limit - Maximum number of playlists per page\n * @param options - Optional token override\n * @returns Paginated list of playlists\n * @throws {SoundCloudError} When the API returns an error\n *\n * @see https://developers.soundcloud.com/docs/api/explorer/open-api#/me/get_me_playlists\n */\n async getPlaylists(limit?: number, options?: TokenOption): Promise<SoundCloudPaginatedResponse<SoundCloudPlaylist>> {\n const t = resolveToken(this.getToken, options?.token);\n return this.fetch({ path: `/me/playlists?${limit ? `limit=${limit}&` : \"\"}linked_partitioning=true`, method: \"GET\", token: t });\n }\n\n /**\n * Get the authenticated user's tracks.\n *\n * @param limit - Maximum number of tracks per page\n * @param options - Optional token override\n * @returns Paginated list of tracks\n * @throws {SoundCloudError} When the API returns an error\n *\n * @see https://developers.soundcloud.com/docs/api/explorer/open-api#/me/get_me_tracks\n */\n async getTracks(limit?: number, options?: TokenOption): Promise<SoundCloudPaginatedResponse<SoundCloudTrack>> {\n const t = resolveToken(this.getToken, options?.token);\n return this.fetch({ path: `/me/tracks?${limit ? `limit=${limit}&` : \"\"}linked_partitioning=true`, method: \"GET\", token: t });\n }\n\n /**\n * List the authenticated user's connected external social accounts.\n *\n * @param options - Optional token override\n * @returns Array of connection objects for linked social services (Twitter, Facebook, etc.)\n * @throws {SoundCloudError} When the API returns an error\n *\n * @remarks This endpoint may require elevated API access or app approval.\n *\n * @example\n * ```ts\n * const connections = await sc.me.getConnections();\n * connections.forEach(c => console.log(c.service, c.display_name));\n * ```\n *\n * @see https://developers.soundcloud.com/docs/api/explorer/open-api#/me/get_me_connections\n */\n async getConnections(options?: TokenOption): Promise<SoundCloudConnection[]> {\n const t = resolveToken(this.getToken, options?.token);\n return this.fetch<SoundCloudConnection[]>({ path: \"/me/connections\", method: \"GET\", token: t });\n }\n }\n\n /**\n * User profile namespace — fetch public user data.\n *\n * @see https://developers.soundcloud.com/docs/api/explorer/open-api#/users\n */\n export class Users {\n constructor(private getToken: TokenGetter, private refreshCtx?: AutoRefreshContext) {}\n private fetch<T>(opts: Parameters<typeof scFetch>[0]) { return scFetch<T>(opts, this.refreshCtx); }\n\n /**\n * Get a user's profile by ID.\n *\n * @param userId - The user's numeric ID or URN\n * @param options - Optional token override\n * @returns The user's public profile\n * @throws {SoundCloudError} When the user is not found or the API returns an error\n *\n * @example\n * ```ts\n * const user = await sc.users.getUser(123456);\n * console.log(user.username, user.followers_count);\n * ```\n *\n * @see https://developers.soundcloud.com/docs/api/explorer/open-api#/users/get_users__user_id_\n */\n async getUser(userId: string | number, options?: TokenOption): Promise<SoundCloudUser> {\n const t = resolveToken(this.getToken, options?.token);\n return this.fetch<SoundCloudUser>({ path: `/users/${userId}`, method: \"GET\", token: t });\n }\n\n /**\n * Get a user's followers.\n *\n * @param userId - The user's numeric ID or URN\n * @param limit - Maximum number of followers per page\n * @param options - Optional token override\n * @returns Paginated list of follower users\n * @throws {SoundCloudError} When the API returns an error\n *\n * @see https://developers.soundcloud.com/docs/api/explorer/open-api#/users/get_users__user_id__followers\n */\n async getFollowers(userId: string | number, limit?: number, options?: TokenOption): Promise<SoundCloudPaginatedResponse<SoundCloudUser>> {\n const t = resolveToken(this.getToken, options?.token);\n return this.fetch({ path: `/users/${userId}/followers?${limit ? `limit=${limit}&` : \"\"}linked_partitioning=true`, method: \"GET\", token: t });\n }\n\n /**\n * Get users that a user is following.\n *\n * @param userId - The user's numeric ID or URN\n * @param limit - Maximum number of users per page\n * @param options - Optional token override\n * @returns Paginated list of followed users\n * @throws {SoundCloudError} When the API returns an error\n *\n * @see https://developers.soundcloud.com/docs/api/explorer/open-api#/users/get_users__user_id__followings\n */\n async getFollowings(userId: string | number, limit?: number, options?: TokenOption): Promise<SoundCloudPaginatedResponse<SoundCloudUser>> {\n const t = resolveToken(this.getToken, options?.token);\n return this.fetch({ path: `/users/${userId}/followings?${limit ? `limit=${limit}&` : \"\"}linked_partitioning=true`, method: \"GET\", token: t });\n }\n\n /**\n * Get a user's public tracks.\n *\n * @param userId - The user's numeric ID or URN\n * @param limit - Maximum number of tracks per page\n * @param options - Optional token override\n * @returns Paginated list of tracks\n * @throws {SoundCloudError} When the API returns an error\n *\n * @see https://developers.soundcloud.com/docs/api/explorer/open-api#/users/get_users__user_id__tracks\n */\n async getTracks(userId: string | number, limit?: number, options?: TokenOption): Promise<SoundCloudPaginatedResponse<SoundCloudTrack>> {\n const t = resolveToken(this.getToken, options?.token);\n return this.fetch({ path: `/users/${userId}/tracks?${limit ? `limit=${limit}&` : \"\"}linked_partitioning=true`, method: \"GET\", token: t });\n }\n\n /**\n * Get a user's public playlists.\n *\n * @param userId - The user's numeric ID or URN\n * @param limit - Maximum number of playlists per page\n * @param options - Optional token override\n * @returns Paginated list of playlists (without full track data)\n * @throws {SoundCloudError} When the API returns an error\n *\n * @see https://developers.soundcloud.com/docs/api/explorer/open-api#/users/get_users__user_id__playlists\n */\n async getPlaylists(userId: string | number, limit?: number, options?: TokenOption): Promise<SoundCloudPaginatedResponse<SoundCloudPlaylist>> {\n const t = resolveToken(this.getToken, options?.token);\n return this.fetch({ path: `/users/${userId}/playlists?${limit ? `limit=${limit}&` : \"\"}linked_partitioning=true&show_tracks=false`, method: \"GET\", token: t });\n }\n\n /**\n * Get tracks liked by a user.\n *\n * @param userId - The user's numeric ID or URN\n * @param limit - Maximum number of tracks per page\n * @param cursor - Pagination cursor from a previous response's `next_href`\n * @param options - Optional token override\n * @returns Paginated list of liked tracks\n * @throws {SoundCloudError} When the API returns an error\n *\n * @see https://developers.soundcloud.com/docs/api/explorer/open-api#/users/get_users__user_id__likes_tracks\n */\n async getLikesTracks(userId: string | number, limit?: number, cursor?: string, options?: TokenOption): Promise<SoundCloudPaginatedResponse<SoundCloudTrack>> {\n const t = resolveToken(this.getToken, options?.token);\n return this.fetch({ path: `/users/${userId}/likes/tracks?${limit ? `limit=${limit}&` : \"\"}${cursor ? `cursor=${cursor}&` : \"\"}linked_partitioning=true`, method: \"GET\", token: t });\n }\n\n /**\n * Get playlists liked by a user.\n *\n * @param userId - The user's numeric ID or URN\n * @param limit - Maximum number of playlists per page\n * @param options - Optional token override\n * @returns Paginated list of liked playlists\n * @throws {SoundCloudError} When the API returns an error\n *\n * @see https://developers.soundcloud.com/docs/api/explorer/open-api#/users/get_users__user_id__likes_playlists\n */\n async getLikesPlaylists(userId: string | number, limit?: number, options?: TokenOption): Promise<SoundCloudPaginatedResponse<SoundCloudPlaylist>> {\n const t = resolveToken(this.getToken, options?.token);\n return this.fetch({ path: `/users/${userId}/likes/playlists?${limit ? `limit=${limit}&` : \"\"}linked_partitioning=true`, method: \"GET\", token: t });\n }\n\n /**\n * Get a user's external web profile links (Twitter, Instagram, etc.).\n *\n * @param userId - The user's numeric ID or URN\n * @param options - Optional token override\n * @returns Array of web profile objects\n * @throws {SoundCloudError} When the API returns an error\n *\n * @example\n * ```ts\n * const profiles = await sc.users.getWebProfiles(123456);\n * profiles.forEach(p => console.log(p.service, p.url));\n * ```\n *\n * @see https://developers.soundcloud.com/docs/api/explorer/open-api#/users/get_users__user_id__web_profiles\n */\n async getWebProfiles(userId: string | number, options?: TokenOption): Promise<SoundCloudWebProfile[]> {\n const t = resolveToken(this.getToken, options?.token);\n return this.fetch<SoundCloudWebProfile[]>({ path: `/users/${userId}/web-profiles`, method: \"GET\", token: t });\n }\n }\n\n /**\n * Track namespace — fetch, update, delete tracks and their metadata.\n *\n * @see https://developers.soundcloud.com/docs/api/explorer/open-api#/tracks\n */\n export class Tracks {\n constructor(private getToken: TokenGetter, private refreshCtx?: AutoRefreshContext) {}\n private fetch<T>(opts: Parameters<typeof scFetch>[0]) { return scFetch<T>(opts, this.refreshCtx); }\n\n /**\n * Get a track by ID.\n *\n * @param trackId - The track's numeric ID or URN\n * @param options - Optional token override\n * @returns The track object with full metadata\n * @throws {SoundCloudError} When the track is not found or the API returns an error\n *\n * @example\n * ```ts\n * const track = await sc.tracks.getTrack(123456);\n * console.log(track.title, track.duration);\n * ```\n *\n * @see https://developers.soundcloud.com/docs/api/explorer/open-api#/tracks/get_tracks__track_id_\n */\n async getTrack(trackId: string | number, options?: TokenOption): Promise<SoundCloudTrack> {\n const t = resolveToken(this.getToken, options?.token);\n return this.fetch<SoundCloudTrack>({ path: `/tracks/${trackId}`, method: \"GET\", token: t });\n }\n\n /**\n * Fetch multiple tracks by their IDs in a single request.\n *\n * @param ids - Array of track IDs (numeric or string URNs)\n * @param options - Optional token override\n * @returns Array of track objects (may be shorter than `ids` if some tracks are unavailable)\n * @throws {SoundCloudError} When the API returns an error\n * @throws {Error} When more than 200 IDs are provided\n *\n * @remarks\n * SoundCloud's API likely caps at ~200 IDs per request. Passing more than 200 IDs\n * will throw immediately without making a network request.\n *\n * @example\n * ```ts\n * const tracks = await sc.tracks.getTracks([123456, 234567, 345678]);\n * tracks.forEach(t => console.log(t.title));\n * ```\n *\n * @see https://developers.soundcloud.com/docs/api/explorer/open-api#/tracks/get_tracks\n */\n async getTracks(ids: (string | number)[], options?: TokenOption): Promise<SoundCloudTrack[]> {\n if (ids.length > 200) {\n throw new Error(\"getTracks: SoundCloud API supports a maximum of 200 IDs per request\");\n }\n const t = resolveToken(this.getToken, options?.token);\n return this.fetch<SoundCloudTrack[]>({ path: `/tracks?ids=${ids.join(\",\")}`, method: \"GET\", token: t });\n }\n\n /**\n * Get stream URLs for a track.\n *\n * @param trackId - The track's numeric ID or URN\n * @param options - Optional token override\n * @returns Object containing available stream URLs (HLS, MP3, preview)\n * @throws {SoundCloudError} When the track is not found or not streamable\n *\n * @example\n * ```ts\n * const streams = await sc.tracks.getStreams(123456);\n * console.log(streams.hls_mp3_128_url);\n * ```\n *\n * @see https://developers.soundcloud.com/docs/api/explorer/open-api#/tracks/get_tracks__track_id__streams\n */\n async getStreams(trackId: string | number, options?: TokenOption): Promise<SoundCloudStreams> {\n const t = resolveToken(this.getToken, options?.token);\n return this.fetch<SoundCloudStreams>({ path: `/tracks/${trackId}/streams`, method: \"GET\", token: t });\n }\n\n /**\n * Get comments on a track.\n *\n * @param trackId - The track's numeric ID or URN\n * @param limit - Maximum number of comments per page\n * @param options - Optional token override\n * @returns Paginated list of comments\n * @throws {SoundCloudError} When the API returns an error\n *\n * @see https://developers.soundcloud.com/docs/api/explorer/open-api#/tracks/get_tracks__track_id__comments\n */\n async getComments(trackId: string | number, limit?: number, options?: TokenOption): Promise<SoundCloudPaginatedResponse<SoundCloudComment>> {\n const t = resolveToken(this.getToken, options?.token);\n return this.fetch({ path: `/tracks/${trackId}/comments?threaded=1&filter_replies=0${limit ? `&limit=${limit}` : \"\"}&linked_partitioning=true`, method: \"GET\", token: t });\n }\n\n /**\n * Post a comment on a track.\n *\n * @param trackId - The track's numeric ID or URN\n * @param body - The comment text\n * @param timestamp - Position in the track in milliseconds where the comment is placed\n * @param options - Optional token override\n * @returns The created comment object\n * @throws {SoundCloudError} When the API returns an error\n *\n * @example\n * ```ts\n * const comment = await sc.tracks.createComment(123456, 'Great track!', 30000);\n * console.log(comment.id);\n * ```\n *\n * @see https://developers.soundcloud.com/docs/api/explorer/open-api#/tracks/post_tracks__track_id__comments\n */\n async createComment(trackId: string | number, body: string, timestamp?: number, options?: TokenOption): Promise<SoundCloudComment> {\n const t = resolveToken(this.getToken, options?.token);\n return this.fetch<SoundCloudComment>({\n path: `/tracks/${trackId}/comments`,\n method: \"POST\",\n token: t,\n body: { comment: { body, ...(timestamp !== undefined ? { timestamp } : {}) } },\n });\n }\n\n /**\n * Get users who have liked (favorited) a track.\n *\n * @param trackId - The track's numeric ID or URN\n * @param limit - Maximum number of users per page\n * @param options - Optional token override\n * @returns Paginated list of users who liked the track\n * @throws {SoundCloudError} When the API returns an error\n *\n * @see https://developers.soundcloud.com/docs/api/explorer/open-api#/tracks/get_tracks__track_id__favoriters\n */\n async getLikes(trackId: string | number, limit?: number, options?: TokenOption): Promise<SoundCloudPaginatedResponse<SoundCloudUser>> {\n const t = resolveToken(this.getToken, options?.token);\n return this.fetch({ path: `/tracks/${trackId}/favoriters?${limit ? `limit=${limit}&` : \"\"}linked_partitioning=true`, method: \"GET\", token: t });\n }\n\n /**\n * Get users who have reposted a track.\n *\n * @param trackId - The track's numeric ID or URN\n * @param limit - Maximum number of users per page\n * @param options - Optional token override\n * @returns Paginated list of users who reposted the track\n * @throws {SoundCloudError} When the API returns an error\n *\n * @see https://developers.soundcloud.com/docs/api/explorer/open-api#/tracks/get_tracks__track_id__reposters\n */\n async getReposts(trackId: string | number, limit?: number, options?: TokenOption): Promise<SoundCloudPaginatedResponse<SoundCloudUser>> {\n const t = resolveToken(this.getToken, options?.token);\n return this.fetch({ path: `/tracks/${trackId}/reposters?${limit ? `limit=${limit}&` : \"\"}linked_partitioning=true`, method: \"GET\", token: t });\n }\n\n /**\n * Get tracks related to a given track.\n *\n * @param trackId - The track's numeric ID or URN\n * @param limit - Maximum number of related tracks to return\n * @param options - Optional token override\n * @returns Array of related tracks\n * @throws {SoundCloudError} When the API returns an error\n *\n * @example\n * ```ts\n * const related = await sc.tracks.getRelated(123456, 5);\n * related.forEach(t => console.log(t.title));\n * ```\n *\n * @see https://developers.soundcloud.com/docs/api/explorer/open-api#/tracks/get_tracks__track_id__related\n */\n async getRelated(trackId: string | number, limit?: number, options?: TokenOption): Promise<SoundCloudTrack[]> {\n const t = resolveToken(this.getToken, options?.token);\n return this.fetch<SoundCloudTrack[]>({ path: `/tracks/${trackId}/related${limit ? `?limit=${limit}` : \"\"}`, method: \"GET\", token: t });\n }\n\n /**\n * Update a track's metadata.\n *\n * @param trackId - The track's numeric ID or URN\n * @param params - Fields to update (title, description, genre, etc.)\n * @param options - Optional token override\n * @returns The updated track object\n * @throws {SoundCloudError} When the API returns an error\n *\n * @example\n * ```ts\n * const updated = await sc.tracks.update(123456, { title: 'New Title', genre: 'Electronic' });\n * console.log(updated.title);\n * ```\n *\n * @see https://developers.soundcloud.com/docs/api/explorer/open-api#/tracks/put_tracks__track_id_\n */\n async update(trackId: string | number, params: UpdateTrackParams, options?: TokenOption): Promise<SoundCloudTrack> {\n const t = resolveToken(this.getToken, options?.token);\n return this.fetch<SoundCloudTrack>({ path: `/tracks/${trackId}`, method: \"PUT\", token: t, body: { track: params } });\n }\n\n /**\n * Delete a track.\n *\n * @param trackId - The track's numeric ID or URN\n * @param options - Optional token override\n * @throws {SoundCloudError} When the API returns an error\n *\n * @example\n * ```ts\n * await sc.tracks.delete(123456);\n * ```\n *\n * @see https://developers.soundcloud.com/docs/api/explorer/open-api#/tracks/delete_tracks__track_id_\n */\n async delete(trackId: string | number, options?: TokenOption): Promise<void> {\n const t = resolveToken(this.getToken, options?.token);\n return this.fetch<void>({ path: `/tracks/${trackId}`, method: \"DELETE\", token: t });\n }\n }\n\n /**\n * Playlist namespace — fetch, create, update, and delete playlists.\n *\n * @see https://developers.soundcloud.com/docs/api/explorer/open-api#/playlists\n */\n export class Playlists {\n constructor(private getToken: TokenGetter, private refreshCtx?: AutoRefreshContext) {}\n private fetch<T>(opts: Parameters<typeof scFetch>[0]) { return scFetch<T>(opts, this.refreshCtx); }\n\n /**\n * Get a playlist by ID.\n *\n * @param playlistId - The playlist's numeric ID or URN\n * @param options - Optional token override\n * @returns The playlist object with track data\n * @throws {SoundCloudError} When the playlist is not found or the API returns an error\n *\n * @example\n * ```ts\n * const playlist = await sc.playlists.getPlaylist(123456);\n * console.log(playlist.title, playlist.track_count);\n * ```\n *\n * @see https://developers.soundcloud.com/docs/api/explorer/open-api#/playlists/get_playlists__playlist_id_\n */\n async getPlaylist(playlistId: string | number, options?: TokenOption): Promise<SoundCloudPlaylist> {\n const t = resolveToken(this.getToken, options?.token);\n return this.fetch<SoundCloudPlaylist>({ path: `/playlists/${playlistId}`, method: \"GET\", token: t });\n }\n\n /**\n * Get tracks in a playlist.\n *\n * @param playlistId - The playlist's numeric ID or URN\n * @param limit - Maximum number of tracks per page\n * @param offset - Number of tracks to skip (for offset-based pagination)\n * @param options - Optional token override\n * @returns Paginated list of tracks\n * @throws {SoundCloudError} When the API returns an error\n *\n * @see https://developers.soundcloud.com/docs/api/explorer/open-api#/playlists/get_playlists__playlist_id__tracks\n */\n async getTracks(playlistId: string | number, limit?: number, offset?: number, options?: TokenOption): Promise<SoundCloudPaginatedResponse<SoundCloudTrack>> {\n const t = resolveToken(this.getToken, options?.token);\n return this.fetch({ path: `/playlists/${playlistId}/tracks?${limit ? `limit=${limit}&` : \"\"}linked_partitioning=true${offset ? `&offset=${offset}` : \"\"}`, method: \"GET\", token: t });\n }\n\n /**\n * Get users who have reposted a playlist.\n *\n * @param playlistId - The playlist's numeric ID or URN\n * @param limit - Maximum number of users per page\n * @param options - Optional token override\n * @returns Paginated list of users who reposted the playlist\n * @throws {SoundCloudError} When the API returns an error\n *\n * @see https://developers.soundcloud.com/docs/api/explorer/open-api#/playlists/get_playlists__playlist_id__reposters\n */\n async getReposts(playlistId: string | number, limit?: number, options?: TokenOption): Promise<SoundCloudPaginatedResponse<SoundCloudUser>> {\n const t = resolveToken(this.getToken, options?.token);\n return this.fetch({ path: `/playlists/${playlistId}/reposters?${limit ? `limit=${limit}&` : \"\"}linked_partitioning=true`, method: \"GET\", token: t });\n }\n\n /**\n * Create a new playlist.\n *\n * @param params - Playlist creation parameters (title is required)\n * @param options - Optional token override\n * @returns The created playlist object\n * @throws {SoundCloudError} When the API returns an error\n *\n * @example\n * ```ts\n * const playlist = await sc.playlists.create({\n * title: 'My Favorites',\n * sharing: 'public',\n * tracks: [{ urn: 'soundcloud:tracks:123' }],\n * });\n * ```\n *\n * @see https://developers.soundcloud.com/docs/api/explorer/open-api#/playlists/post_playlists\n */\n async create(params: CreatePlaylistParams, options?: TokenOption): Promise<SoundCloudPlaylist> {\n const t = resolveToken(this.getToken, options?.token);\n return this.fetch<SoundCloudPlaylist>({ path: \"/playlists\", method: \"POST\", token: t, body: { playlist: params } });\n }\n\n /**\n * Update a playlist's metadata or track list.\n *\n * @param playlistId - The playlist's numeric ID or URN\n * @param params - Fields to update\n * @param options - Optional token override\n * @returns The updated playlist object\n * @throws {SoundCloudError} When the API returns an error\n *\n * @example\n * ```ts\n * const updated = await sc.playlists.update(123456, { title: 'Updated Title' });\n * ```\n *\n * @see https://developers.soundcloud.com/docs/api/explorer/open-api#/playlists/put_playlists__playlist_id_\n */\n async update(playlistId: string | number, params: UpdatePlaylistParams, options?: TokenOption): Promise<SoundCloudPlaylist> {\n const t = resolveToken(this.getToken, options?.token);\n return this.fetch<SoundCloudPlaylist>({ path: `/playlists/${playlistId}`, method: \"PUT\", token: t, body: { playlist: params } });\n }\n\n /**\n * Delete a playlist.\n *\n * @param playlistId - The playlist's numeric ID or URN\n * @param options - Optional token override\n * @throws {SoundCloudError} When the API returns an error\n *\n * @example\n * ```ts\n * await sc.playlists.delete(123456);\n * ```\n *\n * @see https://developers.soundcloud.com/docs/api/explorer/open-api#/playlists/delete_playlists__playlist_id_\n */\n async delete(playlistId: string | number, options?: TokenOption): Promise<void> {\n const t = resolveToken(this.getToken, options?.token);\n return this.fetch<void>({ path: `/playlists/${playlistId}`, method: \"DELETE\", token: t });\n }\n }\n\n /**\n * Search namespace — search for tracks, users, and playlists.\n *\n * @see https://developers.soundcloud.com/docs/api/explorer/open-api#/search\n */\n export class Search {\n constructor(private getToken: TokenGetter, private refreshCtx?: AutoRefreshContext) {}\n private fetch<T>(opts: Parameters<typeof scFetch>[0]) { return scFetch<T>(opts, this.refreshCtx); }\n\n /**\n * Search for tracks by query string.\n *\n * @param query - Search query text\n * @param pageNumber - Zero-based page number (10 results per page)\n * @param options - Optional token override\n * @returns Paginated list of matching tracks\n * @throws {SoundCloudError} When the API returns an error\n *\n * @example\n * ```ts\n * const results = await sc.search.tracks('lofi hip hop');\n * results.collection.forEach(t => console.log(t.title));\n * ```\n *\n * @see https://developers.soundcloud.com/docs/api/explorer/open-api#/tracks/get_tracks\n */\n async tracks(query: string, pageNumber?: number, options?: TokenOption): Promise<SoundCloudPaginatedResponse<SoundCloudTrack>> {\n const t = resolveToken(this.getToken, options?.token);\n return this.fetch({ path: `/tracks?q=${encodeURIComponent(query)}&linked_partitioning=true&limit=10${pageNumber && pageNumber > 0 ? `&offset=${10 * pageNumber}` : \"\"}`, method: \"GET\", token: t });\n }\n\n /**\n * Search for users by query string.\n *\n * @param query - Search query text\n * @param pageNumber - Zero-based page number (10 results per page)\n * @param options - Optional token override\n * @returns Paginated list of matching users\n * @throws {SoundCloudError} When the API returns an error\n *\n * @example\n * ```ts\n * const results = await sc.search.users('deadmau5');\n * results.collection.forEach(u => console.log(u.username));\n * ```\n *\n * @see https://developers.soundcloud.com/docs/api/explorer/open-api#/users/get_users\n */\n async users(query: string, pageNumber?: number, options?: TokenOption): Promise<SoundCloudPaginatedResponse<SoundCloudUser>> {\n const t = resolveToken(this.getToken, options?.token);\n return this.fetch({ path: `/users?q=${encodeURIComponent(query)}&linked_partitioning=true&limit=10${pageNumber && pageNumber > 0 ? `&offset=${10 * pageNumber}` : \"\"}`, method: \"GET\", token: t });\n }\n\n /**\n * Search for playlists by query string.\n *\n * @param query - Search query text\n * @param pageNumber - Zero-based page number (10 results per page)\n * @param options - Optional token override\n * @returns Paginated list of matching playlists\n * @throws {SoundCloudError} When the API returns an error\n *\n * @example\n * ```ts\n * const results = await sc.search.playlists('chill vibes');\n * results.collection.forEach(p => console.log(p.title));\n * ```\n *\n * @see https://developers.soundcloud.com/docs/api/explorer/open-api#/playlists/get_playlists\n */\n async playlists(query: string, pageNumber?: number, options?: TokenOption): Promise<SoundCloudPaginatedResponse<SoundCloudPlaylist>> {\n const t = resolveToken(this.getToken, options?.token);\n return this.fetch({ path: `/playlists?q=${encodeURIComponent(query)}&linked_partitioning=true&limit=10${pageNumber && pageNumber > 0 ? `&offset=${10 * pageNumber}` : \"\"}`, method: \"GET\", token: t });\n }\n }\n\n /**\n * Resolve namespace — resolve SoundCloud URLs to API resources.\n *\n * @see https://developers.soundcloud.com/docs/api/explorer/open-api#/resolve\n */\n export class Resolve {\n constructor(private getToken: TokenGetter, private refreshCtx?: AutoRefreshContext) {}\n private fetch<T>(opts: Parameters<typeof scFetch>[0]) { return scFetch<T>(opts, this.refreshCtx); }\n\n /**\n * Resolve a SoundCloud URL to its API resource URL.\n *\n * @param url - A SoundCloud URL (e.g. \"https://soundcloud.com/artist/track-name\")\n * @param options - Optional token override\n * @returns The resolved API resource URL (via 302 redirect)\n * @throws {SoundCloudError} When the URL cannot be resolved\n *\n * @example\n * ```ts\n * const apiUrl = await sc.resolve.resolveUrl('https://soundcloud.com/deadmau5/strobe');\n * console.log(apiUrl); // \"https://api.soundcloud.com/tracks/...\"\n * ```\n *\n * @see https://developers.soundcloud.com/docs/api/explorer/open-api#/resolve/get_resolve\n */\n async resolveUrl(url: string, options?: TokenOption): Promise<string> {\n const t = resolveToken(this.getToken, options?.token);\n return this.fetch<string>({ path: `/resolve?url=${encodeURIComponent(url)}`, method: \"GET\", token: t });\n }\n }\n\n /**\n * Likes namespace — like and unlike tracks and playlists.\n *\n * @see https://developers.soundcloud.com/docs/api/explorer/open-api#/likes\n */\n export class Likes {\n constructor(private getToken: TokenGetter, private refreshCtx?: AutoRefreshContext) {}\n private fetch<T>(opts: Parameters<typeof scFetch>[0]) { return scFetch<T>(opts, this.refreshCtx); }\n\n /**\n * Like a track.\n *\n * @param trackId - The track's numeric ID or URN\n * @param options - Optional token override\n * @returns `true` if the like was successful, `false` on failure\n *\n * @example\n * ```ts\n * const success = await sc.likes.likeTrack(123456);\n * ```\n *\n * @see https://developers.soundcloud.com/docs/api/explorer/open-api#/likes/post_likes_tracks__track_id_\n */\n async likeTrack(trackId: string | number, options?: TokenOption): Promise<boolean> {\n const t = resolveToken(this.getToken, options?.token);\n try { await this.fetch<unknown>({ path: `/likes/tracks/${trackId}`, method: \"POST\", token: t }); return true; } catch { return false; }\n }\n\n /**\n * Unlike a track.\n *\n * @param trackId - The track's numeric ID or URN\n * @param options - Optional token override\n * @returns `true` if the unlike was successful, `false` on failure\n *\n * @see https://developers.soundcloud.com/docs/api/explorer/open-api#/likes/delete_likes_tracks__track_id_\n */\n async unlikeTrack(trackId: string | number, options?: TokenOption): Promise<boolean> {\n const t = resolveToken(this.getToken, options?.token);\n try { await this.fetch<unknown>({ path: `/likes/tracks/${trackId}`, method: \"DELETE\", token: t }); return true; } catch { return false; }\n }\n\n /**\n * Like a playlist.\n *\n * @param playlistId - The playlist's numeric ID or URN\n * @param options - Optional token override\n * @returns `true` if the like was successful, `false` on failure\n *\n * @see https://developers.soundcloud.com/docs/api/explorer/open-api#/likes/post_likes_playlists__playlist_id_\n */\n async likePlaylist(playlistId: string | number, options?: TokenOption): Promise<boolean> {\n const t = resolveToken(this.getToken, options?.token);\n try { await this.fetch<unknown>({ path: `/likes/playlists/${playlistId}`, method: \"POST\", token: t }); return true; } catch { return false; }\n }\n\n /**\n * Unlike a playlist.\n *\n * @param playlistId - The playlist's numeric ID or URN\n * @param options - Optional token override\n * @returns `true` if the unlike was successful, `false` on failure\n *\n * @see https://developers.soundcloud.com/docs/api/explorer/open-api#/likes/delete_likes_playlists__playlist_id_\n */\n async unlikePlaylist(playlistId: string | number, options?: TokenOption): Promise<boolean> {\n const t = resolveToken(this.getToken, options?.token);\n try { await this.fetch<unknown>({ path: `/likes/playlists/${playlistId}`, method: \"DELETE\", token: t }); return true; } catch { return false; }\n }\n }\n\n /**\n * Reposts namespace — repost and unrepost tracks and playlists.\n *\n * @see https://developers.soundcloud.com/docs/api/explorer/open-api#/reposts\n */\n export class Reposts {\n constructor(private getToken: TokenGetter, private refreshCtx?: AutoRefreshContext) {}\n private fetch<T>(opts: Parameters<typeof scFetch>[0]) { return scFetch<T>(opts, this.refreshCtx); }\n\n /**\n * Repost a track to your profile.\n *\n * @param trackId - The track's numeric ID or URN\n * @param options - Optional token override\n * @returns `true` if the repost was successful, `false` on failure\n *\n * @example\n * ```ts\n * const success = await sc.reposts.repostTrack(123456);\n * ```\n *\n * @see https://developers.soundcloud.com/docs/api/explorer/open-api#/reposts/post_reposts_tracks__track_id_\n */\n async repostTrack(trackId: string | number, options?: TokenOption): Promise<boolean> {\n const t = resolveToken(this.getToken, options?.token);\n try { await this.fetch<unknown>({ path: `/reposts/tracks/${trackId}`, method: \"POST\", token: t }); return true; } catch { return false; }\n }\n\n /**\n * Remove a track repost from your profile.\n *\n * @param trackId - The track's numeric ID or URN\n * @param options - Optional token override\n * @returns `true` if the unrepost was successful, `false` on failure\n *\n * @see https://developers.soundcloud.com/docs/api/explorer/open-api#/reposts/delete_reposts_tracks__track_id_\n */\n async unrepostTrack(trackId: string | number, options?: TokenOption): Promise<boolean> {\n const t = resolveToken(this.getToken, options?.token);\n try { await this.fetch<unknown>({ path: `/reposts/tracks/${trackId}`, method: \"DELETE\", token: t }); return true; } catch { return false; }\n }\n\n /**\n * Repost a playlist to your profile.\n *\n * @param playlistId - The playlist's numeric ID or URN\n * @param options - Optional token override\n * @returns `true` if the repost was successful, `false` on failure\n *\n * @see https://developers.soundcloud.com/docs/api/explorer/open-api#/reposts/post_reposts_playlists__playlist_id_\n */\n async repostPlaylist(playlistId: string | number, options?: TokenOption): Promise<boolean> {\n const t = resolveToken(this.getToken, options?.token);\n try { await this.fetch<unknown>({ path: `/reposts/playlists/${playlistId}`, method: \"POST\", token: t }); return true; } catch { return false; }\n }\n\n /**\n * Remove a playlist repost from your profile.\n *\n * @param playlistId - The playlist's numeric ID or URN\n * @param options - Optional token override\n * @returns `true` if the unrepost was successful, `false` on failure\n *\n * @see https://developers.soundcloud.com/docs/api/explorer/open-api#/reposts/delete_reposts_playlists__playlist_id_\n */\n async unrepostPlaylist(playlistId: string | number, options?: TokenOption): Promise<boolean> {\n const t = resolveToken(this.getToken, options?.token);\n try { await this.fetch<unknown>({ path: `/reposts/playlists/${playlistId}`, method: \"DELETE\", token: t }); return true; } catch { return false; }\n }\n }\n}\n","/**\n * Deduplicates concurrent in-flight requests with the same key.\n *\n * When multiple callers request the same resource simultaneously,\n * only one underlying promise is created — all callers share the result.\n * The key is cleaned up automatically once the promise settles.\n *\n * @example\n * ```ts\n * const deduper = new InFlightDeduper();\n *\n * // Both calls share a single fetch:\n * const [a, b] = await Promise.all([\n * deduper.add('track:123', () => fetchTrack(123)),\n * deduper.add('track:123', () => fetchTrack(123)),\n * ]);\n * // a === b (same resolved value)\n * ```\n */\nexport class InFlightDeduper {\n private inFlight = new Map<string, Promise<unknown>>();\n\n /**\n * Return an existing in-flight promise for `key`, or start a new one via `factory`.\n * The entry is removed from the map once the promise settles (resolve or reject).\n */\n add<T>(key: string, factory: () => Promise<T>): Promise<T> {\n const existing = this.inFlight.get(key);\n if (existing) return existing as Promise<T>;\n\n const promise = factory().finally(() => {\n this.inFlight.delete(key);\n });\n\n this.inFlight.set(key, promise);\n return promise;\n }\n\n /** Number of currently in-flight requests */\n get size(): number {\n return this.inFlight.size;\n }\n}\n","/**\n * List of operation IDs currently implemented by soundcloud-api-ts.\n * Used for OpenAPI coverage reporting.\n */\nexport const IMPLEMENTED_OPERATIONS: string[] = [\n // Auth\n \"post_oauth2_token\",\n \"delete_oauth2_token\",\n\n // Me\n \"get_me\",\n \"get_me_activities\",\n \"get_me_activities_own\",\n \"get_me_activities_tracks\",\n \"get_me_likes_tracks\",\n \"get_me_likes_playlists\",\n \"get_me_followings\",\n \"get_me_followings_tracks\",\n \"post_me_followings_user_id\",\n \"delete_me_followings_user_id\",\n \"get_me_followers\",\n \"get_me_playlists\",\n \"get_me_tracks\",\n \"get_me_connections\",\n\n // Users\n \"get_users_user_id\",\n \"get_users_user_id_followers\",\n \"get_users_user_id_followings\",\n \"get_users_user_id_tracks\",\n \"get_users_user_id_playlists\",\n \"get_users_user_id_likes_tracks\",\n \"get_users_user_id_likes_playlists\",\n \"get_users_user_id_web_profiles\",\n\n // Tracks\n \"get_tracks_track_id\",\n \"put_tracks_track_id\",\n \"delete_tracks_track_id\",\n \"get_tracks_track_id_comments\",\n \"post_tracks_track_id_comments\",\n \"get_tracks_track_id_likes\",\n \"get_tracks_track_id_reposts\",\n \"get_tracks_track_id_related\",\n \"get_tracks_track_id_streams\",\n \"post_likes_tracks_track_id\",\n \"delete_likes_tracks_track_id\",\n \"post_reposts_tracks_track_id\",\n \"delete_reposts_tracks_track_id\",\n\n // Playlists\n \"get_playlists_playlist_id\",\n \"post_playlists\",\n \"put_playlists_playlist_id\",\n \"delete_playlists_playlist_id\",\n \"get_playlists_playlist_id_tracks\",\n \"get_playlists_playlist_id_reposts\",\n \"post_likes_playlists_playlist_id\",\n \"delete_likes_playlists_playlist_id\",\n \"post_reposts_playlists_playlist_id\",\n \"delete_reposts_playlists_playlist_id\",\n\n // Search\n \"get_tracks\",\n \"get_users\",\n \"get_playlists\",\n\n // Resolve\n \"get_resolve\",\n];\n","import { scFetch } from \"../client/http.js\";\nimport type { SoundCloudToken } from \"../types/api.js\";\n\n/**\n * Exchange client credentials for an access token (client_credentials grant).\n *\n * This is a standalone function alternative to {@link SoundCloudClient.Auth.getClientToken}.\n *\n * @param clientId - Your SoundCloud application's OAuth client ID\n * @param clientSecret - Your SoundCloud application's OAuth client secret\n * @returns The OAuth token response\n * @throws {SoundCloudError} When authentication fails (e.g. invalid credentials)\n *\n * @example\n * ```ts\n * import { getClientToken } from 'soundcloud-api-ts';\n *\n * const token = await getClientToken('YOUR_CLIENT_ID', 'YOUR_CLIENT_SECRET');\n * console.log(token.access_token);\n * ```\n *\n * @see https://developers.soundcloud.com/docs/api/explorer/open-api#/oauth2/post_oauth2_token\n */\nexport const getClientToken = (clientId: string, clientSecret: string): Promise<SoundCloudToken> => {\n return scFetch<SoundCloudToken>({\n path: \"/oauth/token\",\n method: \"POST\",\n body: new URLSearchParams({\n grant_type: \"client_credentials\",\n client_id: clientId,\n client_secret: clientSecret,\n }),\n });\n};\n","import { scFetch } from \"../client/http.js\";\nimport type { SoundCloudToken } from \"../types/api.js\";\n\n/**\n * Exchange an authorization code for user tokens (authorization_code grant).\n *\n * This is a standalone function alternative to {@link SoundCloudClient.Auth.getUserToken}.\n *\n * @param clientId - Your SoundCloud application's OAuth client ID\n * @param clientSecret - Your SoundCloud application's OAuth client secret\n * @param redirectUri - The redirect URI registered with your SoundCloud application\n * @param code - The authorization code received from the OAuth callback\n * @param codeVerifier - PKCE code verifier if a code challenge was used during authorization\n * @returns The OAuth token response including access and refresh tokens\n * @throws {SoundCloudError} When the code is invalid, expired, or credentials are wrong\n *\n * @example\n * ```ts\n * import { getUserToken } from 'soundcloud-api-ts';\n *\n * const token = await getUserToken(\n * 'YOUR_CLIENT_ID',\n * 'YOUR_CLIENT_SECRET',\n * 'https://example.com/callback',\n * authorizationCode,\n * codeVerifier, // optional, for PKCE\n * );\n * console.log(token.access_token, token.refresh_token);\n * ```\n *\n * @see https://developers.soundcloud.com/docs/api/explorer/open-api#/oauth2/post_oauth2_token\n */\nexport const getUserToken = (\n clientId: string,\n clientSecret: string,\n redirectUri: string,\n code: string,\n codeVerifier?: string,\n): Promise<SoundCloudToken> => {\n const params: Record<string, string> = {\n grant_type: \"authorization_code\",\n client_id: clientId,\n client_secret: clientSecret,\n redirect_uri: redirectUri,\n code,\n };\n if (codeVerifier) params.code_verifier = codeVerifier;\n return scFetch<SoundCloudToken>({\n path: \"/oauth/token\",\n method: \"POST\",\n body: new URLSearchParams(params),\n });\n};\n","import { scFetch } from \"../client/http.js\";\nimport type { SoundCloudToken } from \"../types/api.js\";\n\n/**\n * Refresh an expired access token using a refresh token (refresh_token grant).\n *\n * This is a standalone function alternative to {@link SoundCloudClient.Auth.refreshUserToken}.\n *\n * @param clientId - Your SoundCloud application's OAuth client ID\n * @param clientSecret - Your SoundCloud application's OAuth client secret\n * @param redirectUri - The redirect URI registered with your SoundCloud application\n * @param refreshToken - The refresh token from a previous token response\n * @returns A new OAuth token response with fresh access and refresh tokens\n * @throws {SoundCloudError} When the refresh token is invalid or expired\n *\n * @example\n * ```ts\n * import { refreshUserToken } from 'soundcloud-api-ts';\n *\n * const newToken = await refreshUserToken(\n * 'YOUR_CLIENT_ID',\n * 'YOUR_CLIENT_SECRET',\n * 'https://example.com/callback',\n * oldRefreshToken,\n * );\n * console.log(newToken.access_token);\n * ```\n *\n * @see https://developers.soundcloud.com/docs/api/explorer/open-api#/oauth2/post_oauth2_token\n */\nexport const refreshUserToken = (\n clientId: string,\n clientSecret: string,\n redirectUri: string,\n refreshToken: string,\n): Promise<SoundCloudToken> => {\n return scFetch<SoundCloudToken>({\n path: \"/oauth/token\",\n method: \"POST\",\n body: new URLSearchParams({\n grant_type: \"refresh_token\",\n client_id: clientId,\n client_secret: clientSecret,\n redirect_uri: redirectUri,\n refresh_token: refreshToken,\n }),\n });\n};\n","/**\n * Invalidate the session associated with an access token.\n *\n * **Note:** This hits `https://secure.soundcloud.com`, NOT the regular\n * `api.soundcloud.com` host used by all other endpoints.\n *\n * @param accessToken - The OAuth access token to invalidate\n * @throws {Error} When the sign-out request fails\n *\n * @example\n * ```ts\n * import { signOut } from 'soundcloud-api-ts';\n *\n * await signOut('your-access-token');\n * ```\n */\nexport const signOut = async (accessToken: string): Promise<void> => {\n const res = await fetch(\"https://secure.soundcloud.com/sign-out\", {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ access_token: accessToken }),\n });\n if (!res.ok) throw new Error(`Sign-out failed: ${res.status}`);\n};\n","/**\n * Build the SoundCloud authorization URL for the OAuth 2.1 code flow.\n *\n * Redirect the user to this URL so they can grant access to your application.\n *\n * @param clientId - Your SoundCloud application's OAuth client ID\n * @param redirectUri - The redirect URI registered with your SoundCloud application\n * @param options - Optional parameters for the authorization request\n * @param options.state - Opaque state value for CSRF protection (round-tripped by SoundCloud)\n * @param options.codeChallenge - PKCE S256 code challenge for enhanced security\n * @returns The full authorization URL to redirect the user to\n *\n * @example\n * ```ts\n * import { getAuthorizationUrl, generateCodeVerifier, generateCodeChallenge } from 'soundcloud-api-ts';\n *\n * const verifier = generateCodeVerifier();\n * const challenge = await generateCodeChallenge(verifier);\n * const url = getAuthorizationUrl('YOUR_CLIENT_ID', 'https://example.com/callback', {\n * state: 'random-csrf-token',\n * codeChallenge: challenge,\n * });\n * // Redirect user to `url`\n * ```\n *\n * @see https://developers.soundcloud.com/docs/api/explorer/open-api#/oauth2\n */\nexport function getAuthorizationUrl(\n clientId: string,\n redirectUri: string,\n options?: { state?: string; codeChallenge?: string },\n): string {\n const params = new URLSearchParams({\n client_id: clientId,\n redirect_uri: redirectUri,\n response_type: \"code\",\n });\n if (options?.state) params.set(\"state\", options.state);\n if (options?.codeChallenge) {\n params.set(\"code_challenge\", options.codeChallenge);\n params.set(\"code_challenge_method\", \"S256\");\n }\n return `https://secure.soundcloud.com/authorize?${params}`;\n}\n","/**\n * Generate a random PKCE code verifier (43+ characters, base64url-encoded).\n *\n * Uses the Web Crypto API (`globalThis.crypto`), compatible with Node 20+ and modern browsers.\n *\n * @returns A cryptographically random code verifier string\n *\n * @example\n * ```ts\n * import { generateCodeVerifier, generateCodeChallenge } from 'soundcloud-api-ts';\n *\n * const verifier = generateCodeVerifier();\n * const challenge = await generateCodeChallenge(verifier);\n * // Use `challenge` in getAuthorizationUrl, then `verifier` in getUserToken\n * ```\n *\n * @see https://datatracker.ietf.org/doc/html/rfc7636\n */\nexport function generateCodeVerifier(): string {\n const bytes = new Uint8Array(32);\n globalThis.crypto.getRandomValues(bytes);\n return base64url(bytes);\n}\n\n/**\n * Derive the S256 PKCE code challenge from a code verifier.\n *\n * Computes `BASE64URL(SHA256(verifier))` using the Web Crypto API (SubtleCrypto),\n * available in Node 20+ and modern browsers.\n *\n * @param verifier - The code verifier string (typically from {@link generateCodeVerifier})\n * @returns The base64url-encoded SHA-256 hash of the verifier\n *\n * @example\n * ```ts\n * import { generateCodeVerifier, generateCodeChallenge } from 'soundcloud-api-ts';\n *\n * const verifier = generateCodeVerifier();\n * const challenge = await generateCodeChallenge(verifier);\n * console.log(challenge); // e.g. \"dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk\"\n * ```\n *\n * @see https://datatracker.ietf.org/doc/html/rfc7636#section-4.2\n */\nexport async function generateCodeChallenge(verifier: string): Promise<string> {\n const data = new TextEncoder().encode(verifier);\n const digest = await globalThis.crypto.subtle.digest(\"SHA-256\", data);\n return base64url(new Uint8Array(digest));\n}\n\nfunction base64url(bytes: Uint8Array): string {\n let binary = \"\";\n for (const b of bytes) binary += String.fromCharCode(b);\n return btoa(binary).replace(/\\+/g, \"-\").replace(/\\//g, \"_\").replace(/=+$/, \"\");\n}\n","import { scFetch } from \"../client/http.js\";\nimport type { SoundCloudMe } from \"../types/api.js\";\n\n/**\n * Fetch the authenticated user's profile.\n *\n * @param token - OAuth access token\n * @returns The authenticated user's full profile including private account details\n * @throws {SoundCloudError} When the token is invalid or the API returns an error\n *\n * @example\n * ```ts\n * import { getMe } from 'soundcloud-api-ts';\n *\n * const me = await getMe(token);\n * console.log(me.username, me.private_tracks_count);\n * ```\n *\n * @see https://developers.soundcloud.com/docs/api/explorer/open-api#/me/get_me\n */\nexport const getMe = (token: string): Promise<SoundCloudMe> =>\n scFetch<SoundCloudMe>({ path: \"/me\", method: \"GET\", token });\n","import { scFetch } from \"../client/http.js\";\nimport type { SoundCloudUser } from \"../types/api.js\";\n\n/**\n * Fetch a user's public profile by ID.\n *\n * @param token - OAuth access token\n * @param userId - The user's numeric ID or URN\n * @returns The user's public profile\n * @throws {SoundCloudError} When the user is not found or the API returns an error\n *\n * @example\n * ```ts\n * import { getUser } from 'soundcloud-api-ts';\n *\n * const user = await getUser(token, 123456);\n * console.log(user.username);\n * ```\n *\n * @see https://developers.soundcloud.com/docs/api/explorer/open-api#/users/get_users__user_id_\n */\nexport const getUser = (token: string, userId: string | number): Promise<SoundCloudUser> =>\n scFetch<SoundCloudUser>({ path: `/users/${userId}`, method: \"GET\", token });\n","import { scFetch } from \"../client/http.js\";\nimport type { SoundCloudUser, SoundCloudPaginatedResponse } from \"../types/api.js\";\n\n/**\n * Fetch a user's followers.\n *\n * @param token - OAuth access token\n * @param userId - The user's numeric ID or URN\n * @param limit - Maximum number of followers per page\n * @returns Paginated list of follower users\n * @throws {SoundCloudError} When the API returns an error\n *\n * @example\n * ```ts\n * import { getFollowers } from 'soundcloud-api-ts';\n *\n * const result = await getFollowers(token, 123456, 50);\n * result.collection.forEach(u => console.log(u.username));\n * ```\n *\n * @see https://developers.soundcloud.com/docs/api/explorer/open-api#/users/get_users__user_id__followers\n */\nexport const getFollowers = (token: string, userId: string | number, limit?: number): Promise<SoundCloudPaginatedResponse<SoundCloudUser>> =>\n scFetch({ path: `/users/${userId}/followers?${limit ? `limit=${limit}&` : \"\"}linked_partitioning=true`, method: \"GET\", token });\n","import { scFetch } from \"../client/http.js\";\nimport type { SoundCloudUser, SoundCloudPaginatedResponse } from \"../types/api.js\";\n\n/**\n * Fetch users that a given user is following.\n *\n * @param token - OAuth access token\n * @param userId - The user's numeric ID or URN\n * @param limit - Maximum number of users per page\n * @returns Paginated list of followed users\n * @throws {SoundCloudError} When the API returns an error\n *\n * @example\n * ```ts\n * import { getFollowings } from 'soundcloud-api-ts';\n *\n * const result = await getFollowings(token, 123456, 50);\n * result.collection.forEach(u => console.log(u.username));\n * ```\n *\n * @see https://developers.soundcloud.com/docs/api/explorer/open-api#/users/get_users__user_id__followings\n */\nexport const getFollowings = (token: string, userId: string | number, limit?: number): Promise<SoundCloudPaginatedResponse<SoundCloudUser>> =>\n scFetch({ path: `/users/${userId}/followings?${limit ? `limit=${limit}&` : \"\"}linked_partitioning=true`, method: \"GET\", token });\n","import { scFetch } from \"../client/http.js\";\nimport type { SoundCloudTrack, SoundCloudPaginatedResponse } from \"../types/api.js\";\n\n/**\n * Fetch a user's public tracks.\n *\n * @param token - OAuth access token\n * @param userId - The user's numeric ID or URN\n * @param limit - Maximum number of tracks per page\n * @returns Paginated list of tracks\n * @throws {SoundCloudError} When the API returns an error\n *\n * @example\n * ```ts\n * import { getUserTracks } from 'soundcloud-api-ts';\n *\n * const result = await getUserTracks(token, 123456, 25);\n * result.collection.forEach(t => console.log(t.title));\n * ```\n *\n * @see https://developers.soundcloud.com/docs/api/explorer/open-api#/users/get_users__user_id__tracks\n */\nexport const getUserTracks = (token: string, userId: string | number, limit?: number): Promise<SoundCloudPaginatedResponse<SoundCloudTrack>> =>\n scFetch({ path: `/users/${userId}/tracks?${limit ? `limit=${limit}&` : \"\"}linked_partitioning=true`, method: \"GET\", token });\n","import { scFetch } from \"../client/http.js\";\nimport type { SoundCloudPlaylist, SoundCloudPaginatedResponse } from \"../types/api.js\";\n\n/**\n * Fetch a user's public playlists (without full track data).\n *\n * @param token - OAuth access token\n * @param userId - The user's numeric ID or URN\n * @param limit - Maximum number of playlists per page\n * @returns Paginated list of playlists\n * @throws {SoundCloudError} When the API returns an error\n *\n * @example\n * ```ts\n * import { getUserPlaylists } from 'soundcloud-api-ts';\n *\n * const result = await getUserPlaylists(token, 123456, 10);\n * result.collection.forEach(p => console.log(p.title));\n * ```\n *\n * @see https://developers.soundcloud.com/docs/api/explorer/open-api#/users/get_users__user_id__playlists\n */\nexport const getUserPlaylists = (token: string, userId: string | number, limit?: number): Promise<SoundCloudPaginatedResponse<SoundCloudPlaylist>> =>\n scFetch({ path: `/users/${userId}/playlists?${limit ? `limit=${limit}&` : \"\"}linked_partitioning=true&show_tracks=false`, method: \"GET\", token });\n","import { scFetch } from \"../client/http.js\";\nimport type { SoundCloudTrack, SoundCloudPaginatedResponse } from \"../types/api.js\";\n\n/**\n * Fetch tracks liked by a user.\n *\n * @param token - OAuth access token\n * @param userId - The user's numeric ID or URN\n * @param limit - Maximum number of tracks per page\n * @param cursor - Pagination cursor from a previous response's `next_href`\n * @returns Paginated list of liked tracks\n * @throws {SoundCloudError} When the API returns an error\n *\n * @example\n * ```ts\n * import { getUserLikesTracks } from 'soundcloud-api-ts';\n *\n * const result = await getUserLikesTracks(token, 123456, 50);\n * result.collection.forEach(t => console.log(t.title));\n * ```\n *\n * @see https://developers.soundcloud.com/docs/api/explorer/open-api#/users/get_users__user_id__likes_tracks\n */\nexport const getUserLikesTracks = (token: string, userId: string | number, limit?: number, cursor?: string): Promise<SoundCloudPaginatedResponse<SoundCloudTrack>> =>\n scFetch({ path: `/users/${userId}/likes/tracks?${limit ? `limit=${limit}&` : \"\"}${cursor ? `cursor=${cursor}&` : \"\"}linked_partitioning=true`, method: \"GET\", token });\n","import { scFetch } from \"../client/http.js\";\nimport type { SoundCloudPlaylist, SoundCloudPaginatedResponse } from \"../types/api.js\";\n\n/**\n * Fetch playlists liked by a user.\n *\n * @param token - OAuth access token\n * @param userId - The user's numeric ID or URN\n * @param limit - Maximum number of playlists per page\n * @returns Paginated list of liked playlists\n * @throws {SoundCloudError} When the API returns an error\n *\n * @example\n * ```ts\n * import { getUserLikesPlaylists } from 'soundcloud-api-ts';\n *\n * const result = await getUserLikesPlaylists(token, 123456, 10);\n * result.collection.forEach(p => console.log(p.title));\n * ```\n *\n * @see https://developers.soundcloud.com/docs/api/explorer/open-api#/users/get_users__user_id__likes_playlists\n */\nexport const getUserLikesPlaylists = (token: string, userId: string | number, limit?: number): Promise<SoundCloudPaginatedResponse<SoundCloudPlaylist>> =>\n scFetch({ path: `/users/${userId}/likes/playlists?${limit ? `limit=${limit}&` : \"\"}linked_partitioning=true`, method: \"GET\", token });\n","import { scFetch } from \"../client/http.js\";\nimport type { SoundCloudWebProfile } from \"../types/api.js\";\n\n/**\n * Fetch a user's external web profile links (Twitter, Instagram, personal site, etc.).\n *\n * @param token - OAuth access token\n * @param userId - The user's numeric ID or URN\n * @returns Array of web profile objects\n * @throws {SoundCloudError} When the API returns an error\n *\n * @example\n * ```ts\n * import { getUserWebProfiles } from 'soundcloud-api-ts';\n *\n * const profiles = await getUserWebProfiles(token, 123456);\n * profiles.forEach(p => console.log(p.service, p.url));\n * ```\n *\n * @see https://developers.soundcloud.com/docs/api/explorer/open-api#/users/get_users__user_id__web_profiles\n */\nexport const getUserWebProfiles = (token: string, userId: string | number): Promise<SoundCloudWebProfile[]> =>\n scFetch<SoundCloudWebProfile[]>({ path: `/users/${userId}/web-profiles`, method: \"GET\", token });\n","import { scFetch } from \"../client/http.js\";\nimport type { SoundCloudTrack } from \"../types/api.js\";\n\n/**\n * Fetch a track by ID.\n *\n * @param token - OAuth access token\n * @param trackId - The track's numeric ID or URN\n * @returns The track object with full metadata\n * @throws {SoundCloudError} When the track is not found or the API returns an error\n *\n * @example\n * ```ts\n * import { getTrack } from 'soundcloud-api-ts';\n *\n * const track = await getTrack(token, 123456);\n * console.log(track.title, track.duration);\n * ```\n *\n * @see https://developers.soundcloud.com/docs/api/explorer/open-api#/tracks/get_tracks__track_id_\n */\nexport const getTrack = (token: string, trackId: string | number): Promise<SoundCloudTrack> =>\n scFetch<SoundCloudTrack>({ path: `/tracks/${trackId}`, method: \"GET\", token });\n","import { scFetch } from \"../client/http.js\";\nimport type { SoundCloudTrack } from \"../types/api.js\";\n\n/**\n * Fetch multiple tracks by their IDs in a single request.\n *\n * @param token - OAuth access token\n * @param ids - Array of track IDs (numeric or string URNs)\n * @returns Array of track objects (may be shorter than `ids` if some tracks are unavailable)\n * @throws {SoundCloudError} When the API returns an error\n * @throws {Error} When more than 200 IDs are provided\n *\n * @remarks\n * SoundCloud's API likely caps at ~200 IDs per request. Passing more than 200 IDs\n * will throw immediately without making a network request.\n *\n * @example\n * ```ts\n * import { getTracks } from 'soundcloud-api-ts';\n *\n * const tracks = await getTracks(token, [123456, 234567, 345678]);\n * tracks.forEach(t => console.log(t.title));\n * ```\n *\n * @see https://developers.soundcloud.com/docs/api/explorer/open-api#/tracks/get_tracks\n */\nexport const getTracks = (\n token: string,\n ids: (string | number)[],\n): Promise<SoundCloudTrack[]> => {\n if (ids.length > 200) {\n throw new Error(\"getTracks: SoundCloud API supports a maximum of 200 IDs per request\");\n }\n return scFetch<SoundCloudTrack[]>({\n path: `/tracks?ids=${ids.join(\",\")}`,\n method: \"GET\",\n token,\n });\n};\n","import { scFetch } from \"../client/http.js\";\nimport type { SoundCloudComment, SoundCloudPaginatedResponse } from \"../types/api.js\";\n\n/**\n * Fetch comments on a track.\n *\n * @param token - OAuth access token\n * @param trackId - The track's numeric ID or URN\n * @param limit - Maximum number of comments per page\n * @returns Paginated list of comments\n * @throws {SoundCloudError} When the API returns an error\n *\n * @example\n * ```ts\n * import { getTrackComments } from 'soundcloud-api-ts';\n *\n * const result = await getTrackComments(token, 123456, 20);\n * result.collection.forEach(c => console.log(c.body));\n * ```\n *\n * @see https://developers.soundcloud.com/docs/api/explorer/open-api#/tracks/get_tracks__track_id__comments\n */\nexport const getTrackComments = (token: string, trackId: string | number, limit?: number): Promise<SoundCloudPaginatedResponse<SoundCloudComment>> =>\n scFetch({ path: `/tracks/${trackId}/comments?threaded=1&filter_replies=0${limit ? `&limit=${limit}` : \"\"}&linked_partitioning=true`, method: \"GET\", token });\n","import { scFetch } from \"../client/http.js\";\nimport type { SoundCloudComment } from \"../types/api.js\";\n\n/**\n * Post a comment on a track.\n *\n * @param token - OAuth access token\n * @param trackId - The track's numeric ID or URN\n * @param body - The comment text\n * @param timestamp - Position in the track in milliseconds where the comment is placed\n * @returns The created comment object\n * @throws {SoundCloudError} When the API returns an error\n *\n * @example\n * ```ts\n * import { createTrackComment } from 'soundcloud-api-ts';\n *\n * const comment = await createTrackComment(token, 123456, 'Great drop!', 60000);\n * console.log(comment.id);\n * ```\n *\n * @see https://developers.soundcloud.com/docs/api/explorer/open-api#/tracks/post_tracks__track_id__comments\n */\nexport const createTrackComment = (\n token: string,\n trackId: string | number,\n body: string,\n timestamp?: number,\n): Promise<SoundCloudComment> =>\n scFetch<SoundCloudComment>({\n path: `/tracks/${trackId}/comments`,\n method: \"POST\",\n token,\n body: { comment: { body, ...(timestamp !== undefined ? { timestamp } : {}) } },\n });\n","import { scFetch } from \"../client/http.js\";\nimport type { SoundCloudUser, SoundCloudPaginatedResponse } from \"../types/api.js\";\n\n/**\n * Fetch users who have liked (favorited) a track.\n *\n * @param token - OAuth access token\n * @param trackId - The track's numeric ID or URN\n * @param limit - Maximum number of users per page\n * @returns Paginated list of users who liked the track\n * @throws {SoundCloudError} When the API returns an error\n *\n * @example\n * ```ts\n * import { getTrackLikes } from 'soundcloud-api-ts';\n *\n * const result = await getTrackLikes(token, 123456, 50);\n * result.collection.forEach(u => console.log(u.username));\n * ```\n *\n * @see https://developers.soundcloud.com/docs/api/explorer/open-api#/tracks/get_tracks__track_id__favoriters\n */\nexport const getTrackLikes = (token: string, trackId: string | number, limit?: number): Promise<SoundCloudPaginatedResponse<SoundCloudUser>> =>\n scFetch({ path: `/tracks/${trackId}/favoriters?${limit ? `limit=${limit}&` : \"\"}linked_partitioning=true`, method: \"GET\", token });\n","import { scFetch } from \"../client/http.js\";\nimport type { SoundCloudUser, SoundCloudPaginatedResponse } from \"../types/api.js\";\n\n/**\n * Fetch users who have reposted a track.\n *\n * @param token - OAuth access token\n * @param trackId - The track's numeric ID or URN\n * @param limit - Maximum number of users per page\n * @returns Paginated list of users who reposted the track\n * @throws {SoundCloudError} When the API returns an error\n *\n * @example\n * ```ts\n * import { getTrackReposts } from 'soundcloud-api-ts';\n *\n * const result = await getTrackReposts(token, 123456, 50);\n * result.collection.forEach(u => console.log(u.username));\n * ```\n *\n * @see https://developers.soundcloud.com/docs/api/explorer/open-api#/tracks/get_tracks__track_id__reposters\n */\nexport const getTrackReposts = (token: string, trackId: string | number, limit?: number): Promise<SoundCloudPaginatedResponse<SoundCloudUser>> =>\n scFetch({ path: `/tracks/${trackId}/reposters?${limit ? `limit=${limit}&` : \"\"}linked_partitioning=true`, method: \"GET\", token });\n","import { scFetch } from \"../client/http.js\";\nimport type { SoundCloudTrack } from \"../types/api.js\";\n\n/**\n * Fetch tracks related to a given track.\n *\n * @param token - OAuth access token\n * @param trackId - The track's numeric ID or URN\n * @param limit - Maximum number of related tracks to return\n * @returns Array of related tracks\n * @throws {SoundCloudError} When the API returns an error\n *\n * @example\n * ```ts\n * import { getRelatedTracks } from 'soundcloud-api-ts';\n *\n * const related = await getRelatedTracks(token, 123456, 5);\n * related.forEach(t => console.log(t.title));\n * ```\n *\n * @see https://developers.soundcloud.com/docs/api/explorer/open-api#/tracks/get_tracks__track_id__related\n */\nexport const getRelatedTracks = (token: string, trackId: string | number, limit?: number): Promise<SoundCloudTrack[]> =>\n scFetch<SoundCloudTrack[]>({ path: `/tracks/${trackId}/related${limit ? `?limit=${limit}` : \"\"}`, method: \"GET\", token });\n","import { scFetch } from \"../client/http.js\";\nimport type { SoundCloudStreams } from \"../types/api.js\";\n\n/**\n * Fetch stream URLs for a track (HLS, MP3, preview).\n *\n * @param token - OAuth access token\n * @param trackId - The track's numeric ID or URN\n * @returns Object containing available stream URLs\n * @throws {SoundCloudError} When the track is not found or not streamable\n *\n * @example\n * ```ts\n * import { getTrackStreams } from 'soundcloud-api-ts';\n *\n * const streams = await getTrackStreams(token, 123456);\n * console.log(streams.hls_mp3_128_url);\n * ```\n *\n * @see https://developers.soundcloud.com/docs/api/explorer/open-api#/tracks/get_tracks__track_id__streams\n */\nexport const getTrackStreams = (token: string, trackId: string | number): Promise<SoundCloudStreams> =>\n scFetch<SoundCloudStreams>({ path: `/tracks/${trackId}/streams`, method: \"GET\", token });\n","import { scFetch } from \"../client/http.js\";\n\n/**\n * Like (favorite) a track as the authenticated user.\n *\n * @param token - OAuth access token\n * @param trackId - The track's numeric ID or URN\n * @returns `true` if the like was successful, `false` on failure\n *\n * @example\n * ```ts\n * import { likeTrack } from 'soundcloud-api-ts';\n *\n * const success = await likeTrack(token, 123456);\n * ```\n *\n * @see https://developers.soundcloud.com/docs/api/explorer/open-api#/likes/post_likes_tracks__track_id_\n */\nexport const likeTrack = async (token: string, trackId: string | number): Promise<boolean> => {\n try {\n await scFetch<unknown>({ path: `/likes/tracks/${trackId}`, method: \"POST\", token });\n return true;\n } catch {\n return false;\n }\n};\n","import { scFetch } from \"../client/http.js\";\n\n/**\n * Unlike (unfavorite) a track as the authenticated user.\n *\n * @param token - OAuth access token\n * @param trackId - The track's numeric ID or URN\n * @returns `true` if the unlike was successful, `false` on failure\n *\n * @example\n * ```ts\n * import { unlikeTrack } from 'soundcloud-api-ts';\n *\n * const success = await unlikeTrack(token, 123456);\n * ```\n *\n * @see https://developers.soundcloud.com/docs/api/explorer/open-api#/likes/delete_likes_tracks__track_id_\n */\nexport const unlikeTrack = async (token: string, trackId: string | number): Promise<boolean> => {\n try {\n await scFetch<unknown>({ path: `/likes/tracks/${trackId}`, method: \"DELETE\", token });\n return true;\n } catch {\n return false;\n }\n};\n","import { scFetch } from \"../client/http.js\";\nimport type { SoundCloudTrack } from \"../types/api.js\";\n\n/**\n * Parameters for updating a track's metadata via {@link updateTrack}.\n */\nexport interface UpdateTrackParams {\n /** New track title */\n title?: string;\n /** New track description */\n description?: string;\n /** Music genre (e.g. \"Electronic\", \"Hip-hop & Rap\") */\n genre?: string;\n /** Space-separated tags (tags with spaces should be wrapped in quotes) */\n tag_list?: string;\n /** Visibility: \"public\" or \"private\" */\n sharing?: \"public\" | \"private\";\n /** Whether the track is downloadable */\n downloadable?: boolean;\n /** External purchase URL */\n purchase_url?: string;\n /** Label for the purchase/buy button */\n purchase_title?: string;\n /** Release identifier string */\n release?: string;\n /** Day of the release date (1-31) */\n release_day?: number;\n /** Month of the release date (1-12) */\n release_month?: number;\n /** Year of the release date */\n release_year?: number;\n /** Record label name */\n label_name?: string;\n /** Creative Commons license type (e.g. \"all-rights-reserved\", \"cc-by\") */\n license?: string;\n /** International Standard Recording Code */\n isrc?: string;\n /** Beats per minute */\n bpm?: number;\n /** Musical key signature (e.g. \"C major\") */\n key_signature?: string;\n}\n\n/**\n * Update a track's metadata.\n *\n * @param token - OAuth access token\n * @param trackId - The track's numeric ID or URN\n * @param params - Fields to update\n * @returns The updated track object\n * @throws {SoundCloudError} When the API returns an error\n *\n * @example\n * ```ts\n * import { updateTrack } from 'soundcloud-api-ts';\n *\n * const updated = await updateTrack(token, 123456, {\n * title: 'New Title',\n * genre: 'Electronic',\n * });\n * console.log(updated.title);\n * ```\n *\n * @see https://developers.soundcloud.com/docs/api/explorer/open-api#/tracks/put_tracks__track_id_\n */\nexport const updateTrack = (\n token: string,\n trackId: string | number,\n params: UpdateTrackParams,\n): Promise<SoundCloudTrack> =>\n scFetch<SoundCloudTrack>({\n path: `/tracks/${trackId}`,\n method: \"PUT\",\n token,\n body: { track: params },\n });\n","import { scFetch } from \"../client/http.js\";\n\n/**\n * Delete a track.\n *\n * @param token - OAuth access token\n * @param trackId - The track's numeric ID or URN\n * @throws {SoundCloudError} When the API returns an error\n *\n * @example\n * ```ts\n * import { deleteTrack } from 'soundcloud-api-ts';\n *\n * await deleteTrack(token, 123456);\n * ```\n *\n * @see https://developers.soundcloud.com/docs/api/explorer/open-api#/tracks/delete_tracks__track_id_\n */\nexport const deleteTrack = (token: string, trackId: string | number): Promise<void> =>\n scFetch<void>({ path: `/tracks/${trackId}`, method: \"DELETE\", token });\n","import { scFetch } from \"../client/http.js\";\nimport type { SoundCloudPlaylist } from \"../types/api.js\";\n\n/**\n * Fetch a playlist by ID.\n *\n * @param token - OAuth access token\n * @param playlistId - The playlist's numeric ID or URN\n * @returns The playlist object with track data\n * @throws {SoundCloudError} When the playlist is not found or the API returns an error\n *\n * @example\n * ```ts\n * import { getPlaylist } from 'soundcloud-api-ts';\n *\n * const playlist = await getPlaylist(token, 123456);\n * console.log(playlist.title, playlist.track_count);\n * ```\n *\n * @see https://developers.soundcloud.com/docs/api/explorer/open-api#/playlists/get_playlists__playlist_id_\n */\nexport const getPlaylist = (token: string, playlistId: string | number): Promise<SoundCloudPlaylist> =>\n scFetch<SoundCloudPlaylist>({ path: `/playlists/${playlistId}`, method: \"GET\", token });\n","import { scFetch } from \"../client/http.js\";\nimport type { SoundCloudTrack, SoundCloudPaginatedResponse } from \"../types/api.js\";\n\n/**\n * Fetch tracks in a playlist.\n *\n * @param token - OAuth access token\n * @param playlistId - The playlist's numeric ID or URN\n * @param limit - Maximum number of tracks per page\n * @param offset - Number of tracks to skip (for offset-based pagination)\n * @returns Paginated list of tracks\n * @throws {SoundCloudError} When the API returns an error\n *\n * @example\n * ```ts\n * import { getPlaylistTracks } from 'soundcloud-api-ts';\n *\n * const result = await getPlaylistTracks(token, 123456, 25);\n * result.collection.forEach(t => console.log(t.title));\n * ```\n *\n * @see https://developers.soundcloud.com/docs/api/explorer/open-api#/playlists/get_playlists__playlist_id__tracks\n */\nexport const getPlaylistTracks = (token: string, playlistId: string | number, limit?: number, offset?: number): Promise<SoundCloudPaginatedResponse<SoundCloudTrack>> =>\n scFetch({ path: `/playlists/${playlistId}/tracks?${limit ? `limit=${limit}&` : \"\"}linked_partitioning=true${offset ? `&offset=${offset}` : \"\"}`, method: \"GET\", token });\n","import { scFetch } from \"../client/http.js\";\nimport type { SoundCloudUser, SoundCloudPaginatedResponse } from \"../types/api.js\";\n\n/**\n * Fetch users who have reposted a playlist.\n *\n * @param token - OAuth access token\n * @param playlistId - The playlist's numeric ID or URN\n * @param limit - Maximum number of users per page\n * @returns Paginated list of users who reposted the playlist\n * @throws {SoundCloudError} When the API returns an error\n *\n * @example\n * ```ts\n * import { getPlaylistReposts } from 'soundcloud-api-ts';\n *\n * const result = await getPlaylistReposts(token, 123456, 50);\n * result.collection.forEach(u => console.log(u.username));\n * ```\n *\n * @see https://developers.soundcloud.com/docs/api/explorer/open-api#/playlists/get_playlists__playlist_id__reposters\n */\nexport const getPlaylistReposts = (token: string, playlistId: string | number, limit?: number): Promise<SoundCloudPaginatedResponse<SoundCloudUser>> =>\n scFetch({ path: `/playlists/${playlistId}/reposters?${limit ? `limit=${limit}&` : \"\"}linked_partitioning=true`, method: \"GET\", token });\n","import { scFetch } from \"../client/http.js\";\nimport type { SoundCloudPlaylist } from \"../types/api.js\";\n\n/**\n * Parameters for creating a new playlist via {@link createPlaylist}.\n */\nexport interface CreatePlaylistParams {\n /** Playlist title (required) */\n title: string;\n /** Playlist description */\n description?: string;\n /** Visibility: \"public\" or \"private\" */\n sharing?: \"public\" | \"private\";\n /** Tracks to include, specified by URN (e.g. `[{ urn: \"soundcloud:tracks:123\" }]`) */\n tracks?: { urn: string }[];\n /** European Article Number (barcode) for the release */\n ean?: string;\n /** Music genre */\n genre?: string;\n /** Record label name */\n label_name?: string;\n /** Creative Commons license type */\n license?: string;\n /** Custom permalink slug */\n permalink?: string;\n /** Label for the purchase/buy button */\n purchase_title?: string;\n /** External purchase URL */\n purchase_url?: string;\n /** Release identifier string */\n release?: string;\n /** Release date in ISO 8601 format */\n release_date?: string;\n /** Set type: \"album\" or \"playlist\" */\n set_type?: \"album\" | \"playlist\";\n /** Space-separated tags */\n tag_list?: string;\n}\n\n/**\n * Create a new playlist.\n *\n * @param token - OAuth access token\n * @param params - Playlist creation parameters (title is required)\n * @returns The created playlist object\n * @throws {SoundCloudError} When the API returns an error\n *\n * @example\n * ```ts\n * import { createPlaylist } from 'soundcloud-api-ts';\n *\n * const playlist = await createPlaylist(token, {\n * title: 'My Favorites',\n * sharing: 'public',\n * tracks: [{ urn: 'soundcloud:tracks:123' }],\n * });\n * console.log(playlist.id, playlist.title);\n * ```\n *\n * @see https://developers.soundcloud.com/docs/api/explorer/open-api#/playlists/post_playlists\n */\nexport const createPlaylist = (\n token: string,\n params: CreatePlaylistParams,\n): Promise<SoundCloudPlaylist> =>\n scFetch<SoundCloudPlaylist>({\n path: \"/playlists\",\n method: \"POST\",\n token,\n body: { playlist: params },\n });\n","import { scFetch } from \"../client/http.js\";\nimport type { SoundCloudPlaylist } from \"../types/api.js\";\n\n/**\n * Parameters for updating a playlist via {@link updatePlaylist}.\n */\nexport interface UpdatePlaylistParams {\n /** New playlist title */\n title?: string;\n /** New playlist description */\n description?: string;\n /** Visibility: \"public\" or \"private\" */\n sharing?: \"public\" | \"private\";\n /** Replace the playlist's tracks (specified by URN) */\n tracks?: { urn: string }[];\n /** European Article Number (barcode) */\n ean?: string;\n /** Music genre */\n genre?: string;\n /** Record label name */\n label_name?: string;\n /** Creative Commons license type */\n license?: string;\n /** Custom permalink slug */\n permalink?: string;\n /** Label for the purchase/buy button */\n purchase_title?: string;\n /** External purchase URL */\n purchase_url?: string;\n /** Release identifier string */\n release?: string;\n /** Release date in ISO 8601 format */\n release_date?: string;\n /** Set type: \"album\" or \"playlist\" */\n set_type?: \"album\" | \"playlist\";\n /** Space-separated tags */\n tag_list?: string;\n}\n\n/**\n * Update a playlist's metadata or track list.\n *\n * @param token - OAuth access token\n * @param playlistId - The playlist's numeric ID or URN\n * @param params - Fields to update\n * @returns The updated playlist object\n * @throws {SoundCloudError} When the API returns an error\n *\n * @example\n * ```ts\n * import { updatePlaylist } from 'soundcloud-api-ts';\n *\n * const updated = await updatePlaylist(token, 123456, {\n * title: 'Updated Title',\n * tracks: [{ urn: 'soundcloud:tracks:111' }, { urn: 'soundcloud:tracks:222' }],\n * });\n * ```\n *\n * @see https://developers.soundcloud.com/docs/api/explorer/open-api#/playlists/put_playlists__playlist_id_\n */\nexport const updatePlaylist = (\n token: string,\n playlistId: string | number,\n params: UpdatePlaylistParams,\n): Promise<SoundCloudPlaylist> =>\n scFetch<SoundCloudPlaylist>({\n path: `/playlists/${playlistId}`,\n method: \"PUT\",\n token,\n body: { playlist: params },\n });\n","import { scFetch } from \"../client/http.js\";\n\n/**\n * Delete a playlist.\n *\n * @param token - OAuth access token\n * @param playlistId - The playlist's numeric ID or URN\n * @throws {SoundCloudError} When the API returns an error\n *\n * @example\n * ```ts\n * import { deletePlaylist } from 'soundcloud-api-ts';\n *\n * await deletePlaylist(token, 123456);\n * ```\n *\n * @see https://developers.soundcloud.com/docs/api/explorer/open-api#/playlists/delete_playlists__playlist_id_\n */\nexport const deletePlaylist = (token: string, playlistId: string | number): Promise<void> =>\n scFetch<void>({ path: `/playlists/${playlistId}`, method: \"DELETE\", token });\n","import { scFetch } from \"../client/http.js\";\nimport type { SoundCloudTrack, SoundCloudPaginatedResponse } from \"../types/api.js\";\n\n/**\n * Search for tracks by query string.\n *\n * @param token - OAuth access token\n * @param query - Search query text\n * @param pageNumber - Zero-based page number (10 results per page)\n * @returns Paginated list of matching tracks\n * @throws {SoundCloudError} When the API returns an error\n *\n * @example\n * ```ts\n * import { searchTracks } from 'soundcloud-api-ts';\n *\n * const result = await searchTracks(token, 'lofi hip hop');\n * result.collection.forEach(t => console.log(t.title));\n * ```\n *\n * @see https://developers.soundcloud.com/docs/api/explorer/open-api#/tracks/get_tracks\n */\nexport const searchTracks = (token: string, query: string, pageNumber?: number): Promise<SoundCloudPaginatedResponse<SoundCloudTrack>> =>\n scFetch({ path: `/tracks?q=${encodeURIComponent(query)}&linked_partitioning=true&limit=10${pageNumber && pageNumber > 0 ? `&offset=${10 * pageNumber}` : \"\"}`, method: \"GET\", token });\n","import { scFetch } from \"../client/http.js\";\nimport type { SoundCloudUser, SoundCloudPaginatedResponse } from \"../types/api.js\";\n\n/**\n * Search for users by query string.\n *\n * @param token - OAuth access token\n * @param query - Search query text\n * @param pageNumber - Zero-based page number (10 results per page)\n * @returns Paginated list of matching users\n * @throws {SoundCloudError} When the API returns an error\n *\n * @example\n * ```ts\n * import { searchUsers } from 'soundcloud-api-ts';\n *\n * const result = await searchUsers(token, 'deadmau5');\n * result.collection.forEach(u => console.log(u.username));\n * ```\n *\n * @see https://developers.soundcloud.com/docs/api/explorer/open-api#/users/get_users\n */\nexport const searchUsers = (token: string, query: string, pageNumber?: number): Promise<SoundCloudPaginatedResponse<SoundCloudUser>> =>\n scFetch({ path: `/users?q=${encodeURIComponent(query)}&linked_partitioning=true&limit=10${pageNumber && pageNumber > 0 ? `&offset=${10 * pageNumber}` : \"\"}`, method: \"GET\", token });\n","import { scFetch } from \"../client/http.js\";\nimport type { SoundCloudPlaylist, SoundCloudPaginatedResponse } from \"../types/api.js\";\n\n/**\n * Search for playlists by query string.\n *\n * @param token - OAuth access token\n * @param query - Search query text\n * @param pageNumber - Zero-based page number (10 results per page)\n * @returns Paginated list of matching playlists\n * @throws {SoundCloudError} When the API returns an error\n *\n * @example\n * ```ts\n * import { searchPlaylists } from 'soundcloud-api-ts';\n *\n * const result = await searchPlaylists(token, 'chill vibes');\n * result.collection.forEach(p => console.log(p.title));\n * ```\n *\n * @see https://developers.soundcloud.com/docs/api/explorer/open-api#/playlists/get_playlists\n */\nexport const searchPlaylists = (token: string, query: string, pageNumber?: number): Promise<SoundCloudPaginatedResponse<SoundCloudPlaylist>> =>\n scFetch({ path: `/playlists?q=${encodeURIComponent(query)}&linked_partitioning=true&limit=10${pageNumber && pageNumber > 0 ? `&offset=${10 * pageNumber}` : \"\"}`, method: \"GET\", token });\n","import { scFetch } from \"../client/http.js\";\n\n/**\n * Resolve a SoundCloud URL to its API resource URL.\n *\n * SoundCloud returns a 302 redirect to the API resource; this function returns the redirect target URL.\n *\n * @param token - OAuth access token\n * @param url - A SoundCloud URL (e.g. \"https://soundcloud.com/artist/track-name\")\n * @returns The resolved API resource URL\n * @throws {SoundCloudError} When the URL cannot be resolved\n *\n * @example\n * ```ts\n * import { resolveUrl } from 'soundcloud-api-ts';\n *\n * const apiUrl = await resolveUrl(token, 'https://soundcloud.com/deadmau5/strobe');\n * console.log(apiUrl); // \"https://api.soundcloud.com/tracks/...\"\n * ```\n *\n * @see https://developers.soundcloud.com/docs/api/explorer/open-api#/resolve/get_resolve\n */\nexport const resolveUrl = (token: string, url: string): Promise<string> =>\n scFetch<string>({ path: `/resolve?url=${encodeURIComponent(url)}`, method: \"GET\", token });\n","import { scFetch } from \"../client/http.js\";\nimport type { SoundCloudActivitiesResponse } from \"../types/api.js\";\n\n/**\n * Fetch the authenticated user's activity feed.\n *\n * @param token - OAuth access token\n * @param limit - Maximum number of activities per page\n * @returns Activities response with `future_href` for polling\n * @throws {SoundCloudError} When the API returns an error\n *\n * @example\n * ```ts\n * import { getMeActivities } from 'soundcloud-api-ts';\n *\n * const activities = await getMeActivities(token, 25);\n * activities.collection.forEach(a => console.log(a.type));\n * ```\n *\n * @see https://developers.soundcloud.com/docs/api/explorer/open-api#/me/get_me_activities\n */\nexport const getMeActivities = (token: string, limit?: number): Promise<SoundCloudActivitiesResponse> =>\n scFetch({ path: `/me/activities?${limit ? `limit=${limit}&` : \"\"}linked_partitioning=true`, method: \"GET\", token });\n\n/**\n * Fetch the authenticated user's own activities (uploads, reposts by the user).\n *\n * @param token - OAuth access token\n * @param limit - Maximum number of activities per page\n * @returns Activities response\n * @throws {SoundCloudError} When the API returns an error\n *\n * @example\n * ```ts\n * import { getMeActivitiesOwn } from 'soundcloud-api-ts';\n *\n * const activities = await getMeActivitiesOwn(token, 25);\n * activities.collection.forEach(a => console.log(a.type));\n * ```\n *\n * @see https://developers.soundcloud.com/docs/api/explorer/open-api#/me/get_me_activities_all_own\n */\nexport const getMeActivitiesOwn = (token: string, limit?: number): Promise<SoundCloudActivitiesResponse> =>\n scFetch({ path: `/me/activities/all/own?${limit ? `limit=${limit}&` : \"\"}linked_partitioning=true`, method: \"GET\", token });\n\n/**\n * Fetch track-related activities in the authenticated user's feed.\n *\n * @param token - OAuth access token\n * @param limit - Maximum number of activities per page\n * @returns Activities response filtered to track activities\n * @throws {SoundCloudError} When the API returns an error\n *\n * @example\n * ```ts\n * import { getMeActivitiesTracks } from 'soundcloud-api-ts';\n *\n * const activities = await getMeActivitiesTracks(token, 25);\n * activities.collection.forEach(a => console.log(a.type));\n * ```\n *\n * @see https://developers.soundcloud.com/docs/api/explorer/open-api#/me/get_me_activities_tracks\n */\nexport const getMeActivitiesTracks = (token: string, limit?: number): Promise<SoundCloudActivitiesResponse> =>\n scFetch({ path: `/me/activities/tracks?${limit ? `limit=${limit}&` : \"\"}linked_partitioning=true`, method: \"GET\", token });\n","import { scFetch } from \"../client/http.js\";\nimport type { SoundCloudTrack, SoundCloudPlaylist, SoundCloudPaginatedResponse } from \"../types/api.js\";\n\n/**\n * Fetch tracks liked by the authenticated user.\n *\n * @param token - OAuth access token\n * @param limit - Maximum number of tracks per page\n * @returns Paginated list of liked tracks\n * @throws {SoundCloudError} When the API returns an error\n *\n * @example\n * ```ts\n * import { getMeLikesTracks } from 'soundcloud-api-ts';\n *\n * const result = await getMeLikesTracks(token, 50);\n * result.collection.forEach(t => console.log(t.title));\n * ```\n *\n * @see https://developers.soundcloud.com/docs/api/explorer/open-api#/me/get_me_likes_tracks\n */\nexport const getMeLikesTracks = (token: string, limit?: number): Promise<SoundCloudPaginatedResponse<SoundCloudTrack>> =>\n scFetch({ path: `/me/likes/tracks?${limit ? `limit=${limit}&` : \"\"}linked_partitioning=true`, method: \"GET\", token });\n\n/**\n * Fetch playlists liked by the authenticated user.\n *\n * @param token - OAuth access token\n * @param limit - Maximum number of playlists per page\n * @returns Paginated list of liked playlists\n * @throws {SoundCloudError} When the API returns an error\n *\n * @example\n * ```ts\n * import { getMeLikesPlaylists } from 'soundcloud-api-ts';\n *\n * const result = await getMeLikesPlaylists(token, 50);\n * result.collection.forEach(p => console.log(p.title));\n * ```\n *\n * @see https://developers.soundcloud.com/docs/api/explorer/open-api#/me/get_me_likes_playlists\n */\nexport const getMeLikesPlaylists = (token: string, limit?: number): Promise<SoundCloudPaginatedResponse<SoundCloudPlaylist>> =>\n scFetch({ path: `/me/likes/playlists?${limit ? `limit=${limit}&` : \"\"}linked_partitioning=true`, method: \"GET\", token });\n","import { scFetch } from \"../client/http.js\";\nimport type { SoundCloudUser, SoundCloudTrack, SoundCloudPaginatedResponse } from \"../types/api.js\";\n\n/**\n * Fetch users the authenticated user is following.\n *\n * @param token - OAuth access token\n * @param limit - Maximum number of users per page\n * @returns Paginated list of followed users\n * @throws {SoundCloudError} When the API returns an error\n *\n * @example\n * ```ts\n * import { getMeFollowings } from 'soundcloud-api-ts';\n *\n * const result = await getMeFollowings(token, 50);\n * result.collection.forEach(u => console.log(u.username));\n * ```\n *\n * @see https://developers.soundcloud.com/docs/api/explorer/open-api#/me/get_me_followings\n */\nexport const getMeFollowings = (token: string, limit?: number): Promise<SoundCloudPaginatedResponse<SoundCloudUser>> =>\n scFetch({ path: `/me/followings?${limit ? `limit=${limit}&` : \"\"}linked_partitioning=true`, method: \"GET\", token });\n\n/**\n * Fetch recent tracks from users the authenticated user is following.\n *\n * @param token - OAuth access token\n * @param limit - Maximum number of tracks per page\n * @returns Paginated list of tracks from followed users\n * @throws {SoundCloudError} When the API returns an error\n *\n * @example\n * ```ts\n * import { getMeFollowingsTracks } from 'soundcloud-api-ts';\n *\n * const result = await getMeFollowingsTracks(token, 50);\n * result.collection.forEach(t => console.log(t.title));\n * ```\n *\n * @see https://developers.soundcloud.com/docs/api/explorer/open-api#/me/get_me_followings_tracks\n */\nexport const getMeFollowingsTracks = (token: string, limit?: number): Promise<SoundCloudPaginatedResponse<SoundCloudTrack>> =>\n scFetch({ path: `/me/followings/tracks?${limit ? `limit=${limit}&` : \"\"}linked_partitioning=true`, method: \"GET\", token });\n\n/**\n * Follow a user as the authenticated user.\n *\n * @param token - OAuth access token\n * @param userUrn - The user's ID or URN to follow\n * @throws {SoundCloudError} When the API returns an error\n *\n * @example\n * ```ts\n * import { followUser } from 'soundcloud-api-ts';\n *\n * await followUser(token, 123456);\n * ```\n *\n * @see https://developers.soundcloud.com/docs/api/explorer/open-api#/me/put_me_followings__user_id_\n */\nexport const followUser = (token: string, userUrn: string | number): Promise<void> =>\n scFetch<void>({ path: `/me/followings/${userUrn}`, method: \"PUT\", token });\n\n/**\n * Unfollow a user as the authenticated user.\n *\n * @param token - OAuth access token\n * @param userUrn - The user's ID or URN to unfollow\n * @throws {SoundCloudError} When the API returns an error\n *\n * @example\n * ```ts\n * import { unfollowUser } from 'soundcloud-api-ts';\n *\n * await unfollowUser(token, 123456);\n * ```\n *\n * @see https://developers.soundcloud.com/docs/api/explorer/open-api#/me/delete_me_followings__user_id_\n */\nexport const unfollowUser = (token: string, userUrn: string | number): Promise<void> =>\n scFetch<void>({ path: `/me/followings/${userUrn}`, method: \"DELETE\", token });\n","import { scFetch } from \"../client/http.js\";\nimport type { SoundCloudUser, SoundCloudPaginatedResponse } from \"../types/api.js\";\n\n/**\n * Fetch the authenticated user's followers.\n *\n * @param token - OAuth access token\n * @param limit - Maximum number of users per page\n * @returns Paginated list of follower users\n * @throws {SoundCloudError} When the API returns an error\n *\n * @example\n * ```ts\n * import { getMeFollowers } from 'soundcloud-api-ts';\n *\n * const result = await getMeFollowers(token, 50);\n * result.collection.forEach(u => console.log(u.username));\n * ```\n *\n * @see https://developers.soundcloud.com/docs/api/explorer/open-api#/me/get_me_followers\n */\nexport const getMeFollowers = (token: string, limit?: number): Promise<SoundCloudPaginatedResponse<SoundCloudUser>> =>\n scFetch({ path: `/me/followers?${limit ? `limit=${limit}&` : \"\"}linked_partitioning=true`, method: \"GET\", token });\n","import { scFetch } from \"../client/http.js\";\nimport type { SoundCloudPlaylist, SoundCloudPaginatedResponse } from \"../types/api.js\";\n\n/**\n * Fetch the authenticated user's playlists.\n *\n * @param token - OAuth access token\n * @param limit - Maximum number of playlists per page\n * @returns Paginated list of playlists\n * @throws {SoundCloudError} When the API returns an error\n *\n * @example\n * ```ts\n * import { getMePlaylists } from 'soundcloud-api-ts';\n *\n * const result = await getMePlaylists(token, 10);\n * result.collection.forEach(p => console.log(p.title));\n * ```\n *\n * @see https://developers.soundcloud.com/docs/api/explorer/open-api#/me/get_me_playlists\n */\nexport const getMePlaylists = (token: string, limit?: number): Promise<SoundCloudPaginatedResponse<SoundCloudPlaylist>> =>\n scFetch({ path: `/me/playlists?${limit ? `limit=${limit}&` : \"\"}linked_partitioning=true`, method: \"GET\", token });\n","import { scFetch } from \"../client/http.js\";\nimport type { SoundCloudTrack, SoundCloudPaginatedResponse } from \"../types/api.js\";\n\n/**\n * Fetch tracks uploaded by the authenticated user.\n *\n * @param token - OAuth access token\n * @param limit - Maximum number of tracks per page\n * @returns Paginated list of the user's tracks\n * @throws {SoundCloudError} When the API returns an error\n *\n * @example\n * ```ts\n * import { getMeTracks } from 'soundcloud-api-ts';\n *\n * const result = await getMeTracks(token, 50);\n * result.collection.forEach(t => console.log(t.title));\n * ```\n *\n * @see https://developers.soundcloud.com/docs/api/explorer/open-api#/me/get_me_tracks\n */\nexport const getMeTracks = (token: string, limit?: number): Promise<SoundCloudPaginatedResponse<SoundCloudTrack>> =>\n scFetch({ path: `/me/tracks?${limit ? `limit=${limit}&` : \"\"}linked_partitioning=true`, method: \"GET\", token });\n","import { scFetch } from \"../client/http.js\";\nimport type { SoundCloudConnection } from \"../types/api.js\";\n\n/**\n * List the authenticated user's connected external social accounts.\n *\n * @param token - OAuth access token (user token required)\n * @returns Array of connection objects for linked social services\n * @throws {SoundCloudError} When the API returns an error\n *\n * @remarks This endpoint may require elevated API access or app approval.\n *\n * @example\n * ```ts\n * import { getMeConnections } from 'soundcloud-api-ts';\n *\n * const connections = await getMeConnections(token);\n * connections.forEach(c => console.log(c.service, c.display_name));\n * ```\n *\n * @see https://developers.soundcloud.com/docs/api/explorer/open-api#/me/get_me_connections\n */\nexport const getMeConnections = (token: string): Promise<SoundCloudConnection[]> =>\n scFetch<SoundCloudConnection[]>({ path: \"/me/connections\", method: \"GET\", token });\n","import { scFetch } from \"../client/http.js\";\n\n/**\n * Like (favorite) a track as the authenticated user.\n *\n * @param token - OAuth access token\n * @param trackId - The track's numeric ID or URN\n * @returns `true` if the like was successful, `false` on failure\n *\n * @example\n * ```ts\n * import { likeTrack } from 'soundcloud-api-ts';\n *\n * const success = await likeTrack(token, 123456);\n * ```\n *\n * @see https://developers.soundcloud.com/docs/api/explorer/open-api#/likes/post_likes_tracks__track_id_\n */\nexport const likeTrack = async (token: string, trackId: string | number): Promise<boolean> => {\n try { await scFetch<unknown>({ path: `/likes/tracks/${trackId}`, method: \"POST\", token }); return true; } catch { return false; }\n};\n\n/**\n * Unlike (unfavorite) a track as the authenticated user.\n *\n * @param token - OAuth access token\n * @param trackId - The track's numeric ID or URN\n * @returns `true` if the unlike was successful, `false` on failure\n *\n * @example\n * ```ts\n * import { unlikeTrack } from 'soundcloud-api-ts';\n *\n * const success = await unlikeTrack(token, 123456);\n * ```\n *\n * @see https://developers.soundcloud.com/docs/api/explorer/open-api#/likes/delete_likes_tracks__track_id_\n */\nexport const unlikeTrack = async (token: string, trackId: string | number): Promise<boolean> => {\n try { await scFetch<unknown>({ path: `/likes/tracks/${trackId}`, method: \"DELETE\", token }); return true; } catch { return false; }\n};\n\n/**\n * Like a playlist as the authenticated user.\n *\n * @param token - OAuth access token\n * @param playlistId - The playlist's numeric ID or URN\n * @returns `true` if the like was successful, `false` on failure\n *\n * @example\n * ```ts\n * import { likePlaylist } from 'soundcloud-api-ts';\n *\n * const success = await likePlaylist(token, 789012);\n * ```\n *\n * @see https://developers.soundcloud.com/docs/api/explorer/open-api#/likes/post_likes_playlists__playlist_id_\n */\nexport const likePlaylist = async (token: string, playlistId: string | number): Promise<boolean> => {\n try { await scFetch<unknown>({ path: `/likes/playlists/${playlistId}`, method: \"POST\", token }); return true; } catch { return false; }\n};\n\n/**\n * Unlike a playlist as the authenticated user.\n *\n * @param token - OAuth access token\n * @param playlistId - The playlist's numeric ID or URN\n * @returns `true` if the unlike was successful, `false` on failure\n *\n * @example\n * ```ts\n * import { unlikePlaylist } from 'soundcloud-api-ts';\n *\n * const success = await unlikePlaylist(token, 789012);\n * ```\n *\n * @see https://developers.soundcloud.com/docs/api/explorer/open-api#/likes/delete_likes_playlists__playlist_id_\n */\nexport const unlikePlaylist = async (token: string, playlistId: string | number): Promise<boolean> => {\n try { await scFetch<unknown>({ path: `/likes/playlists/${playlistId}`, method: \"DELETE\", token }); return true; } catch { return false; }\n};\n","import { scFetch } from \"../client/http.js\";\n\n/**\n * Repost a track to your profile.\n *\n * @param token - OAuth access token\n * @param trackId - The track's numeric ID or URN\n * @returns `true` if the repost was successful, `false` on failure\n *\n * @example\n * ```ts\n * import { repostTrack } from 'soundcloud-api-ts';\n *\n * const success = await repostTrack(token, 123456);\n * ```\n *\n * @see https://developers.soundcloud.com/docs/api/explorer/open-api#/reposts/post_reposts_tracks__track_id_\n */\nexport const repostTrack = async (token: string, trackId: string | number): Promise<boolean> => {\n try { await scFetch<unknown>({ path: `/reposts/tracks/${trackId}`, method: \"POST\", token }); return true; } catch { return false; }\n};\n\n/**\n * Remove a track repost from your profile.\n *\n * @param token - OAuth access token\n * @param trackId - The track's numeric ID or URN\n * @returns `true` if the unrepost was successful, `false` on failure\n *\n * @example\n * ```ts\n * import { unrepostTrack } from 'soundcloud-api-ts';\n *\n * const success = await unrepostTrack(token, 123456);\n * ```\n *\n * @see https://developers.soundcloud.com/docs/api/explorer/open-api#/reposts/delete_reposts_tracks__track_id_\n */\nexport const unrepostTrack = async (token: string, trackId: string | number): Promise<boolean> => {\n try { await scFetch<unknown>({ path: `/reposts/tracks/${trackId}`, method: \"DELETE\", token }); return true; } catch { return false; }\n};\n\n/**\n * Repost a playlist to your profile.\n *\n * @param token - OAuth access token\n * @param playlistId - The playlist's numeric ID or URN\n * @returns `true` if the repost was successful, `false` on failure\n *\n * @example\n * ```ts\n * import { repostPlaylist } from 'soundcloud-api-ts';\n *\n * const success = await repostPlaylist(token, 789012);\n * ```\n *\n * @see https://developers.soundcloud.com/docs/api/explorer/open-api#/reposts/post_reposts_playlists__playlist_id_\n */\nexport const repostPlaylist = async (token: string, playlistId: string | number): Promise<boolean> => {\n try { await scFetch<unknown>({ path: `/reposts/playlists/${playlistId}`, method: \"POST\", token }); return true; } catch { return false; }\n};\n\n/**\n * Remove a playlist repost from your profile.\n *\n * @param token - OAuth access token\n * @param playlistId - The playlist's numeric ID or URN\n * @returns `true` if the unrepost was successful, `false` on failure\n *\n * @example\n * ```ts\n * import { unrepostPlaylist } from 'soundcloud-api-ts';\n *\n * const success = await unrepostPlaylist(token, 789012);\n * ```\n *\n * @see https://developers.soundcloud.com/docs/api/explorer/open-api#/reposts/delete_reposts_playlists__playlist_id_\n */\nexport const unrepostPlaylist = async (token: string, playlistId: string | number): Promise<boolean> => {\n try { await scFetch<unknown>({ path: `/reposts/playlists/${playlistId}`, method: \"DELETE\", token }); return true; } catch { return false; }\n};\n","/**\n * Returns an encoded SoundCloud widget embed URL for a given track ID.\n *\n * @param trackId - The track's numeric ID or string identifier\n * @returns URL-encoded widget embed URL string\n *\n * @example\n * ```ts\n * import { getSoundCloudWidgetUrl } from 'soundcloud-api-ts';\n *\n * const widgetUrl = getSoundCloudWidgetUrl(123456);\n * console.log(widgetUrl);\n * ```\n */\nexport const getSoundCloudWidgetUrl = (trackId: string | number): string =>\n `https%3A//api.soundcloud.com/tracks/${trackId}&show_teaser=false&color=%2300a99d&inverse=false&show_user=false&sharing=false&buying=false&liking=false&show_artwork=false&show_name=false`;\n"]}
@@ -561,13 +561,13 @@ exports.SoundCloudClient = class _SoundCloudClient {
561
561
  * @see https://developers.soundcloud.com/docs/api/explorer/open-api#/oauth2/post_oauth2_token
562
562
  */
563
563
  async getClientToken() {
564
+ const credentials = Buffer.from(`${this.config.clientId}:${this.config.clientSecret}`).toString("base64");
564
565
  return this.fetch({
565
566
  path: "/oauth/token",
566
567
  method: "POST",
568
+ headers: { Authorization: `Basic ${credentials}` },
567
569
  body: new URLSearchParams({
568
- grant_type: "client_credentials",
569
- client_id: this.config.clientId,
570
- client_secret: this.config.clientSecret
570
+ grant_type: "client_credentials"
571
571
  })
572
572
  });
573
573
  }
@@ -2100,5 +2100,5 @@ exports.unrepostPlaylist = unrepostPlaylist;
2100
2100
  exports.unrepostTrack = unrepostTrack;
2101
2101
  exports.updatePlaylist = updatePlaylist;
2102
2102
  exports.updateTrack = updateTrack;
2103
- //# sourceMappingURL=chunk-FYDWU4M3.js.map
2104
- //# sourceMappingURL=chunk-FYDWU4M3.js.map
2103
+ //# sourceMappingURL=chunk-ZOHFLO4B.js.map
2104
+ //# sourceMappingURL=chunk-ZOHFLO4B.js.map