javascript-ampache 1.1.10 → 2.0.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.
Files changed (108) hide show
  1. package/README.md +16 -6
  2. package/dist/index.js +1 -1
  3. package/dist/index.js.map +1 -1
  4. package/dist/index.m.js +1 -1
  5. package/dist/index.m.js.map +1 -1
  6. package/dist/index.modern.mjs +1 -1
  7. package/dist/index.modern.mjs.map +1 -1
  8. package/dist/index.umd.js +1 -1
  9. package/dist/index.umd.js.map +1 -1
  10. package/package.json +8 -7
  11. package/src/albums.js +106 -0
  12. package/src/artists.js +105 -0
  13. package/src/auth.js +142 -0
  14. package/src/base.js +145 -0
  15. package/src/bookmarks.js +106 -0
  16. package/src/catalogs.js +133 -0
  17. package/src/genres.js +57 -0
  18. package/src/index.js +30 -0
  19. package/src/labels.js +53 -0
  20. package/src/licenses.js +47 -0
  21. package/src/live-streams.js +97 -0
  22. package/src/playlists.js +241 -0
  23. package/src/podcasts.js +230 -0
  24. package/src/preferences.js +114 -0
  25. package/src/shares.js +99 -0
  26. package/src/shouts.js +24 -0
  27. package/src/songs.js +273 -0
  28. package/src/system.js +510 -0
  29. package/src/users.js +224 -0
  30. package/src/{utils.ts → utils.js} +16 -16
  31. package/src/videos.js +84 -0
  32. package/dist/albums/index.d.ts +0 -64
  33. package/dist/albums/types.d.ts +0 -37
  34. package/dist/artists/index.d.ts +0 -64
  35. package/dist/artists/types.d.ts +0 -35
  36. package/dist/auth/index.d.ts +0 -56
  37. package/dist/auth/types.d.ts +0 -32
  38. package/dist/base.d.ts +0 -47
  39. package/dist/bookmarks/index.d.ts +0 -91
  40. package/dist/bookmarks/types.d.ts +0 -13
  41. package/dist/catalogs/index.d.ts +0 -87
  42. package/dist/catalogs/types.d.ts +0 -19
  43. package/dist/genres/index.d.ts +0 -28
  44. package/dist/genres/types.d.ts +0 -22
  45. package/dist/index.d.ts +0 -24
  46. package/dist/labels/index.d.ts +0 -32
  47. package/dist/labels/types.d.ts +0 -18
  48. package/dist/licenses/index.d.ts +0 -32
  49. package/dist/licenses/types.d.ts +0 -12
  50. package/dist/live-streams/index.d.ts +0 -80
  51. package/dist/live-streams/types.d.ts +0 -14
  52. package/dist/playlists/index.d.ts +0 -204
  53. package/dist/playlists/types.d.ts +0 -26
  54. package/dist/podcasts/index.d.ts +0 -121
  55. package/dist/podcasts/types.d.ts +0 -79
  56. package/dist/preferences/index.d.ts +0 -80
  57. package/dist/preferences/types.d.ts +0 -18
  58. package/dist/shares/index.d.ts +0 -69
  59. package/dist/shares/types.d.ts +0 -23
  60. package/dist/shouts/index.d.ts +0 -17
  61. package/dist/shouts/types.d.ts +0 -10
  62. package/dist/songs/index.d.ts +0 -143
  63. package/dist/songs/types.d.ts +0 -73
  64. package/dist/system/index.d.ts +0 -407
  65. package/dist/system/types.d.ts +0 -24
  66. package/dist/users/index.d.ts +0 -190
  67. package/dist/users/types.d.ts +0 -34
  68. package/dist/utils.d.ts +0 -4
  69. package/dist/videos/index.d.ts +0 -33
  70. package/dist/videos/types.d.ts +0 -38
  71. package/src/albums/index.ts +0 -88
  72. package/src/albums/types.ts +0 -40
  73. package/src/artists/index.ts +0 -88
  74. package/src/artists/types.ts +0 -38
  75. package/src/auth/index.ts +0 -118
  76. package/src/auth/types.ts +0 -32
  77. package/src/base.ts +0 -133
  78. package/src/bookmarks/index.ts +0 -116
  79. package/src/bookmarks/types.ts +0 -15
  80. package/src/catalogs/index.ts +0 -130
  81. package/src/catalogs/types.ts +0 -27
  82. package/src/genres/index.ts +0 -39
  83. package/src/genres/types.ts +0 -25
  84. package/src/index.ts +0 -63
  85. package/src/labels/index.ts +0 -43
  86. package/src/labels/types.ts +0 -20
  87. package/src/licenses/index.ts +0 -43
  88. package/src/licenses/types.ts +0 -14
  89. package/src/live-streams/index.ts +0 -104
  90. package/src/live-streams/types.ts +0 -16
  91. package/src/playlists/index.ts +0 -280
  92. package/src/playlists/types.ts +0 -29
  93. package/src/podcasts/index.ts +0 -174
  94. package/src/podcasts/types.ts +0 -85
  95. package/src/preferences/index.ts +0 -114
  96. package/src/preferences/types.ts +0 -20
  97. package/src/shares/index.ts +0 -100
  98. package/src/shares/types.ts +0 -25
  99. package/src/shouts/index.ts +0 -18
  100. package/src/shouts/types.ts +0 -11
  101. package/src/songs/index.ts +0 -221
  102. package/src/songs/types.ts +0 -77
  103. package/src/system/index.ts +0 -845
  104. package/src/system/types.ts +0 -42
  105. package/src/users/index.ts +0 -227
  106. package/src/users/types.ts +0 -38
  107. package/src/videos/index.ts +0 -49
  108. package/src/videos/types.ts +0 -42
