@borealise/api 1.1.11 → 2.0.0-alpha.10

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,205 +1,286 @@
1
- # @borealise/api
2
-
3
- Official JavaScript/TypeScript API client for [Borealise](https://borealise.com).
4
-
5
- ## Installation
6
-
7
- ```bash
8
- npm install @borealise/api axios
9
- # or
10
- yarn add @borealise/api axios
11
- # or
12
- pnpm add @borealise/api axios
13
- ```
14
-
15
- > `axios` is a peer dependency — you need to install it alongside this package.
16
-
17
- ---
18
-
19
- ## Quick Start
20
-
21
- Initialize the API client once (e.g. in your app entry point), then use the resource singletons anywhere.
22
-
23
- ```ts
24
- import { Api, authResource, roomResource } from '@borealise/api'
25
-
26
- // Initialize once
27
- Api.getInstance({
28
- baseURL: 'https://prod.borealise.com',
29
- })
30
-
31
- // Login
32
- const { data } = await authResource.login({ login: 'you@example.com', password: 'secret' })
33
- Api.getInstance().setAuthToken(data.data.accessToken)
34
-
35
- // Join a room
36
- const room = await roomResource.join('chill-lounge')
37
- ```
38
-
39
- ---
40
-
41
- ## Configuration
42
-
43
- ```ts
44
- Api.getInstance({
45
- baseURL: 'https://prod.borealise.com', // required
46
- timeout: 15000, // optional, default: 30000ms
47
- logging: false, // optional, disable all console output
48
- })
49
- ```
50
-
51
- ---
52
-
53
- ## Resources
54
-
55
- ### Auth
56
-
57
- ```ts
58
- import { authResource } from '@borealise/api'
59
-
60
- await authResource.login({ login: 'user@example.com', password: '...' })
61
- await authResource.register({ email, username, password, displayName })
62
- await authResource.refresh(refreshToken)
63
- await authResource.me()
64
- await authResource.logout()
65
- ```
66
-
67
- ### Users
68
-
69
- ```ts
70
- import { userResource } from '@borealise/api'
71
-
72
- await userResource.getById(42)
73
- await userResource.getByUsername('djname')
74
- await userResource.updateProfile({ displayName: 'DJ Cool', bio: '...' })
75
- await userResource.deleteAccount()
76
- ```
77
-
78
- ### Rooms
79
-
80
- ```ts
81
- import { roomResource } from '@borealise/api'
82
-
83
- await roomResource.list()
84
- await roomResource.featured()
85
- await roomResource.getBySlug('chill-lounge')
86
- await roomResource.create({ slug: 'my-room', name: 'My Room' })
87
- await roomResource.join('chill-lounge')
88
- await roomResource.leave('chill-lounge')
89
-
90
- // Waitlist
91
- await roomResource.joinWaitlist('chill-lounge')
92
- await roomResource.leaveWaitlist('chill-lounge')
93
- await roomResource.lockWaitlist('chill-lounge')
94
- await roomResource.unlockWaitlist('chill-lounge')
95
-
96
- // Booth
97
- await roomResource.getBooth('chill-lounge')
98
- await roomResource.vote('chill-lounge', 'woot')
99
- await roomResource.grabTrack('chill-lounge', playlistId)
100
- await roomResource.skipTrack('chill-lounge')
101
- ```
102
-
103
- ### Playlists
104
-
105
- ```ts
106
- import { playlistResource } from '@borealise/api'
107
-
108
- await playlistResource.getAll()
109
- await playlistResource.getById(1)
110
- await playlistResource.create('My Playlist')
111
- await playlistResource.rename(1, 'New Name')
112
- await playlistResource.activate(1)
113
- await playlistResource.shuffle(1)
114
- await playlistResource.addItem(1, { source: 'youtube', sourceId: 'dQw4w9WgXcQ' })
115
- await playlistResource.removeItem(1, itemId)
116
- await playlistResource.moveItem(1, itemId, newPosition)
117
- await playlistResource.importPlaylist(1, { url: 'https://youtube.com/playlist?list=...' })
118
- await playlistResource.remove(1)
119
- ```
120
-
121
- ### Sources (Media Search)
122
-
123
- ```ts
124
- import { sourceResource } from '@borealise/api'
125
-
126
- await sourceResource.searchYouTube('lofi hip hop', 10)
127
- await sourceResource.getYouTubeVideo('dQw4w9WgXcQ')
128
- await sourceResource.searchSoundCloud('ambient', 10)
129
- await sourceResource.getSoundCloudTrack('123456')
130
- await sourceResource.resolveSoundCloudUrl('https://soundcloud.com/artist/track')
131
-
132
- // Search both platforms at once
133
- const results = await sourceResource.searchAll('chillwave')
134
- ```
135
-
136
- ### Chat
137
-
138
- ```ts
139
- import { chatResource } from '@borealise/api'
140
-
141
- await chatResource.getMessages('chill-lounge', beforeId, 50)
142
- await chatResource.sendMessage('chill-lounge', { content: 'hello!' })
143
- await chatResource.deleteMessage('chill-lounge', messageId)
144
- ```
145
-
146
- ---
147
-
148
- ## Error Handling
149
-
150
- All methods throw `ApiError` on failure.
151
-
152
- ```ts
153
- import { ApiError } from '@borealise/api'
154
-
155
- try {
156
- await authResource.login({ login: 'bad', password: 'bad' })
157
- } catch (err) {
158
- if (err instanceof ApiError) {
159
- console.log(err.message) // Human-readable message from backend
160
- console.log(err.status) // HTTP status code, e.g. 401
161
- console.log(err.code) // Axios error code, e.g. 'NETWORK_ERROR'
162
- console.log(err.response) // Raw backend error response body
163
- }
164
- }
165
- ```
166
-
167
- ---
168
-
169
- ## Auth Token Management
170
-
171
- ```ts
172
- const api = Api.getInstance()
173
-
174
- // Set token after login
175
- api.setAuthToken(accessToken)
176
-
177
- // Clear token on logout
178
- api.setAuthToken(null)
179
- ```
180
-
181
- ---
182
-
183
- ## TypeScript
184
-
185
- All types are exported directly from the package:
186
-
187
- ```ts
188
- import type {
189
- AuthUser,
190
- Room,
191
- RoomRole,
192
- ChatMessage,
193
- MediaItem,
194
- Playlist,
195
- MediaSearchResult,
196
- BoothState,
197
- WaitlistUser,
198
- } from '@borealise/api'
199
- ```
200
-
201
- ---
202
-
203
- ## License
204
-
205
- © [Borealise](https://borealise.com)
1
+ # @borealise/api
2
+
3
+ Official JavaScript/TypeScript API client for [Borealise](https://borealise.com).
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @borealise/api axios
9
+ # or
10
+ yarn add @borealise/api axios
11
+ # or
12
+ pnpm add @borealise/api axios
13
+ ```
14
+
15
+ > `axios` is a peer dependency — you need to install it alongside this package.
16
+
17
+ ---
18
+
19
+ ## Quick Start
20
+
21
+ ### Option 1: Pre-configured Client (Recommended)
22
+
23
+ Create a client once, then use resources:
24
+
25
+ ```ts
26
+ import { createApiClient } from '@borealise/api'
27
+
28
+ const client = createApiClient({
29
+ baseURL: 'https://prod.borealise.com',
30
+ })
31
+
32
+ // Login
33
+ const { data } = await client.auth.login({ login: 'you@example.com', password: 'secret' })
34
+ client.api.setAuthToken(data.data.accessToken)
35
+
36
+ // Join a room
37
+ const room = await client.room.join('chill-lounge')
38
+ ```
39
+
40
+ ### Option 2: Custom API Instance
41
+
42
+ If you need more control, create the API and resources separately:
43
+
44
+ ```ts
45
+ import { createApi, createAuthResource, createRoomResource } from '@borealise/api'
46
+
47
+ const api = createApi({
48
+ baseURL: 'https://prod.borealise.com',
49
+ timeout: 15000,
50
+ logging: false,
51
+ })
52
+
53
+ const auth = createAuthResource(api)
54
+ const room = createRoomResource(api)
55
+
56
+ // Use custom instances
57
+ await auth.login({ login: 'you@example.com', password: 'secret' })
58
+ ```
59
+
60
+ ---
61
+
62
+ ## Configuration
63
+
64
+ ```ts
65
+ createApiClient({
66
+ baseURL: 'https://prod.borealise.com', // required
67
+ timeout: 15000, // optional, default: 30000ms
68
+ logging: false, // optional, disable all console output
69
+ headers: { 'X-Custom-Header': 'value' } // optional, custom headers
70
+ })
71
+ ```
72
+
73
+ ---
74
+
75
+ ## Resources
76
+
77
+ All resources are accessed via the client:
78
+
79
+ ### Auth
80
+
81
+ ```ts
82
+ const { auth } = createApiClient({ baseURL: '...' })
83
+
84
+ await auth.login({ login: 'user@example.com', password: '...' })
85
+ await auth.register({ email, username, password, displayName })
86
+ await auth.refresh(refreshToken)
87
+ await auth.me()
88
+ await auth.logout()
89
+ ```
90
+
91
+ ### Users
92
+
93
+ ```ts
94
+ const { user } = createApiClient({ baseURL: '...' })
95
+
96
+ await user.getById(42)
97
+ await user.getByUsername('djname')
98
+ await user.updateProfile({ displayName: 'DJ Cool', bio: '...' })
99
+ await user.deleteAccount()
100
+ ```
101
+
102
+ ### Rooms
103
+
104
+ ```ts
105
+ const { room } = createApiClient({ baseURL: '...' })
106
+
107
+ await room.list()
108
+ await room.featured()
109
+ await room.getBySlug('chill-lounge')
110
+ await room.create({ slug: 'my-room', name: 'My Room' })
111
+ await room.join('chill-lounge')
112
+ await room.leave('chill-lounge')
113
+
114
+ // Waitlist
115
+ await room.joinWaitlist('chill-lounge')
116
+ await room.leaveWaitlist('chill-lounge')
117
+ await room.lockWaitlist('chill-lounge')
118
+ await room.unlockWaitlist('chill-lounge')
119
+
120
+ // Booth
121
+ await room.getBooth('chill-lounge')
122
+ await room.vote('chill-lounge', 'woot')
123
+ await room.grabTrack('chill-lounge', playlistId)
124
+ await room.skipTrack('chill-lounge')
125
+ ```
126
+
127
+ ### Playlists
128
+
129
+ ```ts
130
+ const { playlist } = createApiClient({ baseURL: '...' })
131
+
132
+ await playlist.getAll()
133
+ await playlist.getById(1)
134
+ await playlist.create('My Playlist')
135
+ await playlist.rename(1, 'New Name')
136
+ await playlist.activate(1)
137
+ await playlist.shuffle(1)
138
+ await playlist.addItem(1, { source: 'youtube', sourceId: 'dQw4w9WgXcQ' })
139
+ await playlist.removeItem(1, itemId)
140
+ await playlist.moveItem(1, itemId, newPosition)
141
+ await playlist.importPlaylist(1, { url: 'https://youtube.com/playlist?list=...' })
142
+ await playlist.remove(1)
143
+ ```
144
+
145
+ ### Sources (Media Search)
146
+
147
+ ```ts
148
+ const { source } = createApiClient({ baseURL: '...' })
149
+
150
+ await source.searchYouTube('lofi hip hop', 10)
151
+ await source.getYouTubeVideo('dQw4w9WgXcQ')
152
+ await source.searchSoundCloud('ambient', 10)
153
+ await source.getSoundCloudTrack('123456')
154
+ await source.resolveSoundCloudUrl('https://soundcloud.com/artist/track')
155
+
156
+ // Search both platforms at once
157
+ const results = await source.searchAll('chillwave')
158
+ ```
159
+
160
+ ### Chat
161
+
162
+ ```ts
163
+ const { chat } = createApiClient({ baseURL: '...' })
164
+
165
+ await chat.getMessages('chill-lounge', beforeId, 50)
166
+ await chat.sendMessage('chill-lounge', { content: 'hello!' })
167
+ await chat.deleteMessage('chill-lounge', messageId)
168
+ ```
169
+
170
+ ### Friends
171
+
172
+ ```ts
173
+ const { friend } = createApiClient({ baseURL: '...' })
174
+
175
+ await friend.list()
176
+ await friend.getStatus(targetUserId)
177
+ await friend.sendRequest(targetUserId)
178
+ await friend.acceptRequest(friendshipId)
179
+ await friend.remove(friendshipId)
180
+ await friend.block(targetUserId)
181
+ await friend.unblock(targetUserId)
182
+ ```
183
+
184
+ ### Shop
185
+
186
+ ```ts
187
+ const { shop } = createApiClient({ baseURL: '...' })
188
+
189
+ await shop.getAvatarCatalog()
190
+ await shop.unlockAvatar(avatarId)
191
+ await shop.equipAvatar(avatarId)
192
+ ```
193
+
194
+ ### Subscriptions
195
+
196
+ ```ts
197
+ const { subscription } = createApiClient({ baseURL: '...' })
198
+
199
+ await subscription.getStatus()
200
+ await subscription.createIntent('monthly')
201
+ await subscription.cancelIntent(subscriptionId)
202
+ await subscription.createPortal()
203
+ ```
204
+
205
+ ---
206
+
207
+ ## Error Handling
208
+
209
+ All methods throw `ApiError` on failure.
210
+
211
+ ```ts
212
+ import { ApiError } from '@borealise/api'
213
+
214
+ try {
215
+ await api.auth.login({ login: 'bad', password: 'bad' })
216
+ } catch (err) {
217
+ if (err instanceof ApiError) {
218
+ console.log(err.message) // Human-readable message from backend
219
+ console.log(err.status) // HTTP status code, e.g. 401
220
+ console.log(err.code) // Axios error code, e.g. 'NETWORK_ERROR'
221
+ console.log(err.response) // Raw backend error response body
222
+ }
223
+ }
224
+ ```
225
+
226
+ ---
227
+
228
+ ## Auth Token Management
229
+
230
+ ```ts
231
+ const client = createApiClient({ baseURL: '...' })
232
+
233
+ // Set token after login
234
+ client.auth.login({ ... }).then(({ data }) => {
235
+ client.api.setAuthToken(data.data.accessToken)
236
+ })
237
+
238
+ // Clear token on logout
239
+ client.api.setAuthToken(null)
240
+ ```
241
+
242
+ The underlying API instance is accessible via `client.api`. Use it for token management and custom headers:
243
+
244
+ ---
245
+
246
+ ## Tree-Shaking
247
+
248
+ This library uses factory functions to enable tree-shaking. Bundlers like Vite, Webpack, and Rollup can exclude unused methods from your bundle.
249
+
250
+ For maximum tree-shaking, import only the factories you need:
251
+
252
+ ```ts
253
+ import { createApi } from '@borealise/api'
254
+ import { createAuthResource } from '@borealise/api/resources/auth'
255
+ import { createRoomResource } from '@borealise/api/resources/room'
256
+
257
+ const api = createApi({ baseURL: '...' })
258
+ const auth = createAuthResource(api)
259
+ const room = createRoomResource(api)
260
+ ```
261
+
262
+ ---
263
+
264
+ ## TypeScript
265
+
266
+ All types are exported directly from the package:
267
+
268
+ ```ts
269
+ import type {
270
+ AuthUser,
271
+ Room,
272
+ RoomRole,
273
+ ChatMessage,
274
+ MediaItem,
275
+ Playlist,
276
+ MediaSearchResult,
277
+ BoothState,
278
+ WaitlistUser,
279
+ } from '@borealise/api'
280
+ ```
281
+
282
+ ---
283
+
284
+ ## License
285
+
286
+ © [Borealise](https://borealise.com)