@audius/sdk 0.0.37 → 0.0.38

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.
@@ -514,9 +514,9 @@ if (typeof window !== 'undefined' && window && window.Web3) {
514
514
  var LibsWeb3 = Web3;
515
515
 
516
516
  var name = "@audius/sdk";
517
- var version = "0.0.37";
517
+ var version = "0.0.38";
518
518
  var audius = {
519
- releaseSHA: "ce81e1601506bb4982a2d5617ecf220bc94ba76d"
519
+ releaseSHA: "74503074cb96dea181ec2b218c5cb6d528c1db86"
520
520
  };
521
521
  var description = "";
522
522
  var main = "dist/index.cjs.js";
@@ -114,4 +114,10 @@ export interface Track {
114
114
  * @memberof Track
115
115
  */
116
116
  permalink?: string;
117
+ /**
118
+ *
119
+ * @type {boolean}
120
+ * @memberof Track
121
+ */
122
+ is_streamable?: boolean;
117
123
  }
@@ -120,6 +120,12 @@ export interface TrackFull {
120
120
  * @memberof TrackFull
121
121
  */
122
122
  permalink?: string;
123
+ /**
124
+ *
125
+ * @type {boolean}
126
+ * @memberof TrackFull
127
+ */
128
+ is_streamable?: boolean;
123
129
  /**
124
130
  *
125
131
  * @type {number}
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@audius/sdk",
3
- "version": "0.0.37",
3
+ "version": "0.0.38",
4
4
  "audius": {
5
- "releaseSHA": "ce81e1601506bb4982a2d5617ecf220bc94ba76d"
5
+ "releaseSHA": "74503074cb96dea181ec2b218c5cb6d528c1db86"
6
6
  },
7
7
  "description": "",
8
8
  "main": "dist/index.cjs.js",
@@ -1,6 +1,6 @@
1
1
  import { Base, Services } from './base'
2
2
  import type { PlaylistMetadata } from '../services/creatorNode'
3
- import { Nullable, Utils } from '../utils'
3
+ import type { Nullable } from '../utils'
4
4
 
5
5
  export enum Action {
6
6
  CREATE = 'Create',
@@ -21,17 +21,23 @@ export interface PlaylistOperationResponse {
21
21
  * Block number of playlist transaction
22
22
  */
23
23
  blockNumber: Nullable<number>
24
- /**
25
- * ID of playlist being modified
26
- */
27
- playlistId: Nullable<number>
28
24
  /**
29
25
  * String error message returned
30
26
  */
31
27
  error: Nullable<string>
32
28
  }
33
-
34
- const { encodeHashId, decodeHashId } = Utils
29
+ type PlaylistTrack = { time: number; metadata_time?: number; track: number }
30
+
31
+ type PlaylistParam = {
32
+ playlist_id: number
33
+ playlist_name: string
34
+ artwork?: { file?: File; url?: string }
35
+ playlist_contents: { track_ids: PlaylistTrack[] } // number[] for playlist upload flow
36
+ cover_art_sizes: string
37
+ description: string
38
+ is_private: boolean
39
+ is_album: boolean
40
+ }
35
41
 
36
42
  /*
37
43
  API surface for updated data contract interactions.
@@ -48,30 +54,11 @@ export class EntityManager extends Base {
48
54
  return Math.floor(Math.random() * (max - min) + min)
49
55
  }
50
56
 
51
- async getFullPlaylist(playlistId: number, userId: number) {
52
- const encodedPlaylistId = encodeHashId(playlistId) as string
53
- const encodedUserId = encodeHashId(userId) as string
54
-
55
- const playlist: any = (
56
- await this.discoveryProvider.getFullPlaylist(
57
- encodedPlaylistId,
58
- encodedUserId
59
- )
60
- )[0]
61
- return playlist
62
- }
63
-
64
- mapAddedTimestamps(addedTimestamps: any) {
65
- const trackIds = addedTimestamps.map(
66
- (trackObj: {
67
- track_id: string
68
- metadata_timestamp?: number
69
- timestamp: number
70
- }) => ({
71
- track: decodeHashId(trackObj.track_id),
72
- time: trackObj.metadata_timestamp ?? trackObj.timestamp
73
- })
74
- )
57
+ mapTimestamps(addedTimestamps: PlaylistTrack[]) {
58
+ const trackIds = addedTimestamps.map((trackObj) => ({
59
+ track: trackObj.track,
60
+ time: trackObj.metadata_time ?? trackObj.time // default to time for legacy playlists
61
+ }))
75
62
 
76
63
  return trackIds
77
64
  }
@@ -83,7 +70,6 @@ export class EntityManager extends Base {
83
70
  return {
84
71
  blockHash: null,
85
72
  blockNumber: null,
86
- playlistId: null,
87
73
  error: null
88
74
  }
89
75
  }
@@ -91,77 +77,52 @@ export class EntityManager extends Base {
91
77
  /**
92
78
  * Create a playlist using updated data contracts flow
93
79
  */
94
- async createPlaylist({
95
- playlistId,
96
- playlistName,
97
- trackIds,
98
- description,
99
- isAlbum,
100
- isPrivate,
101
- coverArt,
102
- coverArtSizes,
103
- logger = console
104
- }: {
105
- playlistId: number
106
- playlistName: string
107
- trackIds: number[]
108
- description: string
109
- isAlbum: boolean
110
- isPrivate: boolean
111
- coverArt: string
112
- coverArtSizes: string
113
- logger: Console
114
- }): Promise<PlaylistOperationResponse> {
80
+ async createPlaylist(
81
+ playlist: PlaylistParam
82
+ ): Promise<PlaylistOperationResponse> {
115
83
  const responseValues: PlaylistOperationResponse =
116
84
  this.getDefaultPlaylistReponseValues()
117
85
  try {
118
- const currentUserId: string | null =
119
- this.userStateManager.getCurrentUserId()
120
- if (!currentUserId) {
86
+ const userId: number | null = this.userStateManager.getCurrentUserId()
87
+ if (!userId) {
121
88
  responseValues.error = 'Missing current user ID'
122
89
  return responseValues
123
90
  }
124
- const userId: number = parseInt(currentUserId)
125
91
  const createAction = Action.CREATE
126
92
  const entityType = EntityType.PLAYLIST
127
93
  this.REQUIRES(Services.CREATOR_NODE)
128
94
  let dirCID
129
- if (coverArt) {
95
+ if (playlist?.artwork?.file) {
130
96
  const updatedPlaylistImage = await this.creatorNode.uploadImage(
131
- coverArt,
97
+ playlist.artwork.file,
132
98
  true // square
133
99
  )
134
100
  dirCID = updatedPlaylistImage.dirCID
135
101
  }
136
- const web3 = this.web3Manager.getWeb3()
137
- const currentBlockNumber = await web3.eth.getBlockNumber()
138
- const currentBlock = await web3.eth.getBlock(currentBlockNumber)
139
- const tracks = trackIds.map((trackId) => ({
140
- track: trackId,
141
- time: currentBlock.timestamp as number
142
- }))
102
+ const tracks = this.mapTimestamps(playlist.playlist_contents.track_ids)
103
+
143
104
  const metadata: PlaylistMetadata = {
144
- playlist_id: playlistId,
105
+ playlist_id: playlist.playlist_id,
145
106
  playlist_contents: { track_ids: tracks },
146
- playlist_name: playlistName,
147
- playlist_image_sizes_multihash: dirCID ?? coverArtSizes,
148
- description,
149
- is_album: isAlbum,
150
- is_private: isPrivate
107
+ playlist_name: playlist.playlist_name,
108
+ playlist_image_sizes_multihash: dirCID ?? playlist.cover_art_sizes, // default to cover_art_sizes for new playlists from tracks
109
+ description: playlist.description,
110
+ is_album: playlist.is_album,
111
+ is_private: playlist.is_private
151
112
  }
113
+
152
114
  const { metadataMultihash } =
153
115
  await this.creatorNode.uploadPlaylistMetadata(metadata)
154
116
  const manageEntityResponse = await this.manageEntity({
155
117
  userId: userId,
156
118
  entityType,
157
- entityId: playlistId,
119
+ entityId: playlist.playlist_id,
158
120
  action: createAction,
159
121
  metadataMultihash
160
122
  })
161
123
  const txReceipt = manageEntityResponse.txReceipt
162
124
  responseValues.blockHash = txReceipt.blockHash
163
125
  responseValues.blockNumber = txReceipt.blockNumber
164
- responseValues.playlistId = playlistId
165
126
  return responseValues
166
127
  } catch (e) {
167
128
  const error = (e as Error).message
@@ -173,22 +134,14 @@ export class EntityManager extends Base {
173
134
  /**
174
135
  * Delete a playlist using updated data contracts flow
175
136
  */
176
- async deletePlaylist({
177
- playlistId,
178
- logger = console
179
- }: {
180
- playlistId: number
181
- logger: any
182
- }): Promise<{ blockHash: any; blockNumber: any }> {
137
+ async deletePlaylist(playlistId: number): Promise<PlaylistOperationResponse> {
183
138
  const responseValues: PlaylistOperationResponse =
184
139
  this.getDefaultPlaylistReponseValues()
185
- const currentUserId: string | null =
186
- this.userStateManager.getCurrentUserId()
187
- if (!currentUserId) {
140
+ const userId: number | null = this.userStateManager.getCurrentUserId()
141
+ if (!userId) {
188
142
  responseValues.error = 'Missing current user ID'
189
143
  return responseValues
190
144
  }
191
- const userId: number = parseInt(currentUserId)
192
145
  try {
193
146
  const resp = await this.manageEntity({
194
147
  userId,
@@ -200,7 +153,6 @@ export class EntityManager extends Base {
200
153
  const txReceipt = resp.txReceipt
201
154
  responseValues.blockHash = txReceipt.blockHash
202
155
  responseValues.blockNumber = txReceipt.blockNumber
203
- responseValues.playlistId = playlistId
204
156
  return responseValues
205
157
  } catch (e) {
206
158
  const error = (e as Error).message
@@ -211,131 +163,43 @@ export class EntityManager extends Base {
211
163
 
212
164
  /**
213
165
  * Update a playlist using updated data contracts flow
214
- **/
215
- async editPlaylist({
216
- playlistId,
217
- playlistName,
218
- description,
219
- isAlbum,
220
- isPrivate,
221
- coverArt,
222
- logger = console
223
- }: {
224
- playlistId: number
225
- playlistName: Nullable<string>
226
- description: Nullable<string>
227
- isAlbum: Nullable<boolean>
228
- isPrivate: Nullable<boolean>
229
- coverArt: Nullable<string>
230
- logger: Console
231
- }): Promise<PlaylistOperationResponse> {
166
+ */
167
+ async updatePlaylist(
168
+ playlist: PlaylistParam
169
+ ): Promise<PlaylistOperationResponse> {
232
170
  const responseValues: PlaylistOperationResponse =
233
171
  this.getDefaultPlaylistReponseValues()
234
172
 
235
173
  try {
236
- const currentUserId: string | null =
237
- this.userStateManager.getCurrentUserId()
238
- if (!playlistId || playlistId === undefined) {
239
- responseValues.error = 'Missing current playlistId'
174
+ const userId: number | null = this.userStateManager.getCurrentUserId()
175
+
176
+ if (!playlist || playlist === undefined) {
177
+ responseValues.error = 'Missing current playlist'
240
178
  return responseValues
241
179
  }
242
- if (!currentUserId) {
180
+ if (!userId) {
243
181
  responseValues.error = 'Missing current user ID'
244
182
  return responseValues
245
183
  }
246
- const userId: number = parseInt(currentUserId)
247
184
  const updateAction = Action.UPDATE
248
185
  const entityType = EntityType.PLAYLIST
249
186
  this.REQUIRES(Services.CREATOR_NODE)
250
187
  let dirCID
251
- if (coverArt) {
252
- // @ts-expect-error
188
+ if (playlist?.artwork?.file) {
253
189
  const updatedPlaylistImage = await this.creatorNode.uploadImage(
254
- coverArt,
190
+ playlist.artwork.file,
255
191
  true // square
256
192
  )
257
193
  dirCID = updatedPlaylistImage.dirCID
258
194
  }
259
- const playlist = await this.getFullPlaylist(playlistId, userId)
260
- const existingPlaylistTracks = this.mapAddedTimestamps(
261
- playlist.added_timestamps
262
- )
263
- const metadata: PlaylistMetadata = {
264
- playlist_id: playlistId,
265
- playlist_contents: { track_ids: existingPlaylistTracks },
266
- playlist_name: playlistName ?? playlist.playlist_name,
267
- playlist_image_sizes_multihash: dirCID ?? playlist.cover_art,
268
- description: description ?? playlist.description,
269
- is_album: isAlbum ?? playlist.is_album,
270
- is_private: isPrivate ?? playlist.is_private
271
- }
272
- const { metadataMultihash } =
273
- await this.creatorNode.uploadPlaylistMetadata(metadata)
274
- const resp = await this.manageEntity({
275
- userId,
276
- entityType,
277
- entityId: playlistId,
278
- action: updateAction,
279
- metadataMultihash
280
- })
281
- const txReceipt = resp.txReceipt
282
- responseValues.blockHash = txReceipt.blockHash
283
- responseValues.blockNumber = txReceipt.blockNumber
284
- responseValues.playlistId = playlistId
285
- return responseValues
286
- } catch (e) {
287
- const error = (e as Error).message
288
- responseValues.error = error
289
- return responseValues
290
- }
291
- }
292
-
293
- async addPlaylistTrack({
294
- playlistId,
295
- trackId,
296
- timestamp,
297
- logger = console
298
- }: {
299
- playlistId: number
300
- trackId: number
301
- timestamp: number
302
- logger: Console
303
- }): Promise<PlaylistOperationResponse> {
304
- const responseValues: PlaylistOperationResponse =
305
- this.getDefaultPlaylistReponseValues()
306
-
307
- try {
308
- const currentUserId: string | null =
309
- this.userStateManager.getCurrentUserId()
310
- if (!playlistId || playlistId === undefined) {
311
- responseValues.error = 'Missing current playlistId'
312
- return responseValues
313
- }
314
- if (!currentUserId) {
315
- responseValues.error = 'Missing current user ID'
316
- return responseValues
317
- }
318
- const userId: number = parseInt(currentUserId)
319
- const updateAction = Action.UPDATE
320
- const entityType = EntityType.PLAYLIST
321
- this.REQUIRES(Services.CREATOR_NODE)
322
-
323
- const playlist = await this.getFullPlaylist(playlistId, userId)
324
195
 
325
- const updatedPlaylistTracks = this.mapAddedTimestamps(
326
- playlist.added_timestamps
327
- )
328
-
329
- updatedPlaylistTracks.push({
330
- track: trackId,
331
- time: timestamp
332
- })
196
+ const trackIds = this.mapTimestamps(playlist.playlist_contents.track_ids)
333
197
 
334
198
  const metadata: PlaylistMetadata = {
335
- playlist_id: playlistId,
336
- playlist_contents: { track_ids: updatedPlaylistTracks },
199
+ playlist_id: playlist.playlist_id,
200
+ playlist_contents: { track_ids: trackIds },
337
201
  playlist_name: playlist.playlist_name,
338
- playlist_image_sizes_multihash: playlist.cover_art,
202
+ playlist_image_sizes_multihash: dirCID ?? playlist.cover_art_sizes,
339
203
  description: playlist.description,
340
204
  is_album: playlist.is_album,
341
205
  is_private: playlist.is_private
@@ -345,172 +209,13 @@ export class EntityManager extends Base {
345
209
  const resp = await this.manageEntity({
346
210
  userId,
347
211
  entityType,
348
- entityId: playlistId,
349
- action: updateAction,
350
- metadataMultihash
351
- })
352
- const txReceipt = resp.txReceipt
353
- responseValues.blockHash = txReceipt.blockHash
354
- responseValues.blockNumber = txReceipt.blockNumber
355
- responseValues.playlistId = playlistId
356
- return responseValues
357
- } catch (e) {
358
- const error = (e as Error).message
359
- responseValues.error = error
360
- return responseValues
361
- }
362
- }
363
-
364
- async deletePlaylistTrack({
365
- playlistId,
366
- trackId,
367
- timestamp,
368
- logger = console
369
- }: {
370
- playlistId: number
371
- trackId: number
372
- timestamp: number
373
- logger: Console
374
- }): Promise<PlaylistOperationResponse> {
375
- const responseValues: PlaylistOperationResponse =
376
- this.getDefaultPlaylistReponseValues()
377
-
378
- try {
379
- const currentUserId: string | null =
380
- this.userStateManager.getCurrentUserId()
381
- if (!playlistId || playlistId === undefined) {
382
- responseValues.error = 'Missing current playlistId'
383
- return responseValues
384
- }
385
- if (!currentUserId) {
386
- responseValues.error = 'Missing current user ID'
387
- return responseValues
388
- }
389
- const userId: number = parseInt(currentUserId)
390
- const updateAction = Action.UPDATE
391
- const entityType = EntityType.PLAYLIST
392
- this.REQUIRES(Services.CREATOR_NODE)
393
- const playlist = await this.getFullPlaylist(playlistId, userId)
394
-
395
- const existingPlaylistTracks = this.mapAddedTimestamps(
396
- playlist.added_timestamps
397
- )
398
-
399
- const updatedTrackIds = existingPlaylistTracks.filter(
400
- (trackObj: { track: number; metadata_time?: number; time: number }) =>
401
- (trackObj.track !== trackId &&
402
- timestamp !== trackObj.metadata_time) ??
403
- trackObj.time
404
- )
405
-
406
- const metadata: PlaylistMetadata = {
407
- playlist_id: playlistId,
408
- playlist_contents: { track_ids: updatedTrackIds },
409
- playlist_name: playlist.playlist_name,
410
- playlist_image_sizes_multihash: playlist.cover_art,
411
- description: playlist.description,
412
- is_album: playlist.is_album,
413
- is_private: playlist.is_private
414
- }
415
- const { metadataMultihash } =
416
- await this.creatorNode.uploadPlaylistMetadata(metadata)
417
- const resp = await this.manageEntity({
418
- userId,
419
- entityType,
420
- entityId: playlistId,
421
- action: updateAction,
422
- metadataMultihash
423
- })
424
- const txReceipt = resp.txReceipt
425
- responseValues.blockHash = txReceipt.blockHash
426
- responseValues.blockNumber = txReceipt.blockNumber
427
- responseValues.playlistId = playlistId
428
- return responseValues
429
- } catch (e) {
430
- const error = (e as Error).message
431
- responseValues.error = error
432
- return responseValues
433
- }
434
- }
435
-
436
- /**
437
- * Update a playlist using updated data contracts flow
438
- **/
439
- async orderPlaylist({
440
- playlistId,
441
- trackIds,
442
- logger = console
443
- }: {
444
- playlistId: number
445
- trackIds: number[]
446
- logger: Console
447
- }): Promise<PlaylistOperationResponse> {
448
- const responseValues: PlaylistOperationResponse =
449
- this.getDefaultPlaylistReponseValues()
450
-
451
- try {
452
- const currentUserId: string | null =
453
- this.userStateManager.getCurrentUserId()
454
- if (!playlistId || playlistId === undefined) {
455
- responseValues.error = 'Missing current playlistId'
456
- return responseValues
457
- }
458
- if (!currentUserId) {
459
- responseValues.error = 'Missing current user ID'
460
- return responseValues
461
- }
462
- const userId: number = parseInt(currentUserId)
463
- const updateAction = Action.UPDATE
464
- const entityType = EntityType.PLAYLIST
465
- this.REQUIRES(Services.CREATOR_NODE)
466
- const playlist = await this.getFullPlaylist(playlistId, userId)
467
-
468
- const existingPlaylistTracks = this.mapAddedTimestamps(
469
- playlist.added_timestamps
470
- )
471
-
472
- let trackIdsWithTimes = []
473
- const trackIdTimes = {}
474
- existingPlaylistTracks.forEach(
475
- (trackObj: { track: number; metadata_time?: number; time: number }) => {
476
- const trackId = trackObj.track
477
- const timestamp = trackObj.metadata_time ?? trackObj.time
478
- if (trackId in trackIdTimes) {
479
- trackIdTimes[trackId].push(timestamp)
480
- } else {
481
- trackIdTimes[trackId] = [timestamp]
482
- }
483
- }
484
- )
485
-
486
- // new tracks default to currentBlock timestamp
487
- trackIdsWithTimes = trackIds.map((trackId: number) => ({
488
- track: trackId,
489
- time: trackIdTimes[trackId].pop()
490
- }))
491
- const metadata: PlaylistMetadata = {
492
- playlist_id: playlistId,
493
- playlist_contents: { track_ids: trackIdsWithTimes },
494
- playlist_name: playlist.playlist_name,
495
- playlist_image_sizes_multihash: playlist.cover_art,
496
- description: playlist.description,
497
- is_album: playlist.is_album,
498
- is_private: playlist.is_private
499
- }
500
- const { metadataMultihash } =
501
- await this.creatorNode.uploadPlaylistMetadata(metadata)
502
-
503
- const resp = await this.manageEntity({
504
- userId,
505
- entityType,
506
- entityId: playlistId,
212
+ entityId: playlist.playlist_id,
507
213
  action: updateAction,
508
214
  metadataMultihash
509
215
  })
510
216
  const txReceipt = resp.txReceipt
511
217
  responseValues.blockHash = txReceipt.blockHash
512
218
  responseValues.blockNumber = txReceipt.blockNumber
513
- responseValues.playlistId = playlistId
514
219
  return responseValues
515
220
  } catch (e) {
516
221
  const error = (e as Error).message
@@ -134,5 +134,11 @@ export interface Track {
134
134
  * @memberof Track
135
135
  */
136
136
  permalink?: string;
137
+ /**
138
+ *
139
+ * @type {boolean}
140
+ * @memberof Track
141
+ */
142
+ is_streamable?: boolean;
137
143
  }
138
144
 
@@ -170,6 +170,12 @@ export interface TrackFull {
170
170
  * @memberof TrackFull
171
171
  */
172
172
  permalink?: string;
173
+ /**
174
+ *
175
+ * @type {boolean}
176
+ * @memberof TrackFull
177
+ */
178
+ is_streamable?: boolean;
173
179
  /**
174
180
  *
175
181
  * @type {number}