package/package.json CHANGED
@@ -1,31 +1,32 @@
1
1
  {
2
2
  "name": "javascript-ampache",
3
- "version": "1.1.10",
3
+ "version": "2.0.0",
4
4
  "description": "A JS library for the Ampache API",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.m.js",
7
7
  "umd:main": "dist/index.umd.js",
8
- "source": "src/index.ts",
8
+ "source": "src/index.js",
9
9
  "repository": "github:mitchray/javascript-ampache",
10
10
  "scripts": {
11
- "build": "rimraf dist && microbundle --tsconfig tsconfig.json",
12
- "dev": "microbundle watch --tsconfig tsconfig.json",
11
+ "build": "rimraf dist && microbundle",
12
+ "dev": "microbundle watch",
13
13
  "test": "jest"
14
14
  },
15
15
  "devDependencies": {
16
- "@types/jest": "^25.2.3",
16
+ "@babel/preset-env": "^7.29.0",
17
+ "babel-jest": "^30.2.0",
17
18
  "isomorphic-unfetch": "^3.1.0",
18
19
  "jest": "^29.3.1",
19
20
  "jssha": "^3.3.0",
20
21
  "microbundle": "^0.15.1",
21
22
  "nock": "^13.0.0",
23
+ "node-fetch": "^2.7.0",
22
24
  "querystringify": "2.2.0",
23
25
  "rimraf": "^5.0.0"
24
26
  },
25
27
  "keywords": [
26
28
  "ampache",
27
29
  "javascript",
28
- "typescript",
29
30
  "api",
30
31
  "js"
31
32
  ],
@@ -35,4 +36,4 @@
35
36
  "src",
36
37
  "dist"
37
38
  ]
