@omelhorsite/sdk 0.4.0 → 0.4.1

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.
Files changed (35) hide show
  1. package/README.md +4 -4
  2. package/dist/index.js +4 -4
  3. package/dist/types/auth/device.d.ts +1 -1
  4. package/dist/types/auth/index.d.ts +2 -2
  5. package/dist/types/auth/tokens.d.ts +15 -15
  6. package/dist/types/client.d.ts +10 -10
  7. package/dist/types/errors.d.ts +12 -15
  8. package/dist/types/http.d.ts +74 -118
  9. package/dist/types/index.d.ts +1 -2
  10. package/dist/types/local/qr.d.ts +1 -1
  11. package/dist/types/local/wordlist.d.ts +2 -3
  12. package/dist/types/resources/account.d.ts +14 -17
  13. package/dist/types/resources/auth/index.d.ts +1 -1
  14. package/dist/types/resources/auth/passkeys.d.ts +127 -163
  15. package/dist/types/resources/auth/sessions.d.ts +110 -152
  16. package/dist/types/resources/chests.d.ts +27 -31
  17. package/dist/types/resources/dynamicQrs.d.ts +29 -45
  18. package/dist/types/resources/forms.d.ts +37 -58
  19. package/dist/types/resources/jobs.d.ts +28 -40
  20. package/dist/types/resources/media.d.ts +48 -61
  21. package/dist/types/resources/music/artists.d.ts +179 -245
  22. package/dist/types/resources/music/imports.d.ts +181 -210
  23. package/dist/types/resources/music/index.d.ts +8 -7
  24. package/dist/types/resources/music/playlists.d.ts +77 -110
  25. package/dist/types/resources/music/social.d.ts +153 -228
  26. package/dist/types/resources/music/songs.d.ts +160 -206
  27. package/dist/types/resources/realtime.d.ts +75 -88
  28. package/dist/types/resources/shortLinks.d.ts +33 -45
  29. package/dist/types/resources/storage/upload.d.ts +42 -56
  30. package/dist/types/resources/storage.d.ts +71 -104
  31. package/dist/types/resources/tools/backgroundRemoval.d.ts +11 -13
  32. package/dist/types/resources/tools/captions.d.ts +107 -135
  33. package/dist/types/resources/tools/upscale.d.ts +12 -16
  34. package/dist/types/types.d.ts +29 -38
  35. package/package.json +1 -1
@@ -1,11 +1,11 @@
1
1
  /**
2
2
  * The music domain, reachable as `oms.music`.
3
3
  *
4
- * Five modules split by what they own rather than by which controller serves
5
- * them, because the Rails routes here are flatter than the concepts are:
6
- * `/songs`, `/artists`, `/playlists`, `/song_imports`, `/jams` and a dozen more
7
- * all hang off the root, and grouping them by prefix would have produced a
8
- * surface nobody could guess from.
4
+ * Five modules split by what they own rather than by URL prefix, because the
5
+ * routes here are flatter than the concepts are: `/songs`, `/artists`,
6
+ * `/playlists`, `/song_imports`, `/jams` and a dozen more all hang off the
7
+ * root, and grouping them by prefix would have produced a surface nobody could
8
+ * guess from.
9
9
  *
10
10
  * ```ts
11
11
  * const songs = await oms.music.songs.list({ artist: "Nina Simone" });
@@ -18,7 +18,8 @@
18
18
  *
19
19
  * `songs`, `artists`, `playlists`, `playlist_songs`, `liked_songs`,
20
20
  * `play_events`, `jams`, `song_imports` and `artist_imports` are INTEGERS over
21
- * HTTP. The same song ids come back as STRINGS on the cable. The types in each
21
+ * HTTP. The same song ids come back as STRINGS on the realtime stream. The
22
+ * types in each
22
23
  * module say which one applies where; do not normalise them yourself on the way
23
24
  * in, because `exact_search` compares them typed and a stringified integer
24
25
  * silently matches nothing.
@@ -53,7 +54,7 @@ export declare class MusicNamespace extends Resource {
53
54
  readonly artists: MusicArtistsNamespace;
54
55
  /** Playlists, plus `.songs`, `.mixes`, `.radios` and `.plays`. */
55
56
  readonly playlists: MusicPlaylistsNamespace;
