soundcloud-api-ts-next 1.0.0 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,38 +1,56 @@
1
1
  # soundcloud-api-ts-next
2
2
 
3
- React hooks and Next.js API route handlers for the SoundCloud API. Client secrets stay on the server.
3
+ Next.js integration for [soundcloud-api-ts](https://github.com/twin-paws/soundcloud-api-ts) React hooks + secure API route handlers.
4
4
 
5
- Built on top of [`soundcloud-api-ts`](https://github.com/twin-paws/soundcloud-api-ts).
6
-
7
- ## Install
5
+ ## Installation
8
6
 
9
7
  ```bash
10
- pnpm add soundcloud-api-ts-next soundcloud-api-ts
8
+ npm install soundcloud-api-ts-next
9
+ # or
10
+ pnpm add soundcloud-api-ts-next
11
11
  ```
12
12
 
13
- ## Quick Start
13
+ ## Setup
14
+
15
+ ### 1. Server Routes
16
+
17
+ Create an API route handler that proxies SoundCloud requests (keeps your credentials server-side).
14
18
 
15
- ### 1. Set up the API route (App Router)
19
+ **App Router** (`app/api/soundcloud/[...route]/route.ts`):
16
20
 
17
21
  ```ts
18
- // app/api/soundcloud/[...route]/route.ts
19
22
  import { createSoundCloudRoutes } from "soundcloud-api-ts-next/server";
20
23
 
21
24
  const sc = createSoundCloudRoutes({
22
- clientId: process.env.SC_CLIENT_ID!,
23
- clientSecret: process.env.SC_CLIENT_SECRET!,
25
+ clientId: process.env.SOUNDCLOUD_CLIENT_ID!,
26
+ clientSecret: process.env.SOUNDCLOUD_CLIENT_SECRET!,
24
27
  });
25
28
 
26
- export const GET = sc.handler();
29
+ const handler = sc.handler();
30
+ export const GET = handler;
27
31
  ```
28
32
 
29
- ### 2. Wrap your app with the provider
33
+ **Pages Router** (`pages/api/soundcloud/[...route].ts`):
34
+
35
+ ```ts
36
+ import { createSoundCloudRoutes } from "soundcloud-api-ts-next/server";
37
+
38
+ const sc = createSoundCloudRoutes({
39
+ clientId: process.env.SOUNDCLOUD_CLIENT_ID!,
40
+ clientSecret: process.env.SOUNDCLOUD_CLIENT_SECRET!,
41
+ });
42
+
43
+ export default sc.pagesHandler();
44
+ ```
45
+
46
+ ### 2. Client Provider
47
+
48
+ Wrap your app with the `SoundCloudProvider`:
30
49
 
31
50
  ```tsx
32
- // app/layout.tsx
33
51
  import { SoundCloudProvider } from "soundcloud-api-ts-next";
34
52
 
35
- export default function RootLayout({ children }) {
53
+ export default function Layout({ children }) {
36
54
  return (
37
55
  <SoundCloudProvider apiPrefix="/api/soundcloud">
38
56
  {children}
@@ -41,94 +59,100 @@ export default function RootLayout({ children }) {
41
59
  }
42
60
  ```
43
61
 
44
- ### 3. Use hooks in your components
45
-
46
- ```tsx
47
- "use client";
48
- import { useTrackSearch } from "soundcloud-api-ts-next";
62
+ ## Hooks
49
63
 
50
- export function Search() {
51
- const { data, loading, error } = useTrackSearch("lofi beats", { limit: 10 });
64
+ All hooks return `{ data, loading, error }`.
52
65
 
53
- if (loading) return <p>Loading...</p>;
54
- if (error) return <p>Error: {error.message}</p>;
66
+ ### Tracks
55
67
 
56
- return (
57
- <ul>
58
- {data?.map((track) => (
59
- <li key={track.id}>{track.title}</li>
60
- ))}
61
- </ul>
62
- );
63
- }
64
- ```
68
+ | Hook | Arguments | Description |
69
+ |------|-----------|-------------|
70
+ | `useTrack(trackId)` | `string \| number \| undefined` | Fetch a single track |
71
+ | `useTrackSearch(query, options?)` | `string`, `{ limit? }` | Search tracks |
72
+ | `useTrackComments(trackId)` | `string \| number \| undefined` | Get track comments |
73
+ | `useTrackLikes(trackId)` | `string \| number \| undefined` | Get users who liked a track |
74
+ | `useRelatedTracks(trackId)` | `string \| number \| undefined` | Get related tracks |
65
75
 
66
- ## Pages Router Setup
76
+ ### Users
67
77
 
68
- ```ts
69
- // pages/api/soundcloud/[...route].ts
70
- import { createSoundCloudRoutes } from "soundcloud-api-ts-next/server";
78
+ | Hook | Arguments | Description |
79
+ |------|-----------|-------------|
80
+ | `useUser(userId)` | `string \| number \| undefined` | Fetch a single user |
81
+ | `useUserSearch(query)` | `string` | Search users |
82
+ | `useUserTracks(userId)` | `string \| number \| undefined` | Get a user's tracks |
83
+ | `useUserPlaylists(userId)` | `string \| number \| undefined` | Get a user's playlists |
84
+ | `useUserLikes(userId)` | `string \| number \| undefined` | Get a user's liked tracks |
85
+ | `useUserFollowers(userId)` | `string \| number \| undefined` | Get a user's followers |
86
+ | `useUserFollowings(userId)` | `string \| number \| undefined` | Get a user's followings |
71
87
 
72
- const sc = createSoundCloudRoutes({
73
- clientId: process.env.SC_CLIENT_ID!,
74
- clientSecret: process.env.SC_CLIENT_SECRET!,
75
- });
88
+ ### Playlists
76
89
 
77
- export default sc.pagesHandler();
78
- ```
90
+ | Hook | Arguments | Description |
91
+ |------|-----------|-------------|
92
+ | `usePlaylist(playlistId)` | `string \| number \| undefined` | Fetch a single playlist |
93
+ | `usePlaylistTracks(playlistId)` | `string \| number \| undefined` | Get tracks in a playlist |
94
+ | `usePlaylistSearch(query)` | `string` | Search playlists |
79
95
 
80
- ## Hooks
96
+ ### Player
81
97
 
82
- ### `useTrackSearch(query: string, options?: { limit?: number })`
98
+ | Hook | Arguments | Description |
99
+ |------|-----------|-------------|
100
+ | `usePlayer(streamUrl)` | `string \| undefined` | Audio player with play/pause/seek |
83
101
 
84
- Search for tracks. Returns `{ data: SoundCloudTrack[] | null, loading, error }`.
102
+ ## Server Routes
85
103
 
86
- ### `useTrack(trackId: string | number)`
104
+ All routes are available via the catch-all handler and as individual methods on the routes object.
87
105
 
88
- Fetch a single track by ID. Returns `{ data: SoundCloudTrack | null, loading, error }`.
106
+ ### Search
89
107
 
90
- ### `useUser(userId: string | number)`
108
+ | Route | Method | Description |
109
+ |-------|--------|-------------|
110
+ | `GET /search/tracks?q=...` | `searchTracks(q, page?)` | Search tracks |
111
+ | `GET /search/users?q=...` | `searchUsers(q)` | Search users |
112
+ | `GET /search/playlists?q=...` | `searchPlaylists(q)` | Search playlists |
91
113
 
92
- Fetch a single user by ID. Returns `{ data: SoundCloudUser | null, loading, error }`.
114
+ ### Tracks
93
115
 
94
- ### `usePlayer(trackId: string | number)`
116
+ | Route | Method | Description |
117
+ |-------|--------|-------------|
118
+ | `GET /tracks/:id` | `getTrack(id)` | Get track details |
119
+ | `GET /tracks/:id/stream` | `getTrackStreams(id)` | Get stream URLs |
120
+ | `GET /tracks/:id/comments` | `getTrackComments(id)` | Get track comments |
121
+ | `GET /tracks/:id/likes` | `getTrackLikes(id)` | Get track likes |
122
+ | `GET /tracks/:id/related` | `getRelatedTracks(id)` | Get related tracks |
95
123
 
96
- Manages an HTML5 Audio element for streaming. Returns:
124
+ ### Users
97
125
 
98
- ```ts
99
- {
100
- playing: boolean;
101
- progress: number; // current time in seconds
102
- duration: number; // total duration in seconds
103
- play(): void;
104
- pause(): void;
105
- toggle(): void;
106
- seek(time: number): void;
107
- }
108
- ```
126
+ | Route | Method | Description |
127
+ |-------|--------|-------------|
128
+ | `GET /users/:id` | `getUser(id)` | Get user details |
129
+ | `GET /users/:id/tracks` | `getUserTracks(id, limit?)` | Get user's tracks |
130
+ | `GET /users/:id/playlists` | `getUserPlaylists(id)` | Get user's playlists |
131
+ | `GET /users/:id/likes/tracks` | `getUserLikesTracks(id)` | Get user's liked tracks |
132
+ | `GET /users/:id/followers` | `getFollowers(id)` | Get user's followers |
133
+ | `GET /users/:id/followings` | `getFollowings(id)` | Get user's followings |
109
134
 
110
- ## API Routes
135
+ ### Playlists
111
136
 
112
- The server handler supports these routes:
137
+ | Route | Method | Description |
138
+ |-------|--------|-------------|
139
+ | `GET /playlists/:id` | `getPlaylist(id)` | Get playlist details |
140
+ | `GET /playlists/:id/tracks` | `getPlaylistTracks(id)` | Get playlist tracks |
113
141
 
114
- | Route | Description |
115
- |---|---|
116
- | `/search/tracks?q=...&page=...` | Search tracks |
117
- | `/tracks/:id` | Get track by ID |
118
- | `/tracks/:id/stream` | Get stream URLs for a track |
119
- | `/users/:id` | Get user by ID |
120
- | `/users/:id/tracks` | Get user's tracks |
142
+ ## Types
121
143
 
122
- ## Provider
144
+ All SoundCloud types are re-exported from `soundcloud-api-ts`:
123
145
 
124
- ```tsx
125
- <SoundCloudProvider apiPrefix="/api/soundcloud">
126
- {children}
127
- </SoundCloudProvider>
146
+ ```ts
147
+ import type {
148
+ SoundCloudTrack,
149
+ SoundCloudUser,
150
+ SoundCloudPlaylist,
151
+ SoundCloudComment,
152
+ SoundCloudStreams,
153
+ } from "soundcloud-api-ts-next";
128
154
  ```
129
155
 
130
- The `apiPrefix` prop configures where the hooks send requests. Default: `"/api/soundcloud"`.
131
-
132
156
  ## License
133
157
 
134
158
  MIT
package/dist/index.cjs CHANGED
@@ -170,10 +170,336 @@ function usePlayer(trackId) {
170
170
  return { playing, progress, duration, play, pause, toggle, seek };
171
171
  }
172
172
 
173
+ // src/client/hooks/useUserTracks.ts
174
+
175
+ function useUserTracks(userId) {
176
+ const { apiPrefix } = useSoundCloudContext();
177
+ const [data, setData] = _react.useState.call(void 0, null);
178
+ const [loading, setLoading] = _react.useState.call(void 0, false);
179
+ const [error, setError] = _react.useState.call(void 0, null);
180
+ _react.useEffect.call(void 0, () => {
181
+ if (userId == null) {
182
+ setData(null);
183
+ return;
184
+ }
185
+ const controller = new AbortController();
186
+ setLoading(true);
187
+ setError(null);
188
+ fetch(`${apiPrefix}/users/${userId}/tracks`, { signal: controller.signal }).then((res) => {
189
+ if (!res.ok) throw new Error(`HTTP ${res.status}`);
190
+ return res.json();
191
+ }).then((json) => setData(_nullishCoalesce(json.collection, () => ( json)))).catch((err) => {
192
+ if (err.name !== "AbortError") setError(err);
193
+ }).finally(() => setLoading(false));
194
+ return () => controller.abort();
195
+ }, [userId, apiPrefix]);
196
+ return { data, loading, error };
197
+ }
198
+
199
+ // src/client/hooks/useUserPlaylists.ts
200
+
201
+ function useUserPlaylists(userId) {
202
+ const { apiPrefix } = useSoundCloudContext();
203
+ const [data, setData] = _react.useState.call(void 0, null);
204
+ const [loading, setLoading] = _react.useState.call(void 0, false);
205
+ const [error, setError] = _react.useState.call(void 0, null);
206
+ _react.useEffect.call(void 0, () => {
207
+ if (userId == null) {
208
+ setData(null);
209
+ return;
210
+ }
211
+ const controller = new AbortController();
212
+ setLoading(true);
213
+ setError(null);
214
+ fetch(`${apiPrefix}/users/${userId}/playlists`, { signal: controller.signal }).then((res) => {
215
+ if (!res.ok) throw new Error(`HTTP ${res.status}`);
216
+ return res.json();
217
+ }).then((json) => setData(_nullishCoalesce(json.collection, () => ( json)))).catch((err) => {
218
+ if (err.name !== "AbortError") setError(err);
219
+ }).finally(() => setLoading(false));
220
+ return () => controller.abort();
221
+ }, [userId, apiPrefix]);
222
+ return { data, loading, error };
223
+ }
224
+
225
+ // src/client/hooks/useUserLikes.ts
226
+
227
+ function useUserLikes(userId) {
228
+ const { apiPrefix } = useSoundCloudContext();
229
+ const [data, setData] = _react.useState.call(void 0, null);
230
+ const [loading, setLoading] = _react.useState.call(void 0, false);
231
+ const [error, setError] = _react.useState.call(void 0, null);
232
+ _react.useEffect.call(void 0, () => {
233
+ if (userId == null) {
234
+ setData(null);
235
+ return;
236
+ }
237
+ const controller = new AbortController();
238
+ setLoading(true);
239
+ setError(null);
240
+ fetch(`${apiPrefix}/users/${userId}/likes/tracks`, { signal: controller.signal }).then((res) => {
241
+ if (!res.ok) throw new Error(`HTTP ${res.status}`);
242
+ return res.json();
243
+ }).then((json) => setData(_nullishCoalesce(json.collection, () => ( json)))).catch((err) => {
244
+ if (err.name !== "AbortError") setError(err);
245
+ }).finally(() => setLoading(false));
246
+ return () => controller.abort();
247
+ }, [userId, apiPrefix]);
248
+ return { data, loading, error };
249
+ }
250
+
251
+ // src/client/hooks/useUserFollowers.ts
252
+
253
+ function useUserFollowers(userId) {
254
+ const { apiPrefix } = useSoundCloudContext();
255
+ const [data, setData] = _react.useState.call(void 0, null);
256
+ const [loading, setLoading] = _react.useState.call(void 0, false);
257
+ const [error, setError] = _react.useState.call(void 0, null);
258
+ _react.useEffect.call(void 0, () => {
259
+ if (userId == null) {
260
+ setData(null);
261
+ return;
262
+ }
263
+ const controller = new AbortController();
264
+ setLoading(true);
265
+ setError(null);
266
+ fetch(`${apiPrefix}/users/${userId}/followers`, { signal: controller.signal }).then((res) => {
267
+ if (!res.ok) throw new Error(`HTTP ${res.status}`);
268
+ return res.json();
269
+ }).then((json) => setData(_nullishCoalesce(json.collection, () => ( json)))).catch((err) => {
270
+ if (err.name !== "AbortError") setError(err);
271
+ }).finally(() => setLoading(false));
272
+ return () => controller.abort();
273
+ }, [userId, apiPrefix]);
274
+ return { data, loading, error };
275
+ }
276
+
277
+ // src/client/hooks/useUserFollowings.ts
278
+
279
+ function useUserFollowings(userId) {
280
+ const { apiPrefix } = useSoundCloudContext();
281
+ const [data, setData] = _react.useState.call(void 0, null);
282
+ const [loading, setLoading] = _react.useState.call(void 0, false);
283
+ const [error, setError] = _react.useState.call(void 0, null);
284
+ _react.useEffect.call(void 0, () => {
285
+ if (userId == null) {
286
+ setData(null);
287
+ return;
288
+ }
289
+ const controller = new AbortController();
290
+ setLoading(true);
291
+ setError(null);
292
+ fetch(`${apiPrefix}/users/${userId}/followings`, { signal: controller.signal }).then((res) => {
293
+ if (!res.ok) throw new Error(`HTTP ${res.status}`);
294
+ return res.json();
295
+ }).then((json) => setData(_nullishCoalesce(json.collection, () => ( json)))).catch((err) => {
296
+ if (err.name !== "AbortError") setError(err);
297
+ }).finally(() => setLoading(false));
298
+ return () => controller.abort();
299
+ }, [userId, apiPrefix]);
300
+ return { data, loading, error };
301
+ }
302
+
303
+ // src/client/hooks/useTrackComments.ts
304
+
305
+ function useTrackComments(trackId) {
306
+ const { apiPrefix } = useSoundCloudContext();
307
+ const [data, setData] = _react.useState.call(void 0, null);
308
+ const [loading, setLoading] = _react.useState.call(void 0, false);
309
+ const [error, setError] = _react.useState.call(void 0, null);
310
+ _react.useEffect.call(void 0, () => {
311
+ if (trackId == null) {
312
+ setData(null);
313
+ return;
314
+ }
315
+ const controller = new AbortController();
316
+ setLoading(true);
317
+ setError(null);
318
+ fetch(`${apiPrefix}/tracks/${trackId}/comments`, { signal: controller.signal }).then((res) => {
319
+ if (!res.ok) throw new Error(`HTTP ${res.status}`);
320
+ return res.json();
321
+ }).then((json) => setData(_nullishCoalesce(json.collection, () => ( json)))).catch((err) => {
322
+ if (err.name !== "AbortError") setError(err);
323
+ }).finally(() => setLoading(false));
324
+ return () => controller.abort();
325
+ }, [trackId, apiPrefix]);
326
+ return { data, loading, error };
327
+ }
328
+
329
+ // src/client/hooks/useTrackLikes.ts
330
+
331
+ function useTrackLikes(trackId) {
332
+ const { apiPrefix } = useSoundCloudContext();
333
+ const [data, setData] = _react.useState.call(void 0, null);
334
+ const [loading, setLoading] = _react.useState.call(void 0, false);
335
+ const [error, setError] = _react.useState.call(void 0, null);
336
+ _react.useEffect.call(void 0, () => {
337
+ if (trackId == null) {
338
+ setData(null);
339
+ return;
340
+ }
341
+ const controller = new AbortController();
342
+ setLoading(true);
343
+ setError(null);
344
+ fetch(`${apiPrefix}/tracks/${trackId}/likes`, { signal: controller.signal }).then((res) => {
345
+ if (!res.ok) throw new Error(`HTTP ${res.status}`);
346
+ return res.json();
347
+ }).then((json) => setData(_nullishCoalesce(json.collection, () => ( json)))).catch((err) => {
348
+ if (err.name !== "AbortError") setError(err);
349
+ }).finally(() => setLoading(false));
350
+ return () => controller.abort();
351
+ }, [trackId, apiPrefix]);
352
+ return { data, loading, error };
353
+ }
354
+
355
+ // src/client/hooks/useRelatedTracks.ts
356
+
357
+ function useRelatedTracks(trackId) {
358
+ const { apiPrefix } = useSoundCloudContext();
359
+ const [data, setData] = _react.useState.call(void 0, null);
360
+ const [loading, setLoading] = _react.useState.call(void 0, false);
361
+ const [error, setError] = _react.useState.call(void 0, null);
362
+ _react.useEffect.call(void 0, () => {
363
+ if (trackId == null) {
364
+ setData(null);
365
+ return;
366
+ }
367
+ const controller = new AbortController();
368
+ setLoading(true);
369
+ setError(null);
370
+ fetch(`${apiPrefix}/tracks/${trackId}/related`, { signal: controller.signal }).then((res) => {
371
+ if (!res.ok) throw new Error(`HTTP ${res.status}`);
372
+ return res.json();
373
+ }).then((json) => setData(_nullishCoalesce(json.collection, () => ( json)))).catch((err) => {
374
+ if (err.name !== "AbortError") setError(err);
375
+ }).finally(() => setLoading(false));
376
+ return () => controller.abort();
377
+ }, [trackId, apiPrefix]);
378
+ return { data, loading, error };
379
+ }
380
+
381
+ // src/client/hooks/usePlaylist.ts
382
+
383
+ function usePlaylist(playlistId) {
384
+ const { apiPrefix } = useSoundCloudContext();
385
+ const [data, setData] = _react.useState.call(void 0, null);
386
+ const [loading, setLoading] = _react.useState.call(void 0, false);
387
+ const [error, setError] = _react.useState.call(void 0, null);
388
+ _react.useEffect.call(void 0, () => {
389
+ if (playlistId == null) {
390
+ setData(null);
391
+ return;
392
+ }
393
+ const controller = new AbortController();
394
+ setLoading(true);
395
+ setError(null);
396
+ fetch(`${apiPrefix}/playlists/${playlistId}`, { signal: controller.signal }).then((res) => {
397
+ if (!res.ok) throw new Error(`HTTP ${res.status}`);
398
+ return res.json();
399
+ }).then(setData).catch((err) => {
400
+ if (err.name !== "AbortError") setError(err);
401
+ }).finally(() => setLoading(false));
402
+ return () => controller.abort();
403
+ }, [playlistId, apiPrefix]);
404
+ return { data, loading, error };
405
+ }
406
+
407
+ // src/client/hooks/usePlaylistTracks.ts
408
+
409
+ function usePlaylistTracks(playlistId) {
410
+ const { apiPrefix } = useSoundCloudContext();
411
+ const [data, setData] = _react.useState.call(void 0, null);
412
+ const [loading, setLoading] = _react.useState.call(void 0, false);
413
+ const [error, setError] = _react.useState.call(void 0, null);
414
+ _react.useEffect.call(void 0, () => {
415
+ if (playlistId == null) {
416
+ setData(null);
417
+ return;
418
+ }
419
+ const controller = new AbortController();
420
+ setLoading(true);
421
+ setError(null);
422
+ fetch(`${apiPrefix}/playlists/${playlistId}/tracks`, { signal: controller.signal }).then((res) => {
423
+ if (!res.ok) throw new Error(`HTTP ${res.status}`);
424
+ return res.json();
425
+ }).then((json) => setData(_nullishCoalesce(json.collection, () => ( json)))).catch((err) => {
426
+ if (err.name !== "AbortError") setError(err);
427
+ }).finally(() => setLoading(false));
428
+ return () => controller.abort();
429
+ }, [playlistId, apiPrefix]);
430
+ return { data, loading, error };
431
+ }
432
+
433
+ // src/client/hooks/usePlaylistSearch.ts
434
+
435
+ function usePlaylistSearch(query) {
436
+ const { apiPrefix } = useSoundCloudContext();
437
+ const [data, setData] = _react.useState.call(void 0, null);
438
+ const [loading, setLoading] = _react.useState.call(void 0, false);
439
+ const [error, setError] = _react.useState.call(void 0, null);
440
+ _react.useEffect.call(void 0, () => {
441
+ if (!query) {
442
+ setData(null);
443
+ return;
444
+ }
445
+ const controller = new AbortController();
446
+ setLoading(true);
447
+ setError(null);
448
+ const params = new URLSearchParams({ q: query });
449
+ fetch(`${apiPrefix}/search/playlists?${params}`, { signal: controller.signal }).then((res) => {
450
+ if (!res.ok) throw new Error(`HTTP ${res.status}`);
451
+ return res.json();
452
+ }).then((json) => setData(_nullishCoalesce(json.collection, () => ( json)))).catch((err) => {
453
+ if (err.name !== "AbortError") setError(err);
454
+ }).finally(() => setLoading(false));
455
+ return () => controller.abort();
456
+ }, [query, apiPrefix]);
457
+ return { data, loading, error };
458
+ }
459
+
460
+ // src/client/hooks/useUserSearch.ts
461
+
462
+ function useUserSearch(query) {
463
+ const { apiPrefix } = useSoundCloudContext();
464
+ const [data, setData] = _react.useState.call(void 0, null);
465
+ const [loading, setLoading] = _react.useState.call(void 0, false);
466
+ const [error, setError] = _react.useState.call(void 0, null);
467
+ _react.useEffect.call(void 0, () => {
468
+ if (!query) {
469
+ setData(null);
470
+ return;
471
+ }
472
+ const controller = new AbortController();
473
+ setLoading(true);
474
+ setError(null);
475
+ const params = new URLSearchParams({ q: query });
476
+ fetch(`${apiPrefix}/search/users?${params}`, { signal: controller.signal }).then((res) => {
477
+ if (!res.ok) throw new Error(`HTTP ${res.status}`);
478
+ return res.json();
479
+ }).then((json) => setData(_nullishCoalesce(json.collection, () => ( json)))).catch((err) => {
480
+ if (err.name !== "AbortError") setError(err);
481
+ }).finally(() => setLoading(false));
482
+ return () => controller.abort();
483
+ }, [query, apiPrefix]);
484
+ return { data, loading, error };
485
+ }
486
+
487
+
488
+
489
+
490
+
491
+
492
+
493
+
494
+
495
+
496
+
497
+
498
+
173
499
 
174
500
 
175
501
 
176
502
 
177
503
 
178
504
 
179
- exports.SoundCloudProvider = SoundCloudProvider; exports.usePlayer = usePlayer; exports.useSoundCloudContext = useSoundCloudContext; exports.useTrack = useTrack; exports.useTrackSearch = useTrackSearch; exports.useUser = useUser;
505
+ exports.SoundCloudProvider = SoundCloudProvider; exports.usePlayer = usePlayer; exports.usePlaylist = usePlaylist; exports.usePlaylistSearch = usePlaylistSearch; exports.usePlaylistTracks = usePlaylistTracks; exports.useRelatedTracks = useRelatedTracks; exports.useSoundCloudContext = useSoundCloudContext; exports.useTrack = useTrack; exports.useTrackComments = useTrackComments; exports.useTrackLikes = useTrackLikes; exports.useTrackSearch = useTrackSearch; exports.useUser = useUser; exports.useUserFollowers = useUserFollowers; exports.useUserFollowings = useUserFollowings; exports.useUserLikes = useUserLikes; exports.useUserPlaylists = useUserPlaylists; exports.useUserSearch = useUserSearch; exports.useUserTracks = useUserTracks;
package/dist/index.d.cts CHANGED
@@ -1,6 +1,6 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import { ReactNode } from 'react';
3
- import { SoundCloudTrack, SoundCloudUser } from 'soundcloud-api-ts';
3
+ import { SoundCloudTrack, SoundCloudUser, SoundCloudPlaylist, SoundCloudComment } from 'soundcloud-api-ts';
4
4
  export { SoundCloudActivitiesResponse, SoundCloudActivity, SoundCloudComment, SoundCloudMe, SoundCloudPaginatedResponse, SoundCloudPlaylist, SoundCloudStreams, SoundCloudTrack, SoundCloudUser, SoundCloudWebProfile } from 'soundcloud-api-ts';
5
5
 
6
6
  interface SoundCloudContextValue {
@@ -49,4 +49,28 @@ declare function useUser(userId: string | number | undefined): HookResult<SoundC
49
49
 
50
50
  declare function usePlayer(trackId: string | number | undefined): PlayerState;
51
51
 
52
- export { type HookResult, type PlayerState, SoundCloudProvider, type SoundCloudProviderProps, type SoundCloudRoutesConfig, type UseTrackSearchOptions, usePlayer, useSoundCloudContext, useTrack, useTrackSearch, useUser };
52
+ declare function useUserTracks(userId: string | number | undefined): HookResult<SoundCloudTrack[]>;
53
+
54
+ declare function useUserPlaylists(userId: string | number | undefined): HookResult<SoundCloudPlaylist[]>;
55
+
56
+ declare function useUserLikes(userId: string | number | undefined): HookResult<SoundCloudTrack[]>;
57
+
58
+ declare function useUserFollowers(userId: string | number | undefined): HookResult<SoundCloudUser[]>;
59
+
60
+ declare function useUserFollowings(userId: string | number | undefined): HookResult<SoundCloudUser[]>;
61
+
62
+ declare function useTrackComments(trackId: string | number | undefined): HookResult<SoundCloudComment[]>;
63
+
64
+ declare function useTrackLikes(trackId: string | number | undefined): HookResult<SoundCloudUser[]>;
65
+
66
+ declare function useRelatedTracks(trackId: string | number | undefined): HookResult<SoundCloudTrack[]>;
67
+
68
+ declare function usePlaylist(playlistId: string | number | undefined): HookResult<SoundCloudPlaylist>;
69
+
70
+ declare function usePlaylistTracks(playlistId: string | number | undefined): HookResult<SoundCloudTrack[]>;
71
+
72
+ declare function usePlaylistSearch(query: string): HookResult<SoundCloudPlaylist[]>;
73
+
74
+ declare function useUserSearch(query: string): HookResult<SoundCloudUser[]>;
75
+
76
+ export { type HookResult, type PlayerState, SoundCloudProvider, type SoundCloudProviderProps, type SoundCloudRoutesConfig, type UseTrackSearchOptions, usePlayer, usePlaylist, usePlaylistSearch, usePlaylistTracks, useRelatedTracks, useSoundCloudContext, useTrack, useTrackComments, useTrackLikes, useTrackSearch, useUser, useUserFollowers, useUserFollowings, useUserLikes, useUserPlaylists, useUserSearch, useUserTracks };
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import { ReactNode } from 'react';
3
- import { SoundCloudTrack, SoundCloudUser } from 'soundcloud-api-ts';
3
+ import { SoundCloudTrack, SoundCloudUser, SoundCloudPlaylist, SoundCloudComment } from 'soundcloud-api-ts';
4
4
  export { SoundCloudActivitiesResponse, SoundCloudActivity, SoundCloudComment, SoundCloudMe, SoundCloudPaginatedResponse, SoundCloudPlaylist, SoundCloudStreams, SoundCloudTrack, SoundCloudUser, SoundCloudWebProfile } from 'soundcloud-api-ts';
5
5
 
6
6
  interface SoundCloudContextValue {
@@ -49,4 +49,28 @@ declare function useUser(userId: string | number | undefined): HookResult<SoundC
49
49
 
50
50
  declare function usePlayer(trackId: string | number | undefined): PlayerState;
51
51
 
52
- export { type HookResult, type PlayerState, SoundCloudProvider, type SoundCloudProviderProps, type SoundCloudRoutesConfig, type UseTrackSearchOptions, usePlayer, useSoundCloudContext, useTrack, useTrackSearch, useUser };
52
+ declare function useUserTracks(userId: string | number | undefined): HookResult<SoundCloudTrack[]>;
53
+
54
+ declare function useUserPlaylists(userId: string | number | undefined): HookResult<SoundCloudPlaylist[]>;
55
+
56
+ declare function useUserLikes(userId: string | number | undefined): HookResult<SoundCloudTrack[]>;
57
+
58
+ declare function useUserFollowers(userId: string | number | undefined): HookResult<SoundCloudUser[]>;
59
+
60
+ declare function useUserFollowings(userId: string | number | undefined): HookResult<SoundCloudUser[]>;
61
+
62
+ declare function useTrackComments(trackId: string | number | undefined): HookResult<SoundCloudComment[]>;
63
+
64
+ declare function useTrackLikes(trackId: string | number | undefined): HookResult<SoundCloudUser[]>;
65
+
66
+ declare function useRelatedTracks(trackId: string | number | undefined): HookResult<SoundCloudTrack[]>;
67
+
68
+ declare function usePlaylist(playlistId: string | number | undefined): HookResult<SoundCloudPlaylist>;
69
+
70
+ declare function usePlaylistTracks(playlistId: string | number | undefined): HookResult<SoundCloudTrack[]>;
71
+
72
+ declare function usePlaylistSearch(query: string): HookResult<SoundCloudPlaylist[]>;
73
+
74
+ declare function useUserSearch(query: string): HookResult<SoundCloudUser[]>;
75
+
76
+ export { type HookResult, type PlayerState, SoundCloudProvider, type SoundCloudProviderProps, type SoundCloudRoutesConfig, type UseTrackSearchOptions, usePlayer, usePlaylist, usePlaylistSearch, usePlaylistTracks, useRelatedTracks, useSoundCloudContext, useTrack, useTrackComments, useTrackLikes, useTrackSearch, useUser, useUserFollowers, useUserFollowings, useUserLikes, useUserPlaylists, useUserSearch, useUserTracks };