soundcloud-api-ts 1.9.1 → 1.9.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 +197 -0
- package/README.md +5 -1
- package/dist/{chunk-SCUOUK3L.mjs → chunk-G6S6GM75.mjs} +2 -2
- package/dist/{chunk-SCUOUK3L.mjs.map → chunk-G6S6GM75.mjs.map} +1 -1
- package/dist/{chunk-PRQGEYWK.js → chunk-IU4XNEP2.js} +2 -2
- package/dist/{chunk-PRQGEYWK.js.map → chunk-IU4XNEP2.js.map} +1 -1
- package/dist/cli.js +6 -6
- package/dist/cli.mjs +1 -1
- package/dist/index.d.mts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +63 -63
- package/dist/index.mjs +1 -1
- package/llms.txt +195 -0
- package/package.json +4 -2
package/AGENTS.md
ADDED
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
# AGENTS.md — soundcloud-api-ts
|
|
2
|
+
|
|
3
|
+
Instructions for AI coding agents working with this package.
|
|
4
|
+
|
|
5
|
+
## Setup
|
|
6
|
+
|
|
7
|
+
- **Node.js 20+** required (uses native `fetch` and Web Crypto)
|
|
8
|
+
- No environment variables are read by the package — all config is passed to the constructor
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
npm install soundcloud-api-ts
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
```ts
|
|
15
|
+
import { SoundCloudClient } from 'soundcloud-api-ts';
|
|
16
|
+
|
|
17
|
+
const sc = new SoundCloudClient({
|
|
18
|
+
clientId: 'YOUR_CLIENT_ID',
|
|
19
|
+
clientSecret: 'YOUR_CLIENT_SECRET',
|
|
20
|
+
redirectUri: 'https://example.com/callback', // only needed for user auth
|
|
21
|
+
});
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Authentication
|
|
25
|
+
|
|
26
|
+
**Every API call requires a token.** You must call `sc.setToken()` before making requests.
|
|
27
|
+
|
|
28
|
+
### Client Credentials (server-to-server, no user context)
|
|
29
|
+
|
|
30
|
+
```ts
|
|
31
|
+
const token = await sc.auth.getClientToken();
|
|
32
|
+
sc.setToken(token.access_token);
|
|
33
|
+
// Now you can call public endpoints: tracks, users, search, playlists, resolve
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### User Token (user context required)
|
|
37
|
+
|
|
38
|
+
Some endpoints require a user token (not just client credentials):
|
|
39
|
+
- All `sc.me.*` endpoints
|
|
40
|
+
- `sc.likes.*` (likeTrack, unlikeTrack, likePlaylist, unlikePlaylist)
|
|
41
|
+
- `sc.reposts.*` (repostTrack, unrepostTrack, repostPlaylist, unrepostPlaylist)
|
|
42
|
+
- `sc.tracks.createComment()`, `sc.tracks.update()`, `sc.tracks.delete()`
|
|
43
|
+
- `sc.playlists.create()`, `sc.playlists.update()`, `sc.playlists.delete()`
|
|
44
|
+
- `sc.me.follow()`, `sc.me.unfollow()`
|
|
45
|
+
|
|
46
|
+
```ts
|
|
47
|
+
import { generateCodeVerifier, generateCodeChallenge } from 'soundcloud-api-ts';
|
|
48
|
+
|
|
49
|
+
const verifier = generateCodeVerifier();
|
|
50
|
+
const challenge = await generateCodeChallenge(verifier);
|
|
51
|
+
const authUrl = sc.auth.getAuthorizationUrl({ state: 'csrf-token', codeChallenge: challenge });
|
|
52
|
+
// User visits authUrl → redirected back with ?code=...
|
|
53
|
+
const token = await sc.auth.getUserToken(code, verifier);
|
|
54
|
+
sc.setToken(token.access_token, token.refresh_token);
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Common Operations
|
|
58
|
+
|
|
59
|
+
### Get a track
|
|
60
|
+
```ts
|
|
61
|
+
const track = await sc.tracks.getTrack(123456);
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### Search
|
|
65
|
+
```ts
|
|
66
|
+
const results = await sc.search.tracks('lofi hip hop');
|
|
67
|
+
// results.collection is SoundCloudTrack[]
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### Get stream URLs
|
|
71
|
+
```ts
|
|
72
|
+
const streams = await sc.tracks.getStreams(trackId);
|
|
73
|
+
// streams.hls_mp3_128_url, streams.http_mp3_128_url, etc.
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### Resolve a SoundCloud URL
|
|
77
|
+
```ts
|
|
78
|
+
const resource = await sc.resolve.resolveUrl('https://soundcloud.com/artist/track');
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### Get authenticated user profile
|
|
82
|
+
```ts
|
|
83
|
+
const me = await sc.me.getMe(); // requires user token
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## Pagination
|
|
87
|
+
|
|
88
|
+
Paginated endpoints return `{ collection: T[], next_href?: string }`. Use the built-in helpers:
|
|
89
|
+
|
|
90
|
+
```ts
|
|
91
|
+
// Iterate items one by one across all pages
|
|
92
|
+
for await (const track of sc.paginateItems(() => sc.search.tracks('lofi'))) {
|
|
93
|
+
console.log(track.title);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// Collect everything (with optional cap)
|
|
97
|
+
const allTracks = await sc.fetchAll(() => sc.users.getTracks(userId), { maxItems: 200 });
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
## Error Handling
|
|
101
|
+
|
|
102
|
+
All API errors throw `SoundCloudError`:
|
|
103
|
+
|
|
104
|
+
```ts
|
|
105
|
+
import { SoundCloudError } from 'soundcloud-api-ts';
|
|
106
|
+
|
|
107
|
+
try {
|
|
108
|
+
await sc.tracks.getTrack(999999999);
|
|
109
|
+
} catch (err) {
|
|
110
|
+
if (err instanceof SoundCloudError) {
|
|
111
|
+
err.status; // HTTP status code (404, 401, 429, etc.)
|
|
112
|
+
err.message; // Human-readable error message
|
|
113
|
+
err.isNotFound; // true if 404
|
|
114
|
+
err.isUnauthorized; // true if 401
|
|
115
|
+
err.isRateLimited; // true if 429
|
|
116
|
+
err.isServerError; // true if 5xx
|
|
117
|
+
err.errorCode; // Machine-readable code like "invalid_client"
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
## Gotchas
|
|
123
|
+
|
|
124
|
+
1. **Token required for ALL requests** — even public endpoints like `getTrack` need at least a client credentials token. Call `setToken()` first.
|
|
125
|
+
2. **User token vs client token** — write operations (like, repost, comment, follow, create/update/delete) require a user token obtained via the authorization code flow. A client credentials token won't work.
|
|
126
|
+
3. **Rate limits exist** — SoundCloud returns 429 when rate limited. The client has built-in retry with exponential backoff (configurable via `maxRetries` and `retryBaseDelay`).
|
|
127
|
+
4. **Auto token refresh** — pass `onTokenRefresh` in the config to automatically refresh expired tokens on 401.
|
|
128
|
+
5. **No env vars** — the package reads no environment variables. Pass `clientId`, `clientSecret`, and `redirectUri` directly to the constructor.
|
|
129
|
+
6. **IDs can be numbers or strings** — all ID parameters accept `string | number`.
|
|
130
|
+
7. **Search pagination** — search uses zero-based `pageNumber` (10 results per page), not cursor-based pagination.
|
|
131
|
+
|
|
132
|
+
## Project Structure (for contributors)
|
|
133
|
+
|
|
134
|
+
```
|
|
135
|
+
src/
|
|
136
|
+
index.ts — All public exports (source of truth)
|
|
137
|
+
client/SoundCloudClient.ts — Main client class with all namespaced methods
|
|
138
|
+
client/http.ts — scFetch, scFetchUrl (HTTP layer with retry)
|
|
139
|
+
client/paginate.ts — paginate, paginateItems, fetchAll helpers
|
|
140
|
+
auth/ — Standalone auth functions + PKCE
|
|
141
|
+
users/ — Standalone user functions (getMe, getUser, etc.)
|
|
142
|
+
tracks/ — Standalone track functions
|
|
143
|
+
playlists/ — Standalone playlist functions
|
|
144
|
+
search/ — Standalone search functions
|
|
145
|
+
me/ — Standalone /me endpoint functions
|
|
146
|
+
likes/ — Standalone like/unlike functions
|
|
147
|
+
reposts/ — Standalone repost functions
|
|
148
|
+
resolve/ — Standalone resolve function
|
|
149
|
+
utils/ — Widget URL helper
|
|
150
|
+
errors.ts — SoundCloudError class
|
|
151
|
+
types/api.ts — All TypeScript type definitions
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
## Key Files
|
|
155
|
+
|
|
156
|
+
- `src/index.ts` — single source of truth for all exports
|
|
157
|
+
- `src/types/api.ts` — all TypeScript interfaces
|
|
158
|
+
- `src/client/SoundCloudClient.ts` — the main client class
|
|
159
|
+
- `tsup.config.ts` — build config (dual ESM/CJS)
|
|
160
|
+
- `vitest.config.ts` — test config
|
|
161
|
+
- `typedoc.json` — API docs generation config
|
|
162
|
+
|
|
163
|
+
## Build & Test
|
|
164
|
+
|
|
165
|
+
```bash
|
|
166
|
+
pnpm build # tsup → dist/ (ESM + CJS + .d.ts)
|
|
167
|
+
pnpm lint # ESLint
|
|
168
|
+
pnpm typecheck # tsc --noEmit
|
|
169
|
+
pnpm test # Vitest
|
|
170
|
+
pnpm test:watch # Vitest watch mode
|
|
171
|
+
pnpm docs # TypeDoc → API docs site
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
## How to Add a New Endpoint
|
|
175
|
+
|
|
176
|
+
1. Create a standalone function in the appropriate `src/<category>/` directory
|
|
177
|
+
2. Export it from `src/<category>/index.ts`
|
|
178
|
+
3. Re-export from `src/index.ts`
|
|
179
|
+
4. Add a namespaced method in `SoundCloudClient` (in `src/client/SoundCloudClient.ts`)
|
|
180
|
+
5. Add tests in `src/<category>/__tests__/`
|
|
181
|
+
6. Update `llms.txt` and `llms-full.txt` with the new function signature
|
|
182
|
+
|
|
183
|
+
## Publishing
|
|
184
|
+
|
|
185
|
+
Uses **Trusted Publishing** via GitHub Releases:
|
|
186
|
+
1. Bump version in `package.json`
|
|
187
|
+
2. Commit and push to `main`
|
|
188
|
+
3. Create a GitHub Release with the version tag (e.g. `v1.9.2`)
|
|
189
|
+
4. GitHub Actions CI builds and publishes to npm automatically
|
|
190
|
+
|
|
191
|
+
## Related Packages
|
|
192
|
+
|
|
193
|
+
- [soundcloud-api-ts-next](https://github.com/twin-paws/soundcloud-api-ts-next) — React hooks + Next.js API routes (depends on this package)
|
|
194
|
+
|
|
195
|
+
## Full Documentation
|
|
196
|
+
|
|
197
|
+
https://twin-paws.github.io/soundcloud-api-ts/
|
package/README.md
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
[](https://bundlephobia.com/package/soundcloud-api-ts)
|
|
8
8
|
[](https://packagephobia.com/result?p=soundcloud-api-ts)
|
|
9
9
|
[](https://www.typescriptlang.org/)
|
|
10
|
-
[](https://nodejs.org/)
|
|
11
11
|
[]()
|
|
12
12
|
[](https://twin-paws.github.io/soundcloud-api-ts/)
|
|
13
13
|
[](https://github.com/twin-paws/soundcloud-api-ts)
|
|
@@ -456,6 +456,10 @@ Full API documentation is available at **[twin-paws.github.io/soundcloud-api-ts]
|
|
|
456
456
|
|
|
457
457
|
See [CHANGELOG.md](CHANGELOG.md) for release history.
|
|
458
458
|
|
|
459
|
+
## Related Packages
|
|
460
|
+
|
|
461
|
+
- **[soundcloud-api-ts-next](https://github.com/twin-paws/soundcloud-api-ts-next)** — React hooks + Next.js API route handlers built on this package. Use it when building Next.js apps that need SoundCloud data with secrets kept server-side.
|
|
462
|
+
|
|
459
463
|
## Contributing
|
|
460
464
|
|
|
461
465
|
Contributions are welcome! Please see [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.
|
|
@@ -1679,5 +1679,5 @@ var unrepostPlaylist = async (token, playlistId) => {
|
|
|
1679
1679
|
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`;
|
|
1680
1680
|
|
|
1681
1681
|
export { SoundCloudClient, createPlaylist, createTrackComment, deletePlaylist, deleteTrack, fetchAll, followUser, generateCodeChallenge, generateCodeVerifier, getAuthorizationUrl, getClientToken, getFollowers, getFollowings, getMe, getMeActivities, getMeActivitiesOwn, getMeActivitiesTracks, getMeFollowers, getMeFollowings, getMeFollowingsTracks, getMeLikesPlaylists, getMeLikesTracks, getMePlaylists, getMeTracks, getPlaylist, getPlaylistReposts, getPlaylistTracks, getRelatedTracks, getSoundCloudWidgetUrl, getTrack, getTrackComments, getTrackLikes, getTrackReposts, getTrackStreams, 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 };
|
|
1682
|
-
//# sourceMappingURL=chunk-
|
|
1683
|
-
//# sourceMappingURL=chunk-
|
|
1682
|
+
//# sourceMappingURL=chunk-G6S6GM75.mjs.map
|
|
1683
|
+
//# sourceMappingURL=chunk-G6S6GM75.mjs.map
|