38
- }
39
+ }
package/src/albums.js ADDED
@@ -0,0 +1,106 @@
1
+ /**
2
+ * @typedef {Object} AlbumSummary
3
+ * @property {import("./base.js").UID} id
4
+ * @property {string} name
5
+ * @property {string|null} prefix
6
+ * @property {string} basename
7
+ */
8
+
9
+ /**
10
+ * @typedef {Object} AlbumResponse
11
+ * @property {import("./base.js").UID} id
12
+ * @property {string} name
13
+ * @property {string|null} prefix
14
+ * @property {string} basename
15
+ * @property {import("./artists.js").ArtistSummary} artist
16
+ * @property {import("./artists.js").ArtistSummary[]} artists
17
+ * @property {import("./artists.js").ArtistSummary[]} songartists
18
+ * @property {number} time
19
+ * @property {number|string} year
20
+ * @property {import("./songs.js").SongResponse[]} [tracks]
21
+ * @property {number} songcount
22
+ * @property {number} disccount
23
+ * @property {string|null} type
24
+ * @property {import("./genres.js").GenreSummary[]} genre
25
+ * @property {string} art
26
+ * @property {boolean} has_art
27
+ * @property {boolean} flag
28
+ * @property {number|null} rating
29
+ * @property {number|null} averagerating
30
+ * @property {string|null} mbid
31
+ */
32
+
33
+ /**
34
+ * @typedef {Object} AlbumsResponse
35
+ * @property {number} total_count
36
+ * @property {string} md5
37
+ * @property {AlbumResponse[]} album
38
+ */
39
+
40
+ export const albumsMethods = {
41
+ /**
42
+ * This returns albums based on the provided search filters
43
+ * @remarks MINIMUM_API_VERSION=380001
44
+ * @param {Object} [params]
45
+ * @param {string} [params.filter] Filter results to match this string
46
+ * @param {import("./base.js").BinaryBoolean} [params.exact] 0, 1 (if true filter is exact = rather than fuzzy LIKE)
47
+ * @param {Date} [params.add] ISO 8601 Date Format (2020-09-16) Find objects with an 'add' date newer than the specified date
48
+ * @param {Date} [params.update] ISO 8601 Date Format (2020-09-16) Find objects with an 'update' time newer than the specified date
49
+ * @param {"albums"|"songs"} [params.include] albums, songs (include child objects in the response)
50
+ * @param {number} [params.offset]
51
+ * @param {number} [params.limit]
52
+ * @param {string} [params.cond]
53
+ * @param {string} [params.sort]
54
+ * @returns {Promise<AlbumsResponse>}
55
+ * @see {@link https://ampache.org/api/api-json-methods#albums}
56
+ */
57
+ albums(params) {
58
+ return this.call("albums", params);
59
+ },
60
+
61
+ /**
62
+ * This returns a single album based on the UID provided
63
+ * @remarks MINIMUM_API_VERSION=380001
64
+ * @param {Object} params
65
+ * @param {import("./base.js").UID} params.filter UID to find
66
+ * @param {"songs"} [params.include] songs (include child objects in the response)
67
+ * @returns {Promise<AlbumResponse>}
68
+ * @see {@link https://ampache.org/api/api-json-methods#album}
69
+ */
70
+ album(params) {
71
+ return this.call("album", params);
72
+ },
73
+
74
+ /**
75
+ * This returns the albums of an artist
76
+ * @remarks MINIMUM_API_VERSION=380001
77
+ * @param {Object} params
78
+ * @param {import("./base.js").UID} params.filter UID to find
79
+ * @param {import("./base.js").BinaryBoolean} [params.album_artist] 0, 1 (if true filter for album artists only)
80
+ * @param {number} [params.offset]
81
+ * @param {number} [params.limit]
82
+ * @param {string} [params.cond]
83
+ * @param {string} [params.sort]
84
+ * @returns {Promise<AlbumsResponse>}
85
+ * @see {@link https://ampache.org/api/api-json-methods#artist_albums}
86
+ */
87
+ artistAlbums(params) {
88
+ return this.call("artist_albums", params);
89
+ },
90
+
91
+ /**
92
+ * This returns the albums associated with the genre in question
93
+ * @remarks MINIMUM_API_VERSION=380001
94
+ * @param {Object} [params]
95
+ * @param {import("./base.js").UID} [params.filter] UID to find
96
+ * @param {number} [params.offset]
97
+ * @param {number} [params.limit]
98
+ * @param {string} [params.cond]
99
+ * @param {string} [params.sort]
100
+ * @returns {Promise<AlbumsResponse>}
101
+ * @see {@link https://ampache.org/api/api-json-methods#genre_albums}
102
+ */
103
+ genreAlbums(params) {
104
+ return this.call("genre_albums", params);
105
+ },
106
+ };
package/src/artists.js ADDED
@@ -0,0 +1,105 @@
1
+ /**
2
+ * @typedef {Object} ArtistSummary
3
+ * @property {string} id
4
+ * @property {string} name
5
+ * @property {string|null} prefix
6
+ * @property {string} basename
7
+ */
8
+
9
+ /**
10
+ * @typedef {Object} ArtistResponse
11
+ * @property {string} id
12
+ * @property {string} name
13
+ * @property {string|null} prefix
14
+ * @property {string} basename
15
+ * @property {import("./albums.js").AlbumResponse[]} albums
16
+ * @property {number} albumcount
17
+ * @property {import("./songs.js").SongsResponse[]} songs
18
+ * @property {number} songcount
19
+ * @property {import("./genres.js").GenreResponse[]} genre
20
+ * @property {string} art
21
+ * @property {boolean} has_art
22
+ * @property {boolean} flag
23
+ * @property {number|null} rating
24
+ * @property {number|null} averagerating
25
+ * @property {string|null} mbid
26
+ * @property {string} summary
27
+ * @property {number} time
28
+ * @property {number} yearformed
29
+ * @property {string} placeformed
30
+ */
31
+
32
+ /**
33
+ * @typedef {Object} ArtistsResponse
34
+ * @property {number} total_count
35
+ * @property {string} md5
36
+ * @property {ArtistResponse[]} artist
37
+ */
38
+
39
+ export const artistsMethods = {
40
+ /**
41
+ * This takes a collection of inputs and returns artist objects
42
+ * @remarks MINIMUM_API_VERSION=380001
43
+ * @param {Object} [params]
44
+ * @param {string} [params.filter] Filter results to match this string
45
+ * @param {import("./base.js").BinaryBoolean} [params.exact] 0, 1 (if true filter is exact = rather than fuzzy LIKE)
46
+ * @param {Date} [params.add] ISO 8601 Date Format (2020-09-16) Find objects with an 'add' date newer than the specified date
47
+ * @param {Date} [params.update] ISO 8601 Date Format (2020-09-16) Find objects with an 'update' time newer than the specified date
48
+ * @param {"albums"|"songs"} [params.include] (albums | songs) include child objects in the response
49
+ * @param {import("./base.js").BinaryBoolean} [params.album_artist] 0, 1 (if true filter for album artists only)
50
+ * @param {number} [params.offset]
51
+ * @param {number} [params.limit]
52
+ * @param {string} [params.cond]
53
+ * @param {string} [params.sort]
54
+ * @returns {Promise<ArtistsResponse>}
55
+ * @see {@link https://ampache.org/api/api-json-methods#artists}
56
+ */
57
+ artists(params) {
58
+ return this.call("artists", params);
59
+ },
60
+
61
+ /**
62
+ * This returns a single artist based on the UID of said artist
63
+ * @remarks MINIMUM_API_VERSION=380001
64
+ * @param {Object} params
65
+ * @param {import("./base.js").UID} params.filter UID to find
66
+ * @param {"albums"|"songs"} [params.include] (albums | songs) include child objects in the response
67
+ * @returns {Promise<ArtistResponse>}
68
+ * @see {@link https://ampache.org/api/api-json-methods#artist}
69
+ */
70
+ artist(params) {
71
+ return this.call("artist", params);
72
+ },
73
+
74
+ /**
75
+ * This returns the artists associated with the genre in question as defined by the UID
76
+ * @remarks MINIMUM_API_VERSION=380001
77
+ * @param {Object} params
78
+ * @param {import("./base.js").UID} params.filter UID to find
79
+ * @param {number} [params.offset]
80
+ * @param {number} [params.limit]
81
+ * @param {string} [params.cond]
82
+ * @param {string} [params.sort]
83
+ * @returns {Promise<ArtistsResponse>}
84
+ * @see {@link https://ampache.org/api/api-json-methods#genre_artists}
85
+ */
86
+ genreArtists(params) {
87
+ return this.call("genre_artists", params);
88
+ },
89
+
90
+ /**
91
+ * This returns the artists associated with the label in question as defined by the UID
92
+ * @remarks MINIMUM_API_VERSION=420000
93
+ * @param {Object} params
94
+ * @param {import("./base.js").UID} params.filter UID of find
95
+ * @param {number} [params.offset]
96
+ * @param {number} [params.limit]
97
+ * @param {string} [params.cond]
98
+ * @param {string} [params.sort]
99
+ * @returns {Promise<ArtistsResponse>}
100
+ * @see {@link https://ampache.org/api/api-json-methods#label_artists}
101
+ */
102
+ labelArtists(params) {
103
+ return this.call("label_artists", params);
104
+ },
105
+ };
package/src/auth.js ADDED
@@ -0,0 +1,142 @@
1
+ /**
2
+ * @typedef {Object} AuthResponse
3
+ * @property {string} add
4
+ * @property {number} albums
5
+ * @property {string} api
6
+ * @property {number} artists
7
+ * @property {string} auth
8
+ * @property {number} catalogs
9
+ * @property {string} compatible
10
+ * @property {string} clean
11
+ * @property {number} genres
12
+ * @property {number} labels
13
+ * @property {number} licenses
14
+ * @property {number} live_streams
15
+ * @property {number} playlists
16
+ * @property {number} podcasts
17
+ * @property {number} podcast_episodes
18
+ * @property {string} server
19
+ * @property {string} session_expire
20
+ * @property {number} shares
21
+ * @property {number} songs
22
+ * @property {string} update
23
+ * @property {number} user
24
+ * @property {string} username
25
+ * @property {string} version
26
+ * @property {number} videos
27
+ * @property {number} max_song
28
+ * @property {number} max_album
29
+ * @property {number} max_artist
30
+ * @property {number} max_video
31
+ * @property {number} max_podcast
32
+ * @property {number} max_podcast_episode
33
+ */
34
+
35
+ import qs from "querystringify";
36
+ import fetch from "isomorphic-unfetch";
37
+ import { outputDebugURL, encryptPassword as encryptPasswordUtil } from "./utils.js";
38
+
39
+ export const authMethods = {
40
+ /**
41
+ * Handles verifying a new handshake
42
+ * @remarks MINIMUM_API_VERSION=380001
43
+ * @param {Object} params
44
+ * @param {string} params.auth encrypted apikey OR password if using password auth
45
+ * @param {string} [params.user] username
46
+ * @param {number} [params.timestamp] UNIXTIME()
47
+ * @param {string} [params.version] version of Ampache API to establish connection with
48
+ * @returns {Promise<AuthResponse>}
49
+ * @see {@link https://ampache.org/api/api-json-methods#handshake}
50
+ */
51
+ handshake(params) {
52
+ let token = params.auth;
53
+
54
+ // generate a timestamp if one wasn't provided
55
+ if (!params.timestamp) {
56
+ params.timestamp = Math.floor(new Date().getTime() / 1000);
57
+ }
58
+
59
+ // override the fallback API version with specified
60
+ if (params.version) {
61
+ this.version = params.version;
62
+ }
63
+
64
+ // drop timestamp if no user provided (i.e. logging in with API key)
65
+ if (!params.user) {
66
+ delete params.timestamp;
67
+ }
68
+
69
+ // not needed if using Bearer token
70
+ if (this.useBearerToken) {
71
+ delete params.auth;
72
+ }
73
+
74
+ let query = this.url + "/server/json.server.php?action=handshake";
75
+ query += qs.stringify(params, "&");
76
+
77
+ if (this.debug) {
78
+ outputDebugURL(query, this);
79
+ }
80
+
81
+ return fetch(query, {
82
+ method: "GET",
83
+ headers: this.useBearerToken ? { Authorization: "Bearer " + token } : {},
84
+ })
85
+ .then((response) => response.json())
86
+ .then((data) => {
87
+ if (data.auth) {
88
+ this.sessionKey = data.auth;
89
+ }
90
+ return /** @type {AuthResponse} */ (data);
91
+ });
92
+ },
93
+
94
+ /**
95
+ * This can be called without being authenticated, it is useful for determining if what the status
96
+ * of the server is, and what version it is running/compatible with
97
+ * @remarks MINIMUM_API_VERSION=380001
98
+ * @param {Object} [params]
99
+ * @param {string} [params.auth] (Session ID) returns version information and extends the session if passed
100
+ * @param {string} [params.version] API Version that the application understands
101
+ * @returns {Promise<AuthResponse>}
102
+ * @see {@link https://ampache.org/api/api-json-methods#ping}
103
+ */
104
+ ping(params) {
105
+ return this.call("ping", params);
106
+ },
107
+
108
+ /**
109
+ * Destroy a session using the session auth parameter
110
+ * @remarks MINIMUM_API_VERSION=400001
111
+ * @param {Object} params
112
+ * @param {string} params.auth Session ID to destroy
113
+ * @returns {Promise<import("./base.js").Success>}
114
+ * @see {@link https://ampache.org/api/api-json-methods#goodbye}
115
+ */
116
+ goodbye(params) {
117
+ return this.call("goodbye", params);
118
+ },
119
+
120
+ /**
121
+ * Email a new password to the user (if allowed) using a reset token.
122
+ * @remarks MINIMUM_API_VERSION=6.1.0
123
+ * @param {Object} params
124
+ * @param {string} params.auth Password reset token
125
+ * @returns {Promise<import("./base.js").Success>}
126
+ * @see {@link https://ampache.org/api/api-json-methods#lost_password}
127
+ */
128
+ lostPassword(params) {
129
+ return this.call("lost_password", params);
130
+ },
131
+
132
+ /**
133
+ * Encrypt your password into the accepted format.
134
+ * @param {Object} params
135
+ * @param {string} params.password
136
+ * @param {number} params.time
137
+ * @returns {string}
138
+ */
139
+ encryptPassword(params) {
140
+ return encryptPasswordUtil(params.password, params.time);
141
+ },
142
+ };
package/src/base.js ADDED
@@ -0,0 +1,145 @@
1
+ import fetch from "isomorphic-unfetch";
2
+ import qs from "querystringify";
3
+ import { outputDebugURL } from "./utils.js";
4
+
5
+ /**
6
+ * @typedef {Object} Config
7
+ * @property {string} url
8
+ * @property {string} [sessionKey]
9
+ * @property {boolean} [useBearerToken]
10
+ * @property {boolean} [debug]
11
+ */
12
+
13
+ /**
14
+ * @typedef {Object} Success
15
+ * @property {string} success
16
+ */
17
+
18
+ /**
19
+ * @typedef {Object} Pagination
20
+ * @property {number} [offset] Return results starting from this index position
21
+ * @property {number} [limit] Maximum number of results to return
22
+ */
23
+
24
+ /**
25
+ * @typedef {Object} ExtendedPagination
26
+ * @property {number} [offset] Return results starting from this index position
27
+ * @property {number} [limit] Maximum number of results to return
28
+ * @property {string} [cond] Apply additional filters to the browse using ; separated comma string pairs (e.g. 'filter1,value1;filter2,value2')
29
+ * @property {string} [sort] Sort name or comma-separated key pair. (e.g. 'name,order') Default order 'ASC' (e.g. 'name,ASC' == 'name')
30
+ */
31
+
32
+ /** @typedef {0|1} BinaryBoolean */
33
+
34
+ /** @typedef {string|number} UID */
35
+
36
+ export class Base {
37
+ /**
38
+ * @param {Config} config
39
+ */
40
+ constructor(config) {
41
+ this.sessionKey = config.sessionKey || null;
42
+ this.url = config.url;
43
+ this.version = "6.6.8";
44
+ this.useBearerToken = config.useBearerToken || false;
45
+ this.debug = config.debug || false;
46
+ }
47
+
48
+ /**
49
+ * Build action string with optional params and call request.
50
+ * @template T
51
+ * @param {string} action API action name
52
+ * @param {Object} [params] Optional query params
53
+ * @returns {Promise<T>}
54
+ */
55
+ call(action, params) {
56
+ const query = action + (params != null ? qs.stringify(params, "&") : "");
57
+ return this.request(query);
58
+ }
59
+
60
+ /**
61
+ * @param {string} endpoint Action and optional query string
62
+ * @returns {string} Full request URL
63
+ * @private
64
+ */
65
+ _buildURL(endpoint) {
66
+ let url =
67
+ this.url +
68
+ "/server/json.server.php?action=" +
69
+ endpoint +
70
+ "&version=" +
71
+ this.version;
72
+
73
+ if (!this.useBearerToken) {
74
+ url += "&auth=" + this.sessionKey;
75
+ }
76
+
77
+ if (this.debug) {
78
+ outputDebugURL(url, this);
79
+ }
80
+
81
+ return url;
82
+ }
83
+
84
+ /**
85
+ * @template T
86
+ * @param {string} endpoint
87
+ * @returns {Promise<T>}
88
+ */
89
+ request(endpoint) {
90
+ const url = this._buildURL(endpoint);
91
+ return fetch(url, {
92
+ method: "GET",
93
+ headers: this.useBearerToken ? { Authorization: "Bearer " + this.sessionKey } : {},
94
+ }).then(async (r) => {
95
+ if (r.ok) {
96
+ return r.json();
97
+ }
98
+ let body = r.statusText;
99
+ const contentType = r.headers.get("content-type");
100
+ try {
101
+ body = contentType && contentType.includes("application/json")
102
+ ? await r.json()
103
+ : await r.text();
104
+ } catch (_) {
105
+ // keep statusText if body read fails
106
+ }
107
+ const err = new Error(r.statusText);
108
+ err.status = r.status;
109
+ err.body = body;
110
+ throw err;
111
+ });
112
+ }
113
+
114
+ /**
115
+ * @param {string} endpoint
116
+ * @returns {Promise<Blob>}
117
+ */
118
+ binary(endpoint) {
119
+ const url = this._buildURL(endpoint);
120
+ return fetch(url, {
121
+ method: "GET",
122
+ headers: this.useBearerToken ? { Authorization: "Bearer " + this.sessionKey } : {},
123
+ }).then((response) => response.blob());
124
+ }
125
+
126
+ /**
127
+ * @param {string} sessionKey
128
+ */
129
+ setSessionKey(sessionKey) {
130
+ this.sessionKey = sessionKey;
131
+ }
132
+
133
+ /**
134
+ * Construct and return a URL
135
+ * @param {string} endpoint
136
+ * @param {Object} [params]
137
+ * @returns {string}
138
+ */
139
+ rawURL(endpoint, params) {
140
+ const query = endpoint + (params != null ? qs.stringify(params, "&") : "");
141
+ return this._buildURL(query);
142
+ }
143
+ }
144
+
145
+ export {};
@@ -0,0 +1,106 @@
1
+ /**
2
+ * @typedef {Object} BookmarkResponse
3
+ * @property {import("./base.js").UID} id
4
+ * @property {"song"|"video"|"podcast_episode"} type
5
+ * @property {number} position
6
+ * @property {string} [client]
7
+ * @property {number} [date]
8
+ */
9
+
10
+ /**
11
+ * @typedef {Object} BookmarksResponse
12
+ * @property {number} total_count
13
+ * @property {string} md5
14
+ * @property {BookmarkResponse[]} bookmark
15
+ */
16
+
17
+ export const bookmarksMethods = {
18
+ /**
19
+ * Get a single bookmark by bookmark_id
20
+ * @remarks MINIMUM_API_VERSION=6.1.0
21
+ * @param {Object} params
22
+ * @param {import("./base.js").UID} params.filter UID to find
23
+ * @param {import("./base.js").BinaryBoolean} [params.include] 0,1, if true include the object in the bookmark
24
+ * @returns {Promise<BookmarkResponse>}
25
+ * @see {@link https://ampache.org/api/api-json-methods#bookmark}
26
+ */
27
+ bookmark(params) {
28
+ return this.call("bookmark", params);
29
+ },
30
+
31
+ /**
32
+ * Get information about bookmarked media this user is allowed to manage
33
+ * @remarks MINIMUM_API_VERSION=5.0.0
34
+ * @param {Object} [params]
35
+ * @param {string} [params.client] filter by the agent/client name
36
+ * @param {import("./base.js").BinaryBoolean} [params.include] 0,1, if true include the object in the bookmark
37
+ * @returns {Promise<BookmarksResponse>}
38
+ * @see {@link https://ampache.org/api/api-json-methods#bookmarks}
39
+ */
40
+ bookmarks(params) {
41
+ return this.call("bookmarks", params);
42
+ },
43
+
44
+ /**
45
+ * Get the bookmark/s from its object_id and object_type.
46
+ * @remarks MINIMUM_API_VERSION=5.0.0
47
+ * @param {Object} params
48
+ * @param {import("./base.js").UID} params.filter UID to find
49
+ * @param {"song"|"video"|"podcast_episode"} params.type Object type
50
+ * @param {import("./base.js").BinaryBoolean} [params.include] 0,1, if true include the object in the bookmark
51
+ * @param {import("./base.js").BinaryBoolean} [params.all]
52
+ * @returns {Promise<BookmarkResponse>}
53
+ * @see {@link https://ampache.org/api/api-json-methods#get_bookmark}
54
+ */
55
+ getBookmark(params) {
56
+ return this.call("get_bookmark", params);
57
+ },
58
+
59
+ /**
60
+ * Create a placeholder for the current media that you can return to later.
61
+ * @remarks MINIMUM_API_VERSION=5.0.0
62
+ * @param {Object} params
63
+ * @param {import("./base.js").UID} params.filter UID to find
64
+ * @param {"song"|"video"|"podcast_episode"} params.type Object type
65
+ * @param {number} params.position current track time in seconds
66
+ * @param {string} [params.client] Agent string. (Default: 'AmpacheAPI')
67
+ * @param {number} [params.date] update time (Default: UNIXTIME())
68
+ * @param {import("./base.js").BinaryBoolean} [params.include] 0,1, if true include the object in the bookmark
69
+ * @returns {Promise<BookmarkResponse>}
70
+ * @see {@link https://ampache.org/api/api-json-methods#bookmark_create}
71
+ */
72
+ bookmarkCreate(params) {
73
+ return this.call("bookmark_create", params);
74
+ },
75
+
76
+ /**
77
+ * Edit a placeholder for the current media that you can return to later.
78
+ * @remarks MINIMUM_API_VERSION=5.0.0
79
+ * @param {Object} params
80
+ * @param {import("./base.js").UID} params.filter UID to find
81
+ * @param {"bookmark"|"song"|"video"|"podcast_episode"} params.type Object type
82
+ * @param {number} params.position current track time in seconds
83
+ * @param {string} [params.client] Agent string. (Default: 'AmpacheAPI')
84
+ * @param {number} [params.date] update time (Default: UNIXTIME())
85
+ * @param {import("./base.js").BinaryBoolean} [params.include] 0,1, if true include the object in the bookmark
86
+ * @returns {Promise<BookmarkResponse>}
87
+ * @see {@link https://ampache.org/api/api-json-methods#bookmark_edit}
88
+ */
89
+ bookmarkEdit(params) {
90
+ return this.call("bookmark_edit", params);
91
+ },
92
+
93
+ /**
94
+ * Delete an existing bookmark. (if it exists)
95
+ * @remarks MINIMUM_API_VERSION=5.0.0
96
+ * @param {Object} params
97
+ * @param {import("./base.js").UID} params.filter UID to find
98
+ * @param {"song"|"video"|"podcast_episode"} params.type Object type
99
+ * @param {string} [params.client] Agent string. (Default: 'AmpacheAPI')
100
+ * @returns {Promise<import("./base.js").Success>}
101
+ * @see {@link https://ampache.org/api/api-json-methods#bookmark_delete}
102
+ */
103
+ bookmarkDelete(params) {
104
+ return this.call("bookmark_delete", params);
105
+ },
106
+ };