56
- /** Getting audio in: uploads, yt-dlp, `.spotify` sync and `.srMachine`. */
57
+ /** Getting audio in: uploads, URL downloads, `.spotify` sync and `.srMachine`. */
57
58
  readonly imports: MusicImportsNamespace;
58
59
  /** Jams, music profiles, the assistant and the DJ. */
59
60
  readonly social: MusicSocialNamespace;
@@ -20,9 +20,8 @@
20
20
  * 2. **System playlists are half read-only.** A playlist whose `source_kind`
21
21
  * is present and not `"manual"` is maintained by an external sync
22
22
  * (Spotify today). Renaming it, re-arting it and reordering it are refused
23
- * with `401`; adding, removing, hiding and copying are NOT. That split is
24
- * newer than `docs/api-music.md`, which still says every structural edit is
25
- * refused. Test with {@link isSystemPlaylist}.
23
+ * with `401`; adding, removing, hiding and copying are NOT. Test with
24
+ * {@link isSystemPlaylist}.
26
25
  * 3. **Removing a song from a synced playlist does not delete anything.** The
27
26
  * sync would just put it back, so the row is marked `hidden` instead and
28
27
  * the API still answers `204`. The row keeps coming back in listings for
@@ -30,7 +29,7 @@
30
29
  * {@link PlaylistSongsNamespace.remove}.
31
30
  * 4. **`/music_radios/*` is throttled at 60 requests per minute**, and the
32
31
  * bucket is keyed by the `Authorization` header - or by the client IP when
33
- * there is none. A cookie-authenticated web client therefore shares one
32
+ * there is none. A cookie-authenticated browser therefore shares one
34
33
  * budget with every other visitor behind the same address. See
35
34
  * {@link MusicRadiosNamespace}.
36
35
  */
@@ -55,7 +54,7 @@ export type PlaylistVisibility = "private" | "friends";
55
54
  /**
56
55
  * Where a playlist came from. `"manual"` (or `null` on very old rows) is a
57
56
  * playlist the user built; anything else marks it as maintained by a sync and
58
- * makes {@link isSystemPlaylist} true. The column is a free string, so treat
57
+ * makes {@link isSystemPlaylist} true. The field is a free string, so treat
59
58
  * unknown values as system rather than as a bug.
60
59
  */
61
60
  export type PlaylistSourceKind = "manual" | "imported" | "spotify_sync" | (string & {});
@@ -71,13 +70,12 @@ export type PlaylistSongOrigin = "sync" | "manual";
71
70
  * The sync numbers its own rows from 1 upwards and never reaches here, so a
72
71
  * user's additions to a synced playlist are parked above the floor and the
73
72
  * next sync run can renumber its own rows without colliding with them.
74
- * Mirrors `PlaylistSong::MANUAL_BLOCK_FLOOR`.
75
73
  */
76
74
  export declare const PLAYLIST_MANUAL_BLOCK_FLOOR = 100000;
77
75
  /**
78
- * Most songs `POST /playlists` will seed from `song_ids` in one call. Mirrors
79
- * `PlaylistsController::SEED_CAP`; the server takes the first 500 and drops
80
- * the rest in silence, so the SDK raises instead.
76
+ * Most songs `POST /playlists` will seed from `song_ids` in one call. The
77
+ * server takes the first 500 and drops the rest in silence, so the SDK raises
78
+ * instead.
81
79
  */
82
80
  export declare const PLAYLIST_SEED_CAP = 500;
83
81
  /**
@@ -88,13 +86,13 @@ export declare const PLAYLIST_SEED_CAP = 500;
88
86
  export declare const MUSIC_RADIO_RATE_LIMIT_PER_MINUTE = 60;
89
87
  /**
90
88
  * Window in which a repeat play of the same song is swallowed rather than
91
- * recorded. Mirrors `PlayEvent::DEDUPE_WINDOW`.
89
+ * recorded.
92
90
  */
93
91
  export declare const PLAY_EVENT_DEDUPE_WINDOW_MS = 30000;
94
92
  /**
95
- * Client labels the backend will store on a play event.
93
+ * Client labels the server will store on a play event.
96
94
  *
97
- * A value outside this list does NOT fail the request: the controller records
95
+ * A value outside this list does NOT fail the request: the server records
98
96
  * the play with a `null` source rather than losing real listening history over
99
97
  * a typo. So a misspelt label is invisible until somebody audits by origin and
100
98
  * finds a pile of unlabelled rows.
@@ -117,13 +115,10 @@ export declare const MIX_KINDS: readonly ["top_artist", "this_is", "monthly_rewi
117
115
  */
