soundcloud-api-ts-next 1.7.2 → 1.7.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.
package/AGENTS.md ADDED
@@ -0,0 +1,96 @@
1
+ # AGENTS.md — soundcloud-api-ts-next
2
+
3
+ Instructions for AI coding agents working with this package.
4
+
5
+ ## Overview
6
+
7
+ React hooks and Next.js API route handlers for the SoundCloud API. Client secrets stay on the server. Built on `soundcloud-api-ts`.
8
+
9
+ ## Setup
10
+
11
+ ```bash
12
+ npm install soundcloud-api-ts-next
13
+ ```
14
+
15
+ Requires: React 18+/19+, Next.js 13+/14+/15+
16
+
17
+ ### 1. Create API Routes (App Router)
18
+
19
+ ```ts
20
+ // app/api/soundcloud/[...soundcloud]/route.ts
21
+ import { createSoundCloudRoutes } from "soundcloud-api-ts-next/server";
22
+
23
+ const routes = createSoundCloudRoutes({
24
+ clientId: process.env.SOUNDCLOUD_CLIENT_ID!,
25
+ clientSecret: process.env.SOUNDCLOUD_CLIENT_SECRET!,
26
+ redirectUri: process.env.SOUNDCLOUD_REDIRECT_URI,
27
+ });
28
+
29
+ export const { GET, POST, DELETE } = routes.handler();
30
+ ```
31
+
32
+ ### 2. Wrap App with Provider
33
+
34
+ ```tsx
35
+ import { SoundCloudProvider } from "soundcloud-api-ts-next";
36
+
37
+ export default function Layout({ children }) {
38
+ return <SoundCloudProvider apiPrefix="/api/soundcloud">{children}</SoundCloudProvider>;
39
+ }
40
+ ```
41
+
42
+ ### 3. Use Hooks
43
+
44
+ ```tsx
45
+ import { useTrack, useTrackSearch, usePlayer } from "soundcloud-api-ts-next";
46
+
47
+ const { data: track } = useTrack(123456);
48
+ const { data: results } = useTrackSearch("lofi");
49
+ const player = usePlayer(trackId);
50
+ ```
51
+
52
+ ## Key Concepts
53
+
54
+ 1. **All SoundCloud API calls go through your Next.js API routes** — client secrets never reach the browser
55
+ 2. **Hooks return `{ data, loading, error }`** — standard pattern for all data hooks
56
+ 3. **Infinite hooks return `{ data, loading, error, hasMore, loadMore, reset }`** — for scroll pagination
57
+ 4. **Action hooks return mutation functions** — `useLike().likeTrack(id)`, `useFollow().follow(id)`
58
+ 5. **Auth is managed via `useSCAuth()`** — handles OAuth redirect flow with PKCE
59
+
60
+ ## Project Structure
61
+
62
+ ```
63
+ src/
64
+ index.ts — Client-side exports (hooks, provider, types)
65
+ server.ts — Server-side exports (createSoundCloudRoutes)
66
+ client/ — React hooks and provider implementation
67
+ server/ — API route handler implementation
68
+ types.ts — Shared type definitions
69
+ ```
70
+
71
+ ## Build
72
+
73
+ ```bash
74
+ pnpm build # tsup → dist/ (ESM + CJS + .d.ts)
75
+ pnpm typecheck # tsc --noEmit
76
+ pnpm docs # TypeDoc → API docs site
77
+ ```
78
+
79
+ ## Publishing
80
+
81
+ Uses **Trusted Publishing** via GitHub Releases (same as soundcloud-api-ts).
82
+
83
+ ## Gotchas
84
+
85
+ 1. **Two entry points** — `soundcloud-api-ts-next` (client hooks) and `soundcloud-api-ts-next/server` (route handlers). Don't import server code in client components.
86
+ 2. **Provider required** — all hooks need `<SoundCloudProvider>` in the component tree.
87
+ 3. **API prefix must match** — the `apiPrefix` in the provider must match your route file path.
88
+ 4. **Auth hooks need redirectUri** — set `redirectUri` in `createSoundCloudRoutes` config for OAuth flow.
89
+
90
+ ## Related Packages
91
+
92
+ - [soundcloud-api-ts](https://github.com/twin-paws/soundcloud-api-ts) — The underlying API client (dependency)
93
+
94
+ ## Full Documentation
95
+
96
+ https://twin-paws.github.io/soundcloud-api-ts-next/
package/llms-full.txt ADDED
@@ -0,0 +1,325 @@
1
+ # soundcloud-api-ts-next
2
+
3
+ > React hooks and Next.js API route handlers for the SoundCloud API. Client secrets stay on the server.
4
+
5
+ ## What this package does
6
+ - Provides 25+ React hooks for accessing SoundCloud data (tracks, users, playlists, search)
7
+ - Provides 10 infinite scroll hooks with cursor-based pagination
8
+ - Provides secure Next.js API route handlers that keep OAuth credentials server-side
9
+ - Provides full OAuth 2.1 authentication with PKCE
10
+ - Provides mutation hooks for authenticated actions (like, follow, repost)
11
+ - Built on soundcloud-api-ts
12
+
13
+ ## When to use this package
14
+ - Building a Next.js app that needs SoundCloud data
15
+ - Building a music discovery or streaming app with React
16
+ - Need to search SoundCloud tracks, users, or playlists from a React app
17
+ - Need SoundCloud OAuth login in a Next.js app
18
+ - Need a SoundCloud audio player in React
19
+ - Want typed SoundCloud API access without exposing client secrets to the browser
20
+
21
+ ## When NOT to use this package
22
+ - Not using React or Next.js (use soundcloud-api-ts directly instead)
23
+ - Building a backend-only service (use soundcloud-api-ts directly)
24
+ - Need to download or scrape SoundCloud content (this is an API client, not a scraper)
25
+
26
+ ## Installation
27
+ npm install soundcloud-api-ts-next
28
+
29
+ ## Quick Setup
30
+ 1. Create API routes: import { createSoundCloudRoutes } from "soundcloud-api-ts-next/server"
31
+ 2. Wrap app with <SoundCloudProvider apiPrefix="/api/soundcloud">
32
+ 3. Use hooks: useTrack, useTrackSearch, useUser, usePlaylist, usePlayer, etc.
33
+
34
+ ## Key Exports (from "soundcloud-api-ts-next")
35
+
36
+ ### Hooks - General
37
+
38
+ ```ts
39
+ function useResolve(url: string | undefined): HookResult<any>
40
+ ```
41
+ Resolve a SoundCloud URL (e.g. `https://soundcloud.com/artist/track`) to a track, user, or playlist object.
42
+
43
+ ### Hooks - Tracks
44
+
45
+ ```ts
46
+ function useTrack(trackId: string | number | undefined): HookResult<SoundCloudTrack>
47
+ ```
48
+ Fetch a single track by ID.
49
+
50
+ ```ts
51
+ function useTrackSearch(query: string, options?: { limit?: number }): HookResult<SoundCloudTrack[]>
52
+ ```
53
+ Search tracks by query string. Optional limit parameter.
54
+
55
+ ```ts
56
+ function useTrackComments(trackId: string | number | undefined): HookResult<SoundCloudComment[]>
57
+ ```
58
+ Fetch comments on a track.
59
+
60
+ ```ts
61
+ function useTrackLikes(trackId: string | number | undefined): HookResult<SoundCloudUser[]>
62
+ ```
63
+ Fetch users who liked a track.
64
+
65
+ ```ts
66
+ function useRelatedTracks(trackId: string | number | undefined): HookResult<SoundCloudTrack[]>
67
+ ```
68
+ Fetch tracks related to the given track.
69
+
70
+ ```ts
71
+ function usePlayer(trackId: string | number | undefined): PlayerState
72
+ ```
73
+ Audio player hook. Returns:
74
+ ```ts
75
+ interface PlayerState {
76
+ playing: boolean;
77
+ progress: number; // current position in seconds
78
+ duration: number; // total duration in seconds
79
+ play: () => void;
80
+ pause: () => void;
81
+ toggle: () => void;
82
+ seek: (time: number) => void;
83
+ }
84
+ ```
85
+
86
+ ### Hooks - Users
87
+
88
+ ```ts
89
+ function useUser(userId: string | number | undefined): HookResult<SoundCloudUser>
90
+ ```
91
+ Fetch a single user by ID.
92
+
93
+ ```ts
94
+ function useUserSearch(query: string): HookResult<SoundCloudUser[]>
95
+ ```
96
+ Search users by query string.
97
+
98
+ ```ts
99
+ function useUserTracks(userId: string | number | undefined): HookResult<SoundCloudTrack[]>
100
+ ```
101
+ Fetch a user's tracks.
102
+
103
+ ```ts
104
+ function useUserPlaylists(userId: string | number | undefined): HookResult<SoundCloudPlaylist[]>
105
+ ```
106
+ Fetch a user's playlists.
107
+
108
+ ```ts
109
+ function useUserLikes(userId: string | number | undefined): HookResult<SoundCloudTrack[]>
110
+ ```
111
+ Fetch a user's liked tracks.
112
+
113
+ ```ts
114
+ function useUserFollowers(userId: string | number | undefined): HookResult<SoundCloudUser[]>
115
+ ```
116
+ Fetch a user's followers.
117
+
118
+ ```ts
119
+ function useUserFollowings(userId: string | number | undefined): HookResult<SoundCloudUser[]>
120
+ ```
121
+ Fetch a user's followings.
122
+
123
+ ### Hooks - Playlists
124
+
125
+ ```ts
126
+ function usePlaylist(playlistId: string | number | undefined): HookResult<SoundCloudPlaylist>
127
+ ```
128
+ Fetch a single playlist by ID.
129
+
130
+ ```ts
131
+ function usePlaylistSearch(query: string): HookResult<SoundCloudPlaylist[]>
132
+ ```
133
+ Search playlists by query string.
134
+
135
+ ```ts
136
+ function usePlaylistTracks(playlistId: string | number | undefined): HookResult<SoundCloudTrack[]>
137
+ ```
138
+ Fetch tracks in a playlist.
139
+
140
+ ### Hooks - Infinite Scroll
141
+
142
+ All infinite hooks return:
143
+ ```ts
144
+ interface InfiniteResult<T> {
145
+ data: T[];
146
+ loading: boolean;
147
+ error: Error | null;
148
+ hasMore: boolean;
149
+ loadMore: () => void;
150
+ reset: () => void;
151
+ }
152
+ ```
153
+
154
+ ```ts
155
+ function useInfiniteTrackSearch(query: string, options?: { limit?: number }): InfiniteResult<SoundCloudTrack>
156
+ function useInfiniteUserSearch(query: string, options?: { limit?: number }): InfiniteResult<SoundCloudUser>
157
+ function useInfinitePlaylistSearch(query: string, options?: { limit?: number }): InfiniteResult<SoundCloudPlaylist>
158
+ function useInfiniteUserTracks(userId: string | number | null): InfiniteResult<SoundCloudTrack>
159
+ function useInfiniteUserPlaylists(userId: string | number | null): InfiniteResult<SoundCloudPlaylist>
160
+ function useInfiniteUserLikes(userId: string | number | null): InfiniteResult<SoundCloudTrack>
161
+ function useInfiniteUserFollowers(userId: string | number | null): InfiniteResult<SoundCloudUser>
162
+ function useInfiniteUserFollowings(userId: string | number | null): InfiniteResult<SoundCloudUser>
163
+ function useInfiniteTrackComments(trackId: string | number | null): InfiniteResult<SoundCloudComment>
164
+ function useInfinitePlaylistTracks(playlistId: string | number | null): InfiniteResult<SoundCloudTrack>
165
+ ```
166
+
167
+ ### Hooks - Authentication
168
+
169
+ ```ts
170
+ function useSCAuth(): {
171
+ user: SoundCloudUser | null;
172
+ isAuthenticated: boolean;
173
+ loading: boolean;
174
+ login: () => void;
175
+ logout: () => void;
176
+ handleCallback: (code: string, state: string) => Promise<SoundCloudToken>;
177
+ }
178
+ ```
179
+ Full OAuth 2.1 with PKCE. Redirects to SoundCloud for login, exchanges code for tokens.
180
+
181
+ ```ts
182
+ function useMe(): HookResult<SoundCloudUser>
183
+ ```
184
+ Current authenticated user profile.
185
+
186
+ ```ts
187
+ function useMeTracks(): HookResult<SoundCloudTrack[]>
188
+ ```
189
+ Current user's tracks.
190
+
191
+ ```ts
192
+ function useMeLikes(): HookResult<SoundCloudTrack[]>
193
+ ```
194
+ Current user's liked tracks.
195
+
196
+ ```ts
197
+ function useMePlaylists(): HookResult<SoundCloudPlaylist[]>
198
+ ```
199
+ Current user's playlists.
200
+
201
+ ```ts
202
+ function useMeFollowings(): HookResult<SoundCloudUser[]>
203
+ ```
204
+ Users the current user follows.
205
+
206
+ ```ts
207
+ function useMeFollowers(): HookResult<SoundCloudUser[]>
208
+ ```
209
+ Current user's followers.
210
+
211
+ ### Hooks - Actions (authenticated)
212
+
213
+ ```ts
214
+ function useLike(): {
215
+ likeTrack: (trackId: string | number) => Promise<void>;
216
+ unlikeTrack: (trackId: string | number) => Promise<void>;
217
+ loading: boolean;
218
+ error: Error | null;
219
+ }
220
+ ```
221
+ Like or unlike a track. Requires authentication.
222
+
223
+ ```ts
224
+ function useFollow(): {
225
+ follow: (userId: string | number) => Promise<void>;
226
+ unfollow: (userId: string | number) => Promise<void>;
227
+ loading: boolean;
228
+ error: Error | null;
229
+ }
230
+ ```
231
+ Follow or unfollow a user. Requires authentication.
232
+
233
+ ```ts
234
+ function useRepost(): {
235
+ repostTrack: (trackId: string | number) => Promise<void>;
236
+ unrepostTrack: (trackId: string | number) => Promise<void>;
237
+ loading: boolean;
238
+ error: Error | null;
239
+ }
240
+ ```
241
+ Repost or unrepost a track. Requires authentication.
242
+
243
+ ### Provider
244
+
245
+ ```tsx
246
+ <SoundCloudProvider apiPrefix="/api/soundcloud">
247
+ {children}
248
+ </SoundCloudProvider>
249
+ ```
250
+ Wraps app, configures API route prefix, manages auth state.
251
+
252
+ ## Key Exports (from "soundcloud-api-ts-next/server")
253
+
254
+ ```ts
255
+ function createSoundCloudRoutes(config: {
256
+ clientId: string;
257
+ clientSecret: string;
258
+ redirectUri?: string;
259
+ getToken?: () => Promise<string>; // custom token provider (e.g. Redis, database)
260
+ }): SoundCloudRoutes
261
+ ```
262
+
263
+ Returns an object with:
264
+ - `.handler()` — App Router catch-all handler (assign to GET, POST, DELETE)
265
+ - `.pagesHandler()` — Pages Router catch-all handler
266
+ - `.resolveUrl(url)` — resolve a SoundCloud URL to an API resource
267
+ - `.searchTracks(q)`, `.getTrack(id)`, `.getUser(id)`, etc. — individual server-side methods
268
+
269
+ When `getToken` is provided, it replaces the built-in client credentials flow for all public routes. Auth routes (`/me/*`, actions) still use the `Authorization: Bearer` header from the request.
270
+
271
+ ## Common Types
272
+
273
+ ```ts
274
+ interface HookResult<T> {
275
+ data: T | null;
276
+ loading: boolean;
277
+ error: Error | null;
278
+ }
279
+
280
+ interface InfiniteResult<T> {
281
+ data: T[];
282
+ loading: boolean;
283
+ error: Error | null;
284
+ hasMore: boolean;
285
+ loadMore: () => void;
286
+ reset: () => void;
287
+ }
288
+
289
+ interface PlayerState {
290
+ playing: boolean;
291
+ progress: number;
292
+ duration: number;
293
+ play: () => void;
294
+ pause: () => void;
295
+ toggle: () => void;
296
+ seek: (time: number) => void;
297
+ }
298
+
299
+ interface SoundCloudRoutesConfig {
300
+ clientId: string;
301
+ clientSecret: string;
302
+ redirectUri?: string;
303
+ getToken?: () => Promise<string>;
304
+ }
305
+
306
+ interface SoundCloudToken {
307
+ access_token: string;
308
+ refresh_token: string;
309
+ expires_in: number;
310
+ token_type: string;
311
+ scope: string;
312
+ }
313
+ ```
314
+
315
+ ## TypeScript types (re-exported from soundcloud-api-ts)
316
+ SoundCloudTrack, SoundCloudUser, SoundCloudPlaylist, SoundCloudComment, SoundCloudStreams, SoundCloudToken, SoundCloudPaginatedResponse, SoundCloudMe, SoundCloudWebProfile, SoundCloudActivity, SoundCloudActivitiesResponse
317
+
318
+ ## Related packages
319
+ - soundcloud-api-ts — TypeScript-first SoundCloud API client (dependency)
320
+
321
+ ## Links
322
+ - npm: https://www.npmjs.com/package/soundcloud-api-ts-next
323
+ - GitHub: https://github.com/twin-paws/soundcloud-api-ts-next
324
+ - API Docs: https://twin-paws.github.io/soundcloud-api-ts-next/
325
+ - API client: https://github.com/twin-paws/soundcloud-api-ts
package/llms.txt ADDED
@@ -0,0 +1,104 @@
1
+ # soundcloud-api-ts-next
2
+
3
+ > React hooks and Next.js API route handlers for the SoundCloud API. Client secrets stay on the server.
4
+
5
+ ## What this package does
6
+ - Provides 25+ React hooks for accessing SoundCloud data (tracks, users, playlists, search)
7
+ - Provides 10 infinite scroll hooks with cursor-based pagination
8
+ - Provides secure Next.js API route handlers that keep OAuth credentials server-side
9
+ - Provides full OAuth 2.1 authentication with PKCE
10
+ - Provides mutation hooks for authenticated actions (like, follow, repost)
11
+ - Built on soundcloud-api-ts
12
+
13
+ ## When to use this package
14
+ - Building a Next.js app that needs SoundCloud data
15
+ - Building a music discovery or streaming app with React
16
+ - Need to search SoundCloud tracks, users, or playlists from a React app
17
+ - Need SoundCloud OAuth login in a Next.js app
18
+ - Need a SoundCloud audio player in React
19
+ - Want typed SoundCloud API access without exposing client secrets to the browser
20
+
21
+ ## When NOT to use this package
22
+ - Not using React or Next.js (use soundcloud-api-ts directly instead)
23
+ - Building a backend-only service (use soundcloud-api-ts directly)
24
+ - Need to download or scrape SoundCloud content (this is an API client, not a scraper)
25
+
26
+ ## Installation
27
+ npm install soundcloud-api-ts-next
28
+
29
+ ## Quick Setup
30
+ 1. Create API routes: import { createSoundCloudRoutes } from "soundcloud-api-ts-next/server"
31
+ 2. Wrap app with <SoundCloudProvider apiPrefix="/api/soundcloud">
32
+ 3. Use hooks: useTrack, useTrackSearch, useUser, usePlaylist, usePlayer, etc.
33
+
34
+ ## Key Exports (from "soundcloud-api-ts-next")
35
+ ### Hooks - General
36
+ - useResolve(url) — resolve a SoundCloud URL to a track, user, or playlist
37
+
38
+ ### Hooks - Tracks
39
+ - useTrack(trackId) — fetch single track
40
+ - useTrackSearch(query) — search tracks
41
+ - useTrackComments(trackId) — track comments
42
+ - useTrackLikes(trackId) — users who liked track
43
+ - useRelatedTracks(trackId) — related tracks
44
+ - usePlayer(streamUrl) — audio player with play/pause/seek
45
+
46
+ ### Hooks - Users
47
+ - useUser(userId) — fetch single user
48
+ - useUserSearch(query) — search users
49
+ - useUserTracks(userId) — user's tracks
50
+ - useUserPlaylists(userId) — user's playlists
51
+ - useUserLikes(userId) — user's liked tracks
52
+ - useUserFollowers(userId) — user's followers
53
+ - useUserFollowings(userId) — user's followings
54
+
55
+ ### Hooks - Playlists
56
+ - usePlaylist(playlistId) — fetch single playlist
57
+ - usePlaylistSearch(query) — search playlists
58
+ - usePlaylistTracks(playlistId) — playlist tracks
59
+
60
+ ### Hooks - Infinite Scroll
61
+ All return { data: T[], loading, error, hasMore, loadMore, reset }
62
+ - useInfiniteTrackSearch, useInfiniteUserSearch, useInfinitePlaylistSearch
63
+ - useInfiniteUserTracks, useInfiniteUserPlaylists, useInfiniteUserLikes
64
+ - useInfiniteUserFollowers, useInfiniteUserFollowings
65
+ - useInfiniteTrackComments, useInfinitePlaylistTracks
66
+
67
+ ### Hooks - Authentication
68
+ - useSCAuth() — { isAuthenticated, user, login, logout, handleCallback }
69
+ - useMe() — current user profile
70
+ - useMeTracks() — your tracks
71
+ - useMeLikes() — your liked tracks
72
+ - useMePlaylists() — your playlists
73
+ - useMeFollowings() — who you follow
74
+ - useMeFollowers() — your followers
75
+
76
+ ### Hooks - Actions (authenticated)
77
+ - useLike() — { likeTrack(id), unlikeTrack(id) }
78
+ - useFollow() — { follow(userId), unfollow(userId) }
79
+ - useRepost() — { repostTrack(id), unrepostTrack(id) }
80
+
81
+ ### Provider
82
+ - SoundCloudProvider — wraps app, configures API route prefix
83
+
84
+ ## Key Exports (from "soundcloud-api-ts-next/server")
85
+ - createSoundCloudRoutes({ clientId, clientSecret, redirectUri?, getToken? }) — creates route handlers
86
+ - getToken: optional async function returning a token string (for custom token stores like Redis)
87
+ - .handler() — App Router catch-all (assign to GET, POST, DELETE)
88
+ - .pagesHandler() — Pages Router catch-all
89
+ - .resolveUrl(url) — resolve a SoundCloud URL server-side
90
+ - .searchTracks(q), .getTrack(id), .getUser(id), etc. — individual methods
91
+
92
+ ## All hooks return
93
+ { data: T | null, loading: boolean, error: Error | null }
94
+
95
+ ## TypeScript types (re-exported from soundcloud-api-ts)
96
+ SoundCloudTrack, SoundCloudUser, SoundCloudPlaylist, SoundCloudComment, SoundCloudStreams, SoundCloudToken
97
+
98
+ ## Related packages
99
+ - soundcloud-api-ts — TypeScript-first SoundCloud API client (dependency)
100
+
101
+ ## Links
102
+ - npm: https://www.npmjs.com/package/soundcloud-api-ts-next
103
+ - GitHub: https://github.com/twin-paws/soundcloud-api-ts-next
104
+ - API client: https://github.com/twin-paws/soundcloud-api-ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "soundcloud-api-ts-next",
3
- "version": "1.7.2",
3
+ "version": "1.7.3",
4
4
  "description": "TypeScript SoundCloud API React hooks and Next.js API route handlers — App Router, Pages Router, OAuth PKCE, secrets stay server-side",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -44,7 +44,10 @@
44
44
  "module": "./dist/index.mjs",
45
45
  "types": "./dist/index.d.ts",
46
46
  "files": [
47
- "dist"
47
+ "dist",
48
+ "llms.txt",
49
+ "llms-full.txt",
50
+ "AGENTS.md"
48
51
  ],
49
52
  "scripts": {
50
53
  "build": "tsup",