118
116
  export type MixKind = (typeof MIX_KINDS)[number] | (string & {});
119
117
  /**
120
- * The compact `ArtistBlueprint` view, as it is embedded in mixes and in the
121
- * album/artist rows of the history endpoints.
122
- *
123
- * Blueprinter views ADD to the base rather than replace it, so `compact`
124
- * carries `id`, `created_at` and `updated_at` too. The `*_fs_node_id` keys are
125
- * a deliberate duplicate of the `*_media_id` ones, kept for the old web
126
- * frontend; read the `_media_id` form in new code.
118
+ * The compact artist, as it is embedded in mixes and in the album/artist rows
119
+ * of the history endpoints. It carries `id`, `created_at` and `updated_at`
120
+ * too. The `*_fs_node_id` keys are a legacy duplicate of the `*_media_id`
121
+ * ones; read the `_media_id` form in new code.
127
122
  */
128
123
  export interface MusicArtistPayload {
129
124
  readonly id: number;
@@ -138,7 +133,7 @@ export interface MusicArtistPayload {
138
133
  /** @deprecated Legacy twin of `compressed_image_media_id`, same value. */
139
134
  readonly compressed_image_fs_node_id?: string | null;
140
135
  }
141
- /** One artist credit on a song, as `SongArtistBlueprint` renders it. */
136
+ /** One artist credit on a song. */
142
137
  export interface MusicSongArtistPayload {
143
138
  readonly id: number;
144
139
  readonly created_at: Timestamp;
@@ -160,9 +155,9 @@ export interface MusicSongArtistPayload {
160
155
  /**
161
156
  * A song, as it is embedded in playlist rows, mixes, radios and history.
162
157
  *
163
- * This is a deliberate SUBSET of what `SongBlueprint` sends: the fields every
158
+ * This is a deliberate SUBSET of what the server sends: the fields every
164
159
  * consumer in this file needs, and no more. The full song type belongs to the
165
- * songs namespace, and duplicating thirty audio-metadata columns in two places
160
+ * songs namespace, and duplicating thirty audio-metadata fields in two places
166
161
  * is how the two copies drift apart. Extra keys ARE on the wire - cast when
167
162
  * you need `isrc`, the codec fields or the stem media ids.
168
163
  */
@@ -183,12 +178,8 @@ export interface MusicSongPayload {
183
178
  readonly compressed_artwork_media_id: string | null;
184
179
  }
185
180
  /**
186
- * A playlist.
187
- *
188
- * `visibility` and `owned` are newer than `docs/api-music.md` and than the
189
- * `Playlist` type in `oms-music/src/domain/playlist.ts`; both are on the wire
190
- * today. `owned` is computed against the ASKING user, which is what makes a
191
- * followed playlist distinguishable from your own in one listing.
181
+ * A playlist. `owned` is computed against the ASKING user, which is what makes
182
+ * a followed playlist distinguishable from your own in one listing.
192
183
  */
193
184
  export interface MusicPlaylist {
194
185
  readonly id: MusicPlaylistId;
@@ -234,9 +225,8 @@ export interface MusicPlaylistSong {
234
225
  readonly origin: PlaylistSongOrigin;
235
226
  /**
236
227
  * A `sync` row the owner removed. It stays so the next sync run finds it and
237
- * leaves it alone. Only the OWNER ever sees a hidden row: the listing filters
238
- * `hidden = FALSE OR playlists.user_id = <you>`, so a follower's page count
239
- * and the owner's differ for the same playlist.
228
+ * leaves it alone. Only the OWNER ever sees a hidden row, so a follower's
229
+ * page count and the owner's differ for the same playlist.
240
230
  */
241
231
  readonly hidden: boolean;
242
232
  /** The full song. Present on every row of every view. */
@@ -324,14 +314,7 @@ export interface RecentSongPlay {
324
314
  /** One row of `GET /play_events/recent?group_by=album`. */
325
315
  export interface RecentAlbumPlay {
326
316
  readonly album: string | null;
327
- /**
328
- * Lead artist of the album, compact view, or `null`.
329
- *
330
- * `oms-music/src/api/endpoints/playEvents.ts` types this as
331
- * `Artist | string | null` and calls the string case "legacy rows". No such
332
- * case exists in the Rails this was checked against: the album grouping joins
333
- * `song_artists` and renders a blueprint or `nil`, never a bare name.
334
- */
317
+ /** Lead artist of the album, compact view, or `null`. Never a bare name. */
335
318
  readonly artist: MusicArtistPayload | null;
336
319
  readonly artwork_media_id: string | null;
337
320
  /** @deprecated Legacy twin of `artwork_media_id`, same value. */
@@ -364,14 +347,14 @@ export interface ListPlaylistsParams extends ListParams<(typeof PLAYLIST_FILTER_
364
347
  /**
365
348
  * Partial, accent-insensitive match on the name, sent as `search[name]`.
366
349
  *
367
- * There is no filter for the owner and none for the visibility: the
368
- * controller's allowlist is `id`, `name`, `created_at`, `updated_at` and
369
- * nothing else, and an unrecognised filter key is a `400`, not a wider
350
+ * There is no filter for the owner and none for the visibility: the filter
351
+ * allowlist is `id`, `name`, `created_at`, `updated_at` and nothing else,
352
+ * and an unrecognised filter key is a `400`, not a wider
370
353
  * result. Use the `owned` flag on each row to tell yours from the ones you
371
354
  * follow.
372
355
  */
373
356
  readonly name?: string;
374
- /** Exact ids, sent as `exact_search[id][]`, which the backend turns into `IN`. */
357
+ /** Exact ids, sent as `exact_search[id][]`; any of them matches. */
375
358
  readonly ids?: readonly MusicPlaylistId[];
376
359
  }
377
360
  /** Arguments for {@link MusicPlaylistsNamespace.create}. */
@@ -407,9 +390,8 @@ export interface UpdatePlaylistInput {
407
390
  * Point the cover at an existing attachment, or pass `null` to purge the
408
391
  * current one. Refused with `401` on a system playlist.
409
392
  *
410
- * Omitting the key and passing `null` are different requests: the server
411
- * tests `params.key?`, so an absent key leaves the artwork alone and an
412
- * explicit `null` deletes it.
393
+ * Omitting the key and passing `null` are different requests: an absent key
394
+ * leaves the artwork alone and an explicit `null` deletes it.
413
395
  */
414
396
  readonly artworkMediaId?: string | null;
415
397
  }
@@ -458,7 +440,7 @@ export interface TopPlaysParams {
458
440
  /** Arguments for {@link PlayEventsNamespace.topSongs}. */
459
441
  export interface TopSongsParams extends TopPlaysParams {
460
442
  /**
461
- * Narrow to one artist by NAME - the backend canonicalises it and looks it
443
+ * Narrow to one artist by NAME - the server canonicalises it and looks it
462
444
  * up in your own roster. A name that matches nothing yields an empty array
463
445
  * rather than a `404`, so an empty result does not tell you which of the two
464
446
  * happened. Only `scope=song` honours this.
@@ -523,9 +505,9 @@ export declare class MusicPlaylistsNamespace extends Resource {
523
505
  * playlist you have not followed is readable by id but never enumerated here.
524
506
  *
525
507
  * The default order is `created_at:desc` rather than the server's, which is
526
- * unspecified. Offset pagination over an unordered query in Postgres can
527
- * repeat a row on one page and skip it on the next, so the SDK always sends
528
- * an order. Pass `order` to choose another one.
508
+ * unspecified. Offset pagination over an unordered query can repeat a row on
509
+ * one page and skip it on the next, so the SDK always sends an order. Pass
510
+ * `order` to choose another one.
529
511
  *
530
512
  * Filters are `name` and `ids` and nothing else - see
531
513
  * {@link ListPlaylistsParams.name} for why. Indexes carry an `ETag`, so a
@@ -557,7 +539,7 @@ export declare class MusicPlaylistsNamespace extends Resource {
557
539
  *
558
540
  * Not retried on a lost answer (the transport's default for a `POST`), because
559
541
  * a replay mints a second playlist. A `429` is still retried, and safely so:
560
- * this backend refuses before it writes.
542
+ * the server refuses before it writes.
561
543
  *
562
544
  * Ceiling: the general authenticated 600/min.
563
545
  *
@@ -612,8 +594,8 @@ export declare class MusicPlaylistsNamespace extends Resource {
612
594
  * renumbered densely from 1.
613
595
  *
614
596
  * Two things it will not do. It only copies a playlist you OWN - a friend's
615
- * playlist that {@link get} opens happily answers `401 "not yours"` here,
616
- * which `docs/api-music.md` does not mention. And the new name is built
597
+ * playlist that {@link get} opens happily answers `401 "not yours"` here.
598
+ * And the new name is built
617
599
  * server-side as `"<name> (cópia)"`, in Portuguese, whatever the client's
618
600
  * locale; rename it afterwards with {@link update} if that matters.
619
601
  *
@@ -628,13 +610,7 @@ export declare class MusicPlaylistsNamespace extends Resource {
628
610
  * `POST /playlists/:id/reorder` - rewrites the order of the playlist.
629
611
  *
630
612
  * Read this before calling it. The endpoint is not "move song X to slot N";
631
- * it is "here is the complete order", and the implementation is one line that
632
- * makes three things true at once:
633
- *
634
- * ```ruby
635
- * new_position = @song_ids.index(ps.song_id)
636
- * ps.update(position: new_position) if new_position
637
- * ```
613
+ * it is "here is the complete order", and three things are true at once:
638
614
  *
639
615
  * 1. **Positions become the INDEX in your array, so they start at 0.** Every
640
616
  * other path numbers from 1 (seeding) or from `max + 1` (appending). After
@@ -644,20 +620,19 @@ export declare class MusicPlaylistsNamespace extends Resource {
644
620
  * interleaves with, or collides with, the renumbered rows. So send the
645
621
  * complete order, always. Ordering by `position` after a partial reorder
646
622
  * gives an arrangement nobody asked for.
647
- * 3. **The ids are matched with `Array#index`, which is `==` on Integers.**
648
- * A string id matches nothing, so `["12","5"]` moves NOTHING and still
649
- * answers `200`. This is the silent failure this method exists to prevent:
650
- * it coerces to numbers and throws on anything that is not an integer.
623
+ * 3. **The ids are matched by identity against integers.** A string id
624
+ * matches nothing, so `["12","5"]` moves NOTHING and still answers `200`.
625
+ * This is the silent failure this method exists to prevent: it coerces to
626
+ * numbers and throws on anything that is not an integer.
651
627
  *
652
- * The response body is the reorderer's internal output (raw ActiveRecord JSON
653
- * of the join rows, not the blueprint) and is not part of the contract, so
654
- * this resolves to `undefined`. Refetch with
655
- * {@link PlaylistSongsNamespace.list} if you need the new state.
628
+ * The response body is not part of the contract, so this resolves to
629
+ * `undefined`. Refetch with {@link PlaylistSongsNamespace.list} if you need
630
+ * the new state.
656
631
  *
657
632
  * Ceiling: the general authenticated 600/min.
658
633
  *
659
- * @throws {TypeError} on an empty array (the service raises `ArgumentError`
660
- * for it, which is a 500, not a 400) or on an id that is not an integer.
634
+ * @throws {TypeError} on an empty array (the server answers a 500 for it,
635
+ * not a 400) or on an id that is not an integer.
661
636
  * @throws {OmsApiError} 404 when the playlist is not visible, 401 `"not yours"`
662
637
  * when it is visible but somebody else's - following it is not enough - and
663
638
  * 401 with the "make a copy first" sentence on a system playlist.
@@ -677,12 +652,12 @@ export declare class MusicPlaylistsNamespace extends Resource {
677
652
  * a 200 with no file in it.
678
653
  *
679
654
  * The bytes go through the music quota funnel, and replacing a cover
680
- * `purge_later`s the previous blob rather than leaking it. Note that this is
681
- * the only artwork path that spends quota: pointing `artworkMediaId` at an
655
+ * discards the previous blob rather than leaking it. Note that this is the
656
+ * only artwork path that spends quota: pointing `artworkMediaId` at an
682
657
  * existing attachment reuses the blob and costs nothing.
683
658
  *
684
659
  * Uploads are capped at roughly 100 MB by the CDN in front of the API, well
685
- * above anything an image crop produces; the app sends a JPEG of about 2 MB.
660
+ * above anything an image crop produces.
686
661
  *
687
662
  * Ceiling: the general authenticated 600/min.
688
663
  *
@@ -710,11 +685,10 @@ export declare class PlaylistSongsNamespace extends Resource {
710
685
  * "add to playlist" dialogue needs: one request tells you which playlists
711
686
  * already contain the song.
712
687
  *
713
- * The scope is `Playlist.viewable_by`, so this also lists a friend's `friends`
714
- * playlist. What a follower does NOT see is the hidden rows: the query is
715
- * `hidden = FALSE OR playlists.user_id = <you>`, so the same playlist has a
716
- * different length depending on who is asking. Do not use a row count from
717
- * here as the owner's row count.
688
+ * This also lists a friend's `friends` playlist. What a follower does NOT
689
+ * see is the hidden rows, so the same playlist has a different length
690
+ * depending on who is asking. Do not use a row count from here as the
691
+ * owner's row count.
718
692
  *
719
693
  * Every row carries a fully preloaded song (artists, artwork, audio and stem
720
694
  * media ids), so a page of 100 is a large payload. Ask for the page size you
@@ -731,10 +705,9 @@ export declare class PlaylistSongsNamespace extends Resource {
731
705
  * least {@link PLAYLIST_MANUAL_BLOCK_FLOOR} with `origin: "manual"`, so the
732
706
  * addition sits in a block the sync never renumbers.
733
707
  *
734
- * Adding to a system playlist WORKS. `docs/api-music.md` still says this is a
735
- * `401`, and it was before semi-sync landed; the current controller only
736
- * requires that you own the playlist. What is still refused on a system
737
- * playlist is renaming it, re-arting it and reordering it.
708
+ * Adding to a system playlist WORKS; the only requirement is that you own
709
+ * the playlist. What is still refused on a system playlist is renaming it,
710
+ * re-arting it and reordering it.
738
711
  *
739
712
  * Not retried on a lost answer: the unique index would turn the replay into a
740
713
  * `400`, reporting a failure for a row that was in fact created.
@@ -773,10 +746,7 @@ export declare class PlaylistSongsNamespace extends Resource {
773
746
  * with the updated row.
774
747
  *
775
748
  * This is what {@link remove} does implicitly to a sync row, made explicit and
776
- * available for manual rows too. Included even though it is not in the route
777
- * list this module was commissioned from, because exposing the hiding half of
778
- * the mechanism without {@link unhide} would leave a caller unable to undo a
779
- * `remove`.
749
+ * available for manual rows too.
780
750
  *
781
751
  * @throws {OmsApiError} 404 when the row is not visible, 401 when the playlist
782
752
  * is not yours.
@@ -818,7 +788,7 @@ export declare class MusicMixesNamespace extends Resource {
818
788
  *
819
789
  * Titles come twice over. `title` and `description` are an English fallback;
820
790
  * `title_key`/`title_params` and their description twins are the i18n
821
- * template the UI should actually render, so the shelf follows the app
791
+ * template the UI should actually render, so the shelf follows the caller's
822
792
  * language instead of being permanently one language. The embedded `artist`
823
793
  * is resolved at render time rather than cached with the shelf, so a picture
824
794
  * that lands today shows up today.
@@ -851,14 +821,13 @@ export declare class MusicMixesNamespace extends Resource {
851
821
  * Artist and song radios: about 40 tracks built by intersecting Last.fm
852
822
  * similar-artist data with what the caller actually owns.
853
823
  *
854
- * **This is the throttled family.** `/music_radios/*` sits behind
855
- * rack-attack's `external_proxy/by_session` rule at
824
+ * **This is the throttled family.** `/music_radios/*` is limited to
856
825
  * {@link MUSIC_RADIO_RATE_LIMIT_PER_MINUTE} requests per minute, shared with
857
826
  * `/lyrics`, `/artists/*` and `/artist_metadata/*`. The bucket key is the
858
827
  * `Authorization` HEADER when there is one and the client IP when there is not,
859
- * which has a consequence worth planning around: a cookie-authenticated web
860
- * client sends no `Authorization`, so every visitor behind one address shares a
861
- * single 60/min budget. Token clients get a bucket per token.
828
+ * which has a consequence worth planning around: a cookie-authenticated
829
+ * browser sends no `Authorization`, so every visitor behind one address shares
830
+ * a single 60/min budget. Token clients get a bucket per token.
862
831
  *
863
832
  * Over the limit the API answers `429` with a `Retry-After`, which the transport
864
833
  * honours by sleeping and retrying - a rate-limited call can therefore take most
@@ -870,20 +839,19 @@ export declare class MusicRadiosNamespace extends Resource {
870
839
  /**
871
840
  * `GET /music_radios/artist/:artist` - a radio seeded on one artist.
872
841
  *
873
- * Takes the artist's SLUG or their name: the backend canonicalises what you
874
- * send and tries `canonical_name` first, then `slug`. `docs/api-music.md` says
875
- * slug only, which understates it. Either way the lookup is against the
876
- * caller's own roster and never creates an artist, so an artist you do not
877
- * have is a `404` rather than an empty radio.
842
+ * Takes the artist's SLUG or their name: the server canonicalises what you
843
+ * send and tries `canonical_name` first, then `slug`. Either way the lookup
844
+ * is against the caller's own roster and never creates an artist, so an
845
+ * artist you do not have is a `404` rather than an empty radio.
878
846
  *
879
847
  * Roughly 30% of the tracks come from the seed artist and the rest from
880
- * similar artists you own, shuffled. The mix is drawn with `RANDOM()` on the
881
- * first build and then frozen for 7 days, so calling twice gives the same
882
- * radio, not a reshuffle.
848
+ * similar artists you own, shuffled. The mix is drawn at random on the first
849
+ * build and then frozen for 7 days, so calling twice gives the same radio,
850
+ * not a reshuffle.
883
851
  *
884
852
  * Ceiling: {@link MUSIC_RADIO_RATE_LIMIT_PER_MINUTE} per minute. A cold build
885
- * runs several queries over the whole library; the mobile app allows 60
886
- * seconds for it, and passing `timeoutMs` is reasonable here.
853
+ * runs several queries over the whole library; a `timeoutMs` of around 60
854
+ * seconds is reasonable here.
887
855
  *
888
856
  * @throws {OmsApiError} 404 `"Could not build radio for <artist>"` - the same
889
857
  * answer for "no such artist in your library" and for "nothing similar to
@@ -936,9 +904,8 @@ export declare class PlayEventsNamespace extends Resource {
936
904
  * doubled. The transport still will not replay a `POST` by default, so pass
937
905
  * `retry: {}` if a lost answer on a flaky connection should be tried again.
938
906
  *
939
- * Hosts usually treat this as fire-and-forget - the app does, with no error
940
- * UI - because a lost play event is worth less than an error toast during
941
- * playback.
907
+ * Treat this as fire-and-forget: a lost play event is worth less than an
908
+ * error toast during playback.
942
909
  *
943
910
  * `listenedSeconds` is clamped server-side rather than validated: `0` is the
944
911
  * floor and three times the track's duration is the ceiling, or 24 hours when
@@ -948,8 +915,8 @@ export declare class PlayEventsNamespace extends Resource {
948
915
  * Ceiling: the general authenticated 600/min. A client that posts one event
949
916
  * per track is nowhere near it; one that posts on every seek is not.
950
917
  *
951
- * @throws {OmsApiError} 400 when `songId` is missing (`ParameterMissing`), 404
952
- * `"Song not found"` when the song is not visible to you.
918
+ * @throws {OmsApiError} 400 when `songId` is missing, 404 `"Song not found"`
919
+ * when the song is not visible to you.
953
920
  */
954
921
  record(input: RecordPlayInput, options?: RequestOptions): Promise<RecordPlayResult>;
955
922
  /**
@@ -971,9 +938,9 @@ export declare class PlayEventsNamespace extends Resource {
971
938
  * `GET /play_events/recent?group_by=album` - recently played albums.
972
939
  *
973
940
  * Grouped by album name AND lead artist, so two albums with the same title by
974
- * different artists stay apart. Songs with no album are excluded entirely -
975
- * the query filters `album NOT IN (NULL, '')` - so a library of loose singles
976
- * produces an empty shelf here while {@link recentSongs} is full.
941
+ * different artists stay apart. Songs with no album (null or empty) are
942
+ * excluded entirely, so a library of loose singles produces an empty shelf
943
+ * here while {@link recentSongs} is full.
977
944
  *
978
945
  * Ceiling: the general authenticated 600/min.
979
946
  */