javascript-ampache 1.0.2 → 1.0.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.
@@ -1 +1 @@
1
- {"version":3,"file":"index.modern.mjs","sources":["../node_modules/querystringify/index.js","../node_modules/unfetch/dist/unfetch.module.js","../node_modules/isomorphic-unfetch/browser.js","../src/base.ts","../node_modules/jssha/dist/sha256.mjs","../src/index.ts","../src/utils.ts","../src/albums/index.ts","../src/artists/index.ts","../src/auth/index.ts","../src/bookmarks/index.ts","../src/catalogs/index.ts","../src/genres/index.ts","../src/labels/index.ts","../src/licenses/index.ts","../src/live-streams/index.ts","../src/playlists/index.ts","../src/podcasts/index.ts","../src/preferences/index.ts","../src/shares/index.ts","../src/shouts/index.ts","../src/songs/index.ts","../src/system/index.ts","../src/users/index.ts","../src/videos/index.ts"],"sourcesContent":["'use strict';\n\nvar has = Object.prototype.hasOwnProperty\n , undef;\n\n/**\n * Decode a URI encoded string.\n *\n * @param {String} input The URI encoded string.\n * @returns {String|Null} The decoded string.\n * @api private\n */\nfunction decode(input) {\n try {\n return decodeURIComponent(input.replace(/\\+/g, ' '));\n } catch (e) {\n return null;\n }\n}\n\n/**\n * Attempts to encode a given input.\n *\n * @param {String} input The string that needs to be encoded.\n * @returns {String|Null} The encoded string.\n * @api private\n */\nfunction encode(input) {\n try {\n return encodeURIComponent(input);\n } catch (e) {\n return null;\n }\n}\n\n/**\n * Simple query string parser.\n *\n * @param {String} query The query string that needs to be parsed.\n * @returns {Object}\n * @api public\n */\nfunction querystring(query) {\n var parser = /([^=?#&]+)=?([^&]*)/g\n , result = {}\n , part;\n\n while (part = parser.exec(query)) {\n var key = decode(part[1])\n , value = decode(part[2]);\n\n //\n // Prevent overriding of existing properties. This ensures that build-in\n // methods like `toString` or __proto__ are not overriden by malicious\n // querystrings.\n //\n // In the case if failed decoding, we want to omit the key/value pairs\n // from the result.\n //\n if (key === null || value === null || key in result) continue;\n result[key] = value;\n }\n\n return result;\n}\n\n/**\n * Transform a query string to an object.\n *\n * @param {Object} obj Object that should be transformed.\n * @param {String} prefix Optional prefix.\n * @returns {String}\n * @api public\n */\nfunction querystringify(obj, prefix) {\n prefix = prefix || '';\n\n var pairs = []\n , value\n , key;\n\n //\n // Optionally prefix with a '?' if needed\n //\n if ('string' !== typeof prefix) prefix = '?';\n\n for (key in obj) {\n if (has.call(obj, key)) {\n value = obj[key];\n\n //\n // Edge cases where we actually want to encode the value to an empty\n // string instead of the stringified value.\n //\n if (!value && (value === null || value === undef || isNaN(value))) {\n value = '';\n }\n\n key = encode(key);\n value = encode(value);\n\n //\n // If we failed to encode the strings, we should bail out as we don't\n // want to add invalid strings to the query.\n //\n if (key === null || value === null) continue;\n pairs.push(key +'='+ value);\n }\n }\n\n return pairs.length ? prefix + pairs.join('&') : '';\n}\n\n//\n// Expose the module.\n//\nexports.stringify = querystringify;\nexports.parse = querystring;\n","export default function(e,n){return n=n||{},new Promise(function(t,r){var s=new XMLHttpRequest,o=[],u=[],i={},a=function(){return{ok:2==(s.status/100|0),statusText:s.statusText,status:s.status,url:s.responseURL,text:function(){return Promise.resolve(s.responseText)},json:function(){return Promise.resolve(s.responseText).then(JSON.parse)},blob:function(){return Promise.resolve(new Blob([s.response]))},clone:a,headers:{keys:function(){return o},entries:function(){return u},get:function(e){return i[e.toLowerCase()]},has:function(e){return e.toLowerCase()in i}}}};for(var l in s.open(n.method||\"get\",e,!0),s.onload=function(){s.getAllResponseHeaders().replace(/^(.*?):[^\\S\\n]*([\\s\\S]*?)$/gm,function(e,n,t){o.push(n=n.toLowerCase()),u.push([n,t]),i[n]=i[n]?i[n]+\",\"+t:t}),t(a())},s.onerror=r,s.withCredentials=\"include\"==n.credentials,n.headers)s.setRequestHeader(l,n.headers[l]);s.send(n.body||null)})}\n//# sourceMappingURL=unfetch.module.js.map\n","module.exports = self.fetch || (self.fetch = require('unfetch').default || require('unfetch'));\n","import fetch from 'isomorphic-unfetch';\r\n\r\ntype Config = {\r\n url: string,\r\n sessionKey?: string,\r\n debug?: boolean,\r\n}\r\n\r\nexport type Success = {\r\n success: string,\r\n}\r\n\r\n/**\r\n * @param [offset] Return results starting from this index position\r\n * @param [limit] Maximum number of results to return\r\n */\r\nexport type Pagination = {\r\n offset?: number,\r\n limit?: number,\r\n}\r\n\r\nexport type BinaryBoolean = 0 | 1;\r\n\r\nexport type UID = string | number;\r\n\r\nexport abstract class Base {\r\n sessionKey: string;\r\n url: string;\r\n version: string = '6.0.0';// default to latest version\r\n debug: boolean;\r\n\r\n constructor(config: Config) {\r\n this.sessionKey = config.sessionKey || null;\r\n this.url = config.url;\r\n this.debug = config.debug || false;\r\n }\r\n\r\n protected request<T> (endpoint: string, includeAuth: boolean = true): Promise<T> {\r\n let url = this.url + \"/server/json.server.php?action=\" + endpoint;\r\n\r\n // some endpoints like ping() or goodbye() can pass their own auth\r\n if (includeAuth) {\r\n url += \"&auth=\" + this.sessionKey + \"&version=\" + this.version;\r\n }\r\n\r\n if (this.debug) {\r\n console.debug(\r\n \"javascript-ampache query URL %c\" + url,\r\n \"color: black; font-style: italic; background-color: orange;padding: 2px\"\r\n );\r\n }\r\n\r\n return fetch(url).then(r => {\r\n if (r.ok) {\r\n return r.json();\r\n }\r\n throw new Error(r.statusText);\r\n })\r\n }\r\n\r\n protected binary<T> (endpoint: string, includeAuth: boolean = true): Promise<Blob> {\r\n let url = this.url + \"/server/json.server.php?action=\" + endpoint;\r\n\r\n if (includeAuth) {\r\n url += \"&auth=\" + this.sessionKey + \"&version=\" + this.version;\r\n }\r\n\r\n if (this.debug) {\r\n console.debug(\r\n \"javascript-ampache query URL %c\" + url,\r\n \"color: black; font-style: italic; background-color: orange;padding: 2px\"\r\n );\r\n }\r\n\r\n return fetch(url)\r\n .then(response => response.blob())\r\n .then(r => {\r\n return r;\r\n })\r\n }\r\n\r\n public setSessionKey(sessionKey: string) {\r\n this.sessionKey = sessionKey;\r\n }\r\n}","/**\n * A JavaScript implementation of the SHA family of hashes - defined in FIPS PUB 180-4, FIPS PUB 202,\n * and SP 800-185 - as well as the corresponding HMAC implementation as defined in FIPS PUB 198-1.\n *\n * Copyright 2008-2023 Brian Turek, 1998-2009 Paul Johnston & Contributors\n * Distributed under the BSD License\n * See http://caligatio.github.com/jsSHA/ for more information\n */\nconst t=\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\",r=\"ARRAYBUFFER not supported by this environment\",n=\"UINT8ARRAY not supported by this environment\";function i(t,r,n,i){let e,s,o;const h=r||[0],u=(n=n||0)>>>3,f=-1===i?3:0;for(e=0;e<t.length;e+=1)o=e+u,s=o>>>2,h.length<=s&&h.push(0),h[s]|=t[e]<<8*(f+i*(o%4));return{value:h,binLen:8*t.length+n}}function e(e,s,o){switch(s){case\"UTF8\":case\"UTF16BE\":case\"UTF16LE\":break;default:throw new Error(\"encoding must be UTF8, UTF16BE, or UTF16LE\")}switch(e){case\"HEX\":return function(t,r,n){return function(t,r,n,i){let e,s,o,h;if(0!=t.length%2)throw new Error(\"String of HEX type must be in byte increments\");const u=r||[0],f=(n=n||0)>>>3,c=-1===i?3:0;for(e=0;e<t.length;e+=2){if(s=parseInt(t.substr(e,2),16),isNaN(s))throw new Error(\"String of HEX type contains invalid characters\");for(h=(e>>>1)+f,o=h>>>2;u.length<=o;)u.push(0);u[o]|=s<<8*(c+i*(h%4))}return{value:u,binLen:4*t.length+n}}(t,r,n,o)};case\"TEXT\":return function(t,r,n){return function(t,r,n,i,e){let s,o,h,u,f,c,a,w,E=0;const l=n||[0],A=(i=i||0)>>>3;if(\"UTF8\"===r)for(a=-1===e?3:0,h=0;h<t.length;h+=1)for(s=t.charCodeAt(h),o=[],128>s?o.push(s):2048>s?(o.push(192|s>>>6),o.push(128|63&s)):55296>s||57344<=s?o.push(224|s>>>12,128|s>>>6&63,128|63&s):(h+=1,s=65536+((1023&s)<<10|1023&t.charCodeAt(h)),o.push(240|s>>>18,128|s>>>12&63,128|s>>>6&63,128|63&s)),u=0;u<o.length;u+=1){for(c=E+A,f=c>>>2;l.length<=f;)l.push(0);l[f]|=o[u]<<8*(a+e*(c%4)),E+=1}else for(a=-1===e?2:0,w=\"UTF16LE\"===r&&1!==e||\"UTF16LE\"!==r&&1===e,h=0;h<t.length;h+=1){for(s=t.charCodeAt(h),!0===w&&(u=255&s,s=u<<8|s>>>8),c=E+A,f=c>>>2;l.length<=f;)l.push(0);l[f]|=s<<8*(a+e*(c%4)),E+=2}return{value:l,binLen:8*E+i}}(t,s,r,n,o)};case\"B64\":return function(r,n,i){return function(r,n,i,e){let s,o,h,u,f,c,a,w=0;const E=n||[0],l=(i=i||0)>>>3,A=-1===e?3:0,p=r.indexOf(\"=\");if(-1===r.search(/^[a-zA-Z0-9=+/]+$/))throw new Error(\"Invalid character in base-64 string\");if(r=r.replace(/=/g,\"\"),-1!==p&&p<r.length)throw new Error(\"Invalid '=' found in base-64 string\");for(o=0;o<r.length;o+=4){for(f=r.substr(o,4),u=0,h=0;h<f.length;h+=1)s=t.indexOf(f.charAt(h)),u|=s<<18-6*h;for(h=0;h<f.length-1;h+=1){for(a=w+l,c=a>>>2;E.length<=c;)E.push(0);E[c]|=(u>>>16-8*h&255)<<8*(A+e*(a%4)),w+=1}}return{value:E,binLen:8*w+i}}(r,n,i,o)};case\"BYTES\":return function(t,r,n){return function(t,r,n,i){let e,s,o,h;const u=r||[0],f=(n=n||0)>>>3,c=-1===i?3:0;for(s=0;s<t.length;s+=1)e=t.charCodeAt(s),h=s+f,o=h>>>2,u.length<=o&&u.push(0),u[o]|=e<<8*(c+i*(h%4));return{value:u,binLen:8*t.length+n}}(t,r,n,o)};case\"ARRAYBUFFER\":try{new ArrayBuffer(0)}catch(t){throw new Error(r)}return function(t,r,n){return function(t,r,n,e){return i(new Uint8Array(t),r,n,e)}(t,r,n,o)};case\"UINT8ARRAY\":try{new Uint8Array(0)}catch(t){throw new Error(n)}return function(t,r,n){return i(t,r,n,o)};default:throw new Error(\"format must be HEX, TEXT, B64, BYTES, ARRAYBUFFER, or UINT8ARRAY\")}}function s(i,e,s,o){switch(i){case\"HEX\":return function(t){return function(t,r,n,i){const e=\"0123456789abcdef\";let s,o,h=\"\";const u=r/8,f=-1===n?3:0;for(s=0;s<u;s+=1)o=t[s>>>2]>>>8*(f+n*(s%4)),h+=e.charAt(o>>>4&15)+e.charAt(15&o);return i.outputUpper?h.toUpperCase():h}(t,e,s,o)};case\"B64\":return function(r){return function(r,n,i,e){let s,o,h,u,f,c=\"\";const a=n/8,w=-1===i?3:0;for(s=0;s<a;s+=3)for(u=s+1<a?r[s+1>>>2]:0,f=s+2<a?r[s+2>>>2]:0,h=(r[s>>>2]>>>8*(w+i*(s%4))&255)<<16|(u>>>8*(w+i*((s+1)%4))&255)<<8|f>>>8*(w+i*((s+2)%4))&255,o=0;o<4;o+=1)c+=8*s+6*o<=n?t.charAt(h>>>6*(3-o)&63):e.b64Pad;return c}(r,e,s,o)};case\"BYTES\":return function(t){return function(t,r,n){let i,e,s=\"\";const o=r/8,h=-1===n?3:0;for(i=0;i<o;i+=1)e=t[i>>>2]>>>8*(h+n*(i%4))&255,s+=String.fromCharCode(e);return s}(t,e,s)};case\"ARRAYBUFFER\":try{new ArrayBuffer(0)}catch(t){throw new Error(r)}return function(t){return function(t,r,n){let i;const e=r/8,s=new ArrayBuffer(e),o=new Uint8Array(s),h=-1===n?3:0;for(i=0;i<e;i+=1)o[i]=t[i>>>2]>>>8*(h+n*(i%4))&255;return s}(t,e,s)};case\"UINT8ARRAY\":try{new Uint8Array(0)}catch(t){throw new Error(n)}return function(t){return function(t,r,n){let i;const e=r/8,s=-1===n?3:0,o=new Uint8Array(e);for(i=0;i<e;i+=1)o[i]=t[i>>>2]>>>8*(s+n*(i%4))&255;return o}(t,e,s)};default:throw new Error(\"format must be HEX, B64, BYTES, ARRAYBUFFER, or UINT8ARRAY\")}}const o=[1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298],h=[3238371032,914150663,812702999,4144912697,4290775857,1750603025,1694076839,3204075428],u=[1779033703,3144134277,1013904242,2773480762,1359893119,2600822924,528734635,1541459225];function f(t){const r={outputUpper:!1,b64Pad:\"=\",outputLen:-1},n=t||{},i=\"Output length must be a multiple of 8\";if(r.outputUpper=n.outputUpper||!1,n.b64Pad&&(r.b64Pad=n.b64Pad),n.outputLen){if(n.outputLen%8!=0)throw new Error(i);r.outputLen=n.outputLen}else if(n.shakeLen){if(n.shakeLen%8!=0)throw new Error(i);r.outputLen=n.shakeLen}if(\"boolean\"!=typeof r.outputUpper)throw new Error(\"Invalid outputUpper formatting option\");if(\"string\"!=typeof r.b64Pad)throw new Error(\"Invalid b64Pad formatting option\");return r}class c{constructor(t,r,n){const i=n||{};if(this.t=r,this.i=i.encoding||\"UTF8\",this.numRounds=i.numRounds||1,isNaN(this.numRounds)||this.numRounds!==parseInt(this.numRounds,10)||1>this.numRounds)throw new Error(\"numRounds must a integer >= 1\");this.o=t,this.h=[],this.u=0,this.l=!1,this.A=0,this.p=!1,this.U=[],this.R=[]}update(t){let r,n=0;const i=this.T>>>5,e=this.F(t,this.h,this.u),s=e.binLen,o=e.value,h=s>>>5;for(r=0;r<h;r+=i)n+this.T<=s&&(this.m=this.g(o.slice(r,r+i),this.m),n+=this.T);return this.A+=n,this.h=o.slice(n>>>5),this.u=s%this.T,this.l=!0,this}getHash(t,r){let n,i,e=this.H;const o=f(r);if(this.B){if(-1===o.outputLen)throw new Error(\"Output length must be specified in options\");e=o.outputLen}const h=s(t,e,this.v,o);if(this.p&&this.C)return h(this.C(o));for(i=this.Y(this.h.slice(),this.u,this.A,this.S(this.m),e),n=1;n<this.numRounds;n+=1)this.B&&e%32!=0&&(i[i.length-1]&=16777215>>>24-e%32),i=this.Y(i,e,0,this.I(this.o),e);return h(i)}setHMACKey(t,r,n){if(!this.L)throw new Error(\"Variant does not support HMAC\");if(this.l)throw new Error(\"Cannot set MAC key after calling update\");const i=e(r,(n||{}).encoding||\"UTF8\",this.v);this.M(i(t))}M(t){const r=this.T>>>3,n=r/4-1;let i;if(1!==this.numRounds)throw new Error(\"Cannot set numRounds with MAC\");if(this.p)throw new Error(\"MAC key already set\");for(r<t.binLen/8&&(t.value=this.Y(t.value,t.binLen,0,this.I(this.o),this.H));t.value.length<=n;)t.value.push(0);for(i=0;i<=n;i+=1)this.U[i]=909522486^t.value[i],this.R[i]=1549556828^t.value[i];this.m=this.g(this.U,this.m),this.A=this.T,this.p=!0}getHMAC(t,r){const n=f(r);return s(t,this.H,this.v,n)(this.N())}N(){let t;if(!this.p)throw new Error(\"Cannot call getHMAC without first setting MAC key\");const r=this.Y(this.h.slice(),this.u,this.A,this.S(this.m),this.H);return t=this.g(this.R,this.I(this.o)),t=this.Y(r,this.H,this.T,t,this.H),t}}function a(t,r){return t>>>r|t<<32-r}function w(t,r){return t>>>r}function E(t,r,n){return t&r^~t&n}function l(t,r,n){return t&r^t&n^r&n}function A(t){return a(t,2)^a(t,13)^a(t,22)}function p(t,r){const n=(65535&t)+(65535&r);return(65535&(t>>>16)+(r>>>16)+(n>>>16))<<16|65535&n}function U(t,r,n,i){const e=(65535&t)+(65535&r)+(65535&n)+(65535&i);return(65535&(t>>>16)+(r>>>16)+(n>>>16)+(i>>>16)+(e>>>16))<<16|65535&e}function d(t,r,n,i,e){const s=(65535&t)+(65535&r)+(65535&n)+(65535&i)+(65535&e);return(65535&(t>>>16)+(r>>>16)+(n>>>16)+(i>>>16)+(e>>>16)+(s>>>16))<<16|65535&s}function R(t){return a(t,7)^a(t,18)^w(t,3)}function y(t){return a(t,6)^a(t,11)^a(t,25)}function T(t){let r;return r=\"SHA-224\"==t?h.slice():u.slice(),r}function F(t,r){let n,i,e,s,h,u,f,c,T,F,b;const m=[];for(n=r[0],i=r[1],e=r[2],s=r[3],h=r[4],u=r[5],f=r[6],c=r[7],b=0;b<64;b+=1)m[b]=b<16?t[b]:U(a(g=m[b-2],17)^a(g,19)^w(g,10),m[b-7],R(m[b-15]),m[b-16]),T=d(c,y(h),E(h,u,f),o[b],m[b]),F=p(A(n),l(n,i,e)),c=f,f=u,u=h,h=p(s,T),s=e,e=i,i=n,n=p(T,F);var g;return r[0]=p(n,r[0]),r[1]=p(i,r[1]),r[2]=p(e,r[2]),r[3]=p(s,r[3]),r[4]=p(h,r[4]),r[5]=p(u,r[5]),r[6]=p(f,r[6]),r[7]=p(c,r[7]),r}class b extends c{constructor(t,r,n){if(\"SHA-224\"!==t&&\"SHA-256\"!==t)throw new Error(\"Chosen SHA variant is not supported\");super(t,r,n);const i=n||{};this.C=this.N,this.L=!0,this.v=-1,this.F=e(this.t,this.i,this.v),this.g=F,this.S=function(t){return t.slice()},this.I=T,this.Y=function(r,n,i,e){return function(t,r,n,i,e){let s,o;const h=15+(r+65>>>9<<4),u=r+n;for(;t.length<=h;)t.push(0);for(t[r>>>5]|=128<<24-r%32,t[h]=4294967295&u,t[h-1]=u/4294967296|0,s=0;s<t.length;s+=16)i=F(t.slice(s,s+16),i);return o=\"SHA-224\"===e?[i[0],i[1],i[2],i[3],i[4],i[5],i[6]]:i,o}(r,n,i,e,t)},this.m=T(t),this.T=512,this.H=\"SHA-224\"===t?224:256,this.B=!1,i.hmacKey&&this.M(function(t,r,n,i){const s=t+\" must include a value and format\";if(!r){if(!i)throw new Error(s);return i}if(void 0===r.value||!r.format)throw new Error(s);return e(r.format,r.encoding||\"UTF8\",n)(r.value)}(\"hmacKey\",i.hmacKey,this.v))}}export{b as default};\n","import { Albums } from './albums';\r\nimport { Artists } from './artists';\r\nimport { Auth } from './auth';\r\nimport { Bookmarks } from './bookmarks';\r\nimport { Catalogs } from './catalogs';\r\nimport { Genres } from './genres';\r\nimport { Labels } from './labels';\r\nimport { Licenses } from './licenses';\r\nimport { LiveStreams } from './live-streams';\r\nimport { Playlists } from './playlists';\r\nimport { Podcasts } from './podcasts';\r\nimport { Preferences } from './preferences';\r\nimport { Shares } from './shares';\r\nimport { Shouts } from './shouts';\r\nimport { Songs } from './songs';\r\nimport { System } from './system';\r\nimport { Users } from './users';\r\nimport { Videos } from './videos';\r\nimport { applyMixins } from './utils';\r\nimport { Base } from './base';\r\n\r\nclass AmpacheAPI extends Base {}\r\ninterface AmpacheAPI extends Albums, Artists, Auth, Bookmarks, Catalogs, Genres, Labels, Licenses, LiveStreams, Playlists, Podcasts, Preferences, Shares, Shouts, Songs, System, Users, Videos {}\r\napplyMixins(AmpacheAPI, [Albums, Artists, Auth, Bookmarks, Catalogs, Genres, Labels, Licenses, LiveStreams, Playlists, Podcasts, Preferences, Shares, Shouts, Songs, System, Users, Videos]);\r\n\r\nexport default AmpacheAPI\r\n","import JsSHA from \"jssha/dist/sha256\";\r\n\r\nexport function applyMixins(derivedCtor: any, baseCtors: any[]) {\r\n baseCtors.forEach(baseCtor => {\r\n Object.getOwnPropertyNames(baseCtor.prototype).forEach(name => {\r\n Object.defineProperty(\r\n derivedCtor.prototype,\r\n name,\r\n Object.getOwnPropertyDescriptor(baseCtor.prototype, name)\r\n );\r\n });\r\n });\r\n}\r\n\r\nexport function encryptPassword(password: string, time: number) {\r\n let key = getSHA256(password);\r\n return getSHA256(time + key);\r\n\r\n function getSHA256(text) {\r\n let shaObj = new JsSHA(\"SHA-256\", \"TEXT\", { encoding: \"UTF8\" });\r\n shaObj.update(text);\r\n\r\n return shaObj.getHash(\"HEX\");\r\n }\r\n}\r\n","import qs from 'querystringify';\r\nimport { Album } from './types';\r\nimport { Base, BinaryBoolean, Pagination, UID } from '../base';\r\n\r\nexport class Albums extends Base {\r\n /**\r\n * This returns albums based on the provided search filters\r\n * @remarks MINIMUM_API_VERSION=380001\r\n * @param [params.filter] UID to find\r\n * @param [params.exact] 0, 1 (if true filter is exact = rather than fuzzy LIKE)\r\n * @param [params.add] ISO 8601 Date Format (2020-09-16) Find objects with an 'add' date newer than the specified date\r\n * @param [params.update] ISO 8601 Date Format (2020-09-16) Find objects with an 'update' time newer than the specified date\r\n * @param [params.include] albums, songs (include child objects in the response)\r\n * @param [params.offset]\r\n * @param [params.limit]\r\n * @see {@link https://ampache.org/api/api-json-methods#albums}\r\n */\r\n async albums (params?: {\r\n filter?: number,\r\n exact?: BinaryBoolean,\r\n add?: Date,\r\n update?: Date,\r\n include?: \"albums\" | \"songs\",\r\n } & Pagination) {\r\n let query = 'albums';\r\n query += qs.stringify(params, '&');\r\n let data = await this.request<{album: Album[]}>(query);\r\n return (data.album) ? data.album : data;\r\n }\r\n\r\n /**\r\n * This returns a single album based on the UID provided\r\n * @remarks MINIMUM_API_VERSION=380001\r\n * @param params.filter UID to find\r\n * @param [params.include] songs (include child objects in the response)\r\n * @see {@link https://ampache.org/api/api-json-methods#album}\r\n */\r\n album (params: {\r\n filter: UID,\r\n include?: 'songs'\r\n }) {\r\n let query = 'album';\r\n query += qs.stringify(params, '&');\r\n return this.request<Album>(query);\r\n }\r\n\r\n /**\r\n * This returns the albums of an artist\r\n * @remarks MINIMUM_API_VERSION=380001\r\n * @param params.filter UID to find\r\n * @param [params.offset]\r\n * @param [params.limit]\r\n * @see {@link https://ampache.org/api/api-json-methods#artist_albums}\r\n */\r\n async artistAlbums (params: {\r\n filter: UID\r\n } & Pagination) {\r\n let query = 'artist_albums';\r\n query += qs.stringify(params, '&');\r\n let data = await this.request<{album: Album[]}>(query);\r\n return (data.album) ? data.album : data;\r\n }\r\n\r\n /**\r\n * This returns the albums associated with the genre in question\r\n * @remarks MINIMUM_API_VERSION=380001\r\n * @param params.filter UID to find\r\n * @param [params.offset]\r\n * @param [params.limit]\r\n * @see {@link https://ampache.org/api/api-json-methods#genre_albums}\r\n */\r\n async genreAlbums (params?: {\r\n filter: UID\r\n } & Pagination) {\r\n let query = 'genre_albums';\r\n query += qs.stringify(params, '&');\r\n let data = await this.request<{album: Album[]}>(query);\r\n return (data.album) ? data.album : data;\r\n }\r\n}\r\n","import qs from 'querystringify';\r\nimport { Artist } from './types';\r\nimport { Base, BinaryBoolean, Pagination, UID } from '../base';\r\n\r\nexport class Artists extends Base {\r\n /**\r\n * This takes a collection of inputs and returns artist objects\r\n * @remarks MINIMUM_API_VERSION=380001\r\n * @param [params.filter] Filter results to match this string\r\n * @param [params.exact] 0, 1 (if true filter is exact = rather than fuzzy LIKE)\r\n * @param [params.add] ISO 8601 Date Format (2020-09-16) Find objects with an 'add' date newer than the specified date\r\n * @param [params.update] ISO 8601 Date Format (2020-09-16) Find objects with an 'update' time newer than the specified date\r\n * @param [params.include] (albums | songs) include child objects in the response\r\n * @param [params.album_artist] 0, 1 (if true filter for album artists only)\r\n * @param [params.offset]\r\n * @param [params.limit]\r\n * @see {@link https://ampache.org/api/api-json-methods#artists}\r\n */\r\n async artists (params?: {\r\n filter?: string,\r\n exact?: BinaryBoolean,\r\n add?: Date,\r\n update?: Date,\r\n include?: 'albums' | 'songs',\r\n album_artist?: BinaryBoolean,\r\n } & Pagination) {\r\n let query = 'artists';\r\n query += qs.stringify(params, '&');\r\n let data = await this.request<{artist: Artist[]}>(query);\r\n return (data.artist) ? data.artist : data;\r\n }\r\n\r\n /**\r\n * This returns a single artist based on the UID of said artist\r\n * @remarks MINIMUM_API_VERSION=380001\r\n * @param params.filter UID to find\r\n * @param [params.include] (albums | songs) include child objects in the response\r\n * @see {@link https://ampache.org/api/api-json-methods#artist}\r\n */\r\n artist (params: {\r\n filter: UID,\r\n include?: 'albums' | 'songs',\r\n }) {\r\n let query = 'artist';\r\n query += qs.stringify(params, '&');\r\n return this.request<Artist>(query);\r\n }\r\n\r\n /**\r\n * This returns the artists associated with the genre in question as defined by the UID\r\n * @remarks MINIMUM_API_VERSION=380001\r\n * @param params.filter UID to find\r\n * @param [params.offset]\r\n * @param [params.limit]\r\n * @see {@link https://ampache.org/api/api-json-methods#genre_artists}\r\n */\r\n async genreArtists (params: {\r\n filter: UID\r\n } & Pagination) {\r\n let query = 'genre_artists';\r\n query += qs.stringify(params, '&');\r\n let data = await this.request<{artist: Artist[]}>(query);\r\n return (data.artist) ? data.artist : data;\r\n }\r\n\r\n /**\r\n * This returns the artists associated with the label in question as defined by the UID\r\n * @remarks MINIMUM_API_VERSION=420000\r\n * @param params.filter UID of find\r\n * @param [params.offset]\r\n * @param [params.limit]\r\n * @see {@link https://ampache.org/api/api-json-methods#label_artists}\r\n */\r\n async labelArtists (params: {\r\n filter: UID\r\n } & Pagination) {\r\n let query = 'label_artists';\r\n query += qs.stringify(params, '&');\r\n let data = await this.request<{artist: Artist[]}>(query);\r\n return (data.artist) ? data.artist : data;\r\n }\r\n}","import JsSHA from \"jssha/dist/sha256\";\r\nimport qs from 'querystringify';\r\nimport fetch from \"isomorphic-unfetch\";\r\nimport { Base, Success } from \"../base\";\r\nimport { AuthResponse } from './types'\r\n\r\nexport class Auth extends Base {\r\n /**\r\n * Handles verifying a new handshake\r\n * @remarks MINIMUM_API_VERSION=380001\r\n * @param params.auth encrypted apikey OR password if using password auth\r\n * @param [params.user] username\r\n * @param [params.timestamp] UNIXTIME()\r\n * @param [params.version] version of Ampache API to establish connection with\r\n * @see {@link https://ampache.org/api/api-json-methods#handshake}\r\n */\r\n handshake (params: {\r\n auth: string,\r\n user?: string,\r\n timestamp?: number,\r\n version?: string\r\n }) {\r\n // generate a timestamp if one wasn't provided\r\n if (!params.timestamp) {\r\n params.timestamp = Math.floor(new Date().getTime() / 1000);\r\n }\r\n\r\n // override the fallback API version with specified\r\n if (params.version) {\r\n this.version = params.version;\r\n }\r\n\r\n // drop timestamp if no user provided (i.e. logging in with API key)\r\n if (!params.user) {\r\n delete params.timestamp;\r\n }\r\n\r\n let query = this.url + \"/server/json.server.php?action=handshake\";\r\n query += qs.stringify(params, '&');\r\n\r\n return fetch(query)\r\n .then(response => response.json())\r\n .then(data => {\r\n if (data.auth) {\r\n this.sessionKey = data.auth;\r\n }\r\n return <AuthResponse>data;\r\n })\r\n }\r\n\r\n /**\r\n * This can be called without being authenticated, it is useful for determining if what the status\r\n * of the server is, and what version it is running/compatible with\r\n * @remarks MINIMUM_API_VERSION=380001\r\n * @param [params.auth] (Session ID) returns version information and extends the session if passed\r\n * @param [params.version] API Version that the application understands\r\n * @see {@link https://ampache.org/api/api-json-methods#ping}\r\n */\r\n ping (params?: { auth?: string, version?: string }) {\r\n let query = 'ping';\r\n query += qs.stringify(params, '&');\r\n return this.request<AuthResponse>(query, false);\r\n }\r\n\r\n /**\r\n * Destroy a session using the session auth parameter\r\n * @remarks MINIMUM_API_VERSION=400001\r\n * @param params.auth Session ID to destroy\r\n * @see {@link https://ampache.org/api/api-json-methods#goodbye}\r\n */\r\n goodbye (params: { auth }) {\r\n let query = 'goodbye';\r\n query += qs.stringify(params, '&');\r\n return this.request<Success>(query, false);\r\n }\r\n\r\n /**\r\n * Encrypt your password into the accepted format.\r\n */\r\n encryptPassword (params: { password: string, time: number }) {\r\n let key = getSHA256(params.password);\r\n return getSHA256(params.time + key);\r\n\r\n function getSHA256(text) {\r\n let shaObj = new JsSHA(\"SHA-256\", \"TEXT\", { encoding: \"UTF8\" });\r\n shaObj.update(text);\r\n\r\n return shaObj.getHash(\"HEX\");\r\n }\r\n }\r\n}","import qs from 'querystringify';\r\nimport { Bookmark } from './types';\r\nimport { Base, Success, UID } from '../base';\r\n\r\nexport class Bookmarks extends Base {\r\n /**\r\n * Get information about bookmarked media this user is allowed to manage\r\n * @remarks MINIMUM_API_VERSION=5.0.0\r\n * @see {@link https://ampache.org/api/api-json-methods#bookmarks}\r\n */\r\n async bookmarks () {\r\n let query = 'bookmarks';\r\n let data = await this.request<{bookmark: Bookmark[]}>(query);\r\n return (data.bookmark) ? data.bookmark : data;\r\n }\r\n\r\n /**\r\n * Get the bookmark from it's object_id and object_type.\r\n * @remarks MINIMUM_API_VERSION=5.0.0\r\n * @param params.filter UID to find\r\n * @param params.type Object type\r\n * @see {@link https://ampache.org/api/api-json-methods#get_bookmark}\r\n */\r\n getBookmark (params: {\r\n filter: UID,\r\n type: 'song' | 'video' | 'podcast_episode',\r\n }) {\r\n let query = 'get_bookmark';\r\n query += qs.stringify(params, '&');\r\n return this.request<Bookmark>(query);\r\n }\r\n\r\n /**\r\n * Create a placeholder for the current media that you can return to later.\r\n * @remarks MINIMUM_API_VERSION=5.0.0\r\n * @param params.filter UID to find\r\n * @param params.type Object type\r\n * @param params.position current track time in seconds\r\n * @param [params.client] Agent string. (Default: 'AmpacheAPI')\r\n * @param [params.date] update time (Default: UNIXTIME())\r\n * @see {@link https://ampache.org/api/api-json-methods#bookmark_create}\r\n */\r\n bookmarkCreate (params: {\r\n filter: UID,\r\n type: 'song' | 'video' | 'podcast_episode',\r\n position: number,\r\n client?: string,\r\n date?: number,\r\n }) {\r\n let query = 'bookmark_create';\r\n query += qs.stringify(params, '&');\r\n return this.request<Bookmark>(query);\r\n }\r\n\r\n /**\r\n * Edit a placeholder for the current media that you can return to later.\r\n * @remarks MINIMUM_API_VERSION=5.0.0\r\n * @param params.filter UID to find\r\n * @param params.type Object type\r\n * @param params.position current track time in seconds\r\n * @param [params.client] Agent string. (Default: 'AmpacheAPI')\r\n * @param [params.date] update time (Default: UNIXTIME())\r\n * @see {@link https://ampache.org/api/api-json-methods#bookmark_edit}\r\n */\r\n bookmarkEdit (params: {\r\n filter: UID,\r\n type: 'song' | 'video' | 'podcast_episode',\r\n position: number,\r\n client?: string,\r\n date?: number,\r\n }) {\r\n let query = 'bookmark_edit';\r\n query += qs.stringify(params, '&');\r\n return this.request<Bookmark>(query);\r\n }\r\n\r\n /**\r\n * Delete an existing bookmark. (if it exists)\r\n * @remarks MINIMUM_API_VERSION=5.0.0\r\n * @param params.filter UID to find\r\n * @param params.type Object type\r\n * @param [params.client] Agent string. (Default: 'AmpacheAPI')\r\n @see {@link https://ampache.org/api/api-json-methods#bookmark_delete}\r\n */\r\n bookmarkDelete (params: {\r\n filter: UID,\r\n type: 'song' | 'video' | 'podcast_episode',\r\n client?: string,\r\n }) {\r\n let query = 'bookmark_delete';\r\n query += qs.stringify(params, '&');\r\n return this.request<Success>(query);\r\n }\r\n}","import qs from 'querystringify';\r\nimport { Catalog } from './types';\r\nimport { Base, Success, UID } from '../base';\r\n\r\nexport class Catalogs extends Base {\r\n /**\r\n * This searches the catalogs and returns... catalogs\r\n * @remarks MINIMUM_API_VERSION=420000\r\n * @param [params.filter] Catalog type\r\n * @see {@link https://ampache.org/api/api-json-methods#catalogs}\r\n */\r\n async catalogs (params?: {\r\n filter?: 'music' | 'clip' | 'tvshow' | 'movie' | 'personal_video' | 'podcast',\r\n }) {\r\n let query = 'catalogs';\r\n query += qs.stringify(params, '&');\r\n let data = await this.request<{catalog: Catalog[]}>(query);\r\n return (data.catalog) ? data.catalog : data;\r\n }\r\n\r\n /**\r\n * Return catalog by UID\r\n * @remarks MINIMUM_API_VERSION=420000\r\n * @param params.filter UID to find\r\n * @see {@link https://ampache.org/api/api-json-methods#catalog}\r\n */\r\n catalog (params: {\r\n filter: UID,\r\n }) {\r\n let query = 'catalog';\r\n query += qs.stringify(params, '&');\r\n return this.request<Catalog>(query);\r\n }\r\n\r\n /**\r\n * Kick off a catalog update or clean for the selected catalog\r\n * ACCESS REQUIRED: 75 (Catalog Manager)\r\n * @remarks MINIMUM_API_VERSION=400001\r\n * @param params.task add_to_catalog, clean_catalog\r\n * @param params.catalog UID of catalog\r\n * @see {@link https://ampache.org/api/api-json-methods#catalog_action}\r\n */\r\n catalogAction(params: {\r\n task: 'add_to_catalog' | 'clean_catalog',\r\n catalog: UID,\r\n }) {\r\n let query = 'catalog_action';\r\n query += qs.stringify(params, '&');\r\n return this.request<Success>(query);\r\n }\r\n\r\n /**\r\n * Perform actions on local catalog files. Single file versions of catalog add, clean, verify and remove (delete).\r\n * Make sure you remember to urlencode those file names!\r\n * ACCESS REQUIRED: 50 (Content Manager)\r\n * @remarks MINIMUM_API_VERSION=420000\r\n * @param params.file FULL path to local file\r\n * @param params.task add, clean, verify, remove, (can include comma-separated values)\r\n * @param params.catalog UID of catalog\r\n * @see {@link https://ampache.org/api/api-json-methods#catalog_file}\r\n */\r\n catalogFile(params: {\r\n file: string,\r\n task: string,\r\n catalog: UID,\r\n }) {\r\n let query = 'catalog_file';\r\n query += qs.stringify(params, '&');\r\n return this.request<Success>(query);\r\n }\r\n\r\n /**\r\n * Create a new catalog.\r\n * ACCESS REQUIRED: 75 (Catalog Manager)\r\n * @remarks MINIMUM_API_VERSION=6.0.0\r\n * @param params.name Name for the catalog\r\n * @param params.path URL or folder path for your catalog\r\n * @param [params.type] Default: 'local'\r\n * @param [params.media_type] Default: 'music'\r\n * @param [params.file_pattern] Pattern used identify tags from the file name. Default: '%T - %t'\r\n * @param [params.folder_pattern] Pattern used identify tags from the folder name. Default: '%a/%A'\r\n * @param [params.username] login to remote catalog\r\n * @param [params.password] password to remote catalog\r\n * @see {@link https://ampache.org/api/api-json-methods#catalog_add}\r\n */\r\n catalogAdd(params: {\r\n name: string,\r\n path: string,\r\n type?: 'local' | 'beets' | 'remote' | 'subsonic' | 'seafile' | 'beetsremote',\r\n media_type?: 'music' | 'podcast' | 'clip' | 'tvshow' | 'movie' | 'personal_video',\r\n file_pattern?: string,\r\n folder_pattern?: string,\r\n username?: string,\r\n password?: string,\r\n }) {\r\n let query = 'catalog_add';\r\n query += qs.stringify(params, '&');\r\n return this.request<Catalog>(query);\r\n }\r\n\r\n /**\r\n * Delete an existing catalog. (if it exists)\r\n * ACCESS REQUIRED: 75 (Catalog Manager)\r\n * @remarks MINIMUM_API_VERSION=6.0.0\r\n * @param params.filter ID of the catalog\r\n * @see {@link https://ampache.org/api/api-json-methods#catalog_delete}\r\n */\r\n catalogDelete(params: {\r\n filter: UID,\r\n }) {\r\n let query = 'catalog_delete';\r\n query += qs.stringify(params, '&');\r\n return this.request<Success>(query);\r\n }\r\n}","import qs from 'querystringify';\r\nimport { Genre } from './types';\r\nimport { Base, BinaryBoolean, Pagination, UID } from '../base';\r\n\r\nexport class Genres extends Base {\r\n /**\r\n * This returns the genres (Tags) based on the specified filter\r\n * @remarks MINIMUM_API_VERSION=380001\r\n * @param [params.filter] UID to find\r\n * @param [params.exact] 0, 1 (if true filter is exact = rather than fuzzy LIKE)\r\n * @param [params.offset]\r\n * @param [params.limit]\r\n * @see {@link https://ampache.org/api/api-json-methods#genres}\r\n */\r\n async genres (params?: {\r\n filter?: string,\r\n exact?: BinaryBoolean,\r\n } & Pagination) {\r\n let query = 'genres';\r\n query += qs.stringify(params, '&');\r\n let data = await this.request<{genre: Genre[]}>(query);\r\n return (data.genre) ? data.genre : data;\r\n }\r\n\r\n /**\r\n * This returns a single genre based on UID\r\n * @remarks MINIMUM_API_VERSION=380001\r\n * @param params.filter UID to find\r\n * @see {@link https://ampache.org/api/api-json-methods#genre}\r\n */\r\n async genre (params: {\r\n filter: UID,\r\n }) {\r\n let query = 'genre';\r\n query += qs.stringify(params, '&');\r\n let data = await this.request<{genre: Genre[]}>(query);\r\n return (data.genre) ? data.genre : data;\r\n }\r\n}","import qs from 'querystringify';\r\nimport { Label } from './types';\r\nimport { Base, BinaryBoolean, Pagination, UID } from '../base';\r\n\r\nexport class Labels extends Base {\r\n /**\r\n * This returns labels based on the specified filter\r\n * @remarks MINIMUM_API_VERSION=420000\r\n * @param [params.filter] Filter results to match this string\r\n * @param [params.exact] 0, 1 (if true filter is exact = rather than fuzzy LIKE)\r\n * @param [params.add] ISO 8601 Date Format (2020-09-16) Find objects with an 'add' date newer than the specified date\r\n * @param [params.update] ISO 8601 Date Format (2020-09-16) Find objects with an 'update' time newer than the specified date\r\n * @param [params.offset]\r\n * @param [params.limit]\r\n * @see {@link https://ampache.org/api/api-json-methods#labels}\r\n */\r\n async labels (params?: {\r\n filter?: string,\r\n exact?: BinaryBoolean,\r\n add?: Date,\r\n update?: Date,\r\n } & Pagination) {\r\n let query = 'labels';\r\n query += qs.stringify(params, '&');\r\n let data = await this.request<{label: Label[]}>(query);\r\n return (data.label) ? data.label : data;\r\n }\r\n\r\n /**\r\n * This returns a single label\r\n * @remarks MINIMUM_API_VERSION=420000\r\n * @param params.filter UID to find\r\n * @see {@link https://ampache.org/api/api-json-methods#label}\r\n */\r\n label (params: {\r\n filter: UID,\r\n }) {\r\n let query = 'label';\r\n query += qs.stringify(params, '&');\r\n return this.request<Label>(query);\r\n }\r\n}","import qs from 'querystringify';\r\nimport { License } from './types';\r\nimport { Base, BinaryBoolean, Pagination, UID } from '../base';\r\n\r\nexport class Licenses extends Base {\r\n /**\r\n * This returns licenses based on the specified filter\r\n * @remarks MINIMUM_API_VERSION=420000\r\n * @param [params.filter] Filter results to match this string\r\n * @param [params.exact] 0, 1 (if true filter is exact = rather than fuzzy LIKE)\r\n * @param [params.add] ISO 8601 Date Format (2020-09-16) Find objects with an 'add' date newer than the specified date\r\n * @param [params.update] ISO 8601 Date Format (2020-09-16) Find objects with an 'update' time newer than the specified date\r\n * @param [params.offset]\r\n * @param [params.limit]\r\n * @see {@link https://ampache.org/api/api-json-methods#licenses}\r\n */\r\n async licenses (params?: {\r\n filter?: string,\r\n exact?: BinaryBoolean,\r\n add?: Date,\r\n update?: Date,\r\n } & Pagination) {\r\n let query = 'licenses';\r\n query += qs.stringify(params, '&');\r\n let data = await this.request<{license: License[]}>(query);\r\n return (data.license) ? data.license : data;\r\n }\r\n\r\n /**\r\n * This returns a single license\r\n * @remarks MINIMUM_API_VERSION=420000\r\n * @param params.filter UID to find\r\n * @see {@link https://ampache.org/api/api-json-methods#license}\r\n */\r\n license (params: {\r\n filter: UID,\r\n }) {\r\n let query = 'license';\r\n query += qs.stringify(params, '&');\r\n return this.request<License>(query);\r\n }\r\n}","import qs from 'querystringify';\r\nimport { LiveStream } from './types';\r\nimport { Base, BinaryBoolean, Pagination, Success, UID } from '../base';\r\n\r\nexport class LiveStreams extends Base {\r\n /**\r\n * This returns live_streams based on the specified filter\r\n * @remarks MINIMUM_API_VERSION=5.1.0\r\n * @param [params.filter] Filter results to match this string\r\n * @param [params.exact] 0, 1 (if true filter is exact = rather than fuzzy LIKE)\r\n * @param [params.add] ISO 8601 Date Format (2020-09-16) Find objects with an 'add' date newer than the specified date\r\n * @param [params.update] ISO 8601 Date Format (2020-09-16) Find objects with an 'update' time newer than the specified date\r\n * @param [params.offset]\r\n * @param [params.limit]\r\n * @see {@link https://ampache.org/api/api-json-methods#live_streams}\r\n */\r\n async liveStreams (params?: {\r\n filter?: string,\r\n exact?: BinaryBoolean,\r\n add?: Date,\r\n update?: Date,\r\n } & Pagination) {\r\n let query = 'live_streams';\r\n query += qs.stringify(params, '&');\r\n let data = await this.request<{live_stream: LiveStream[]}>(query);\r\n return (data.live_stream) ? data.live_stream : data;\r\n }\r\n\r\n /**\r\n * This returns a single live_stream\r\n * @remarks MINIMUM_API_VERSION=5.1.0\r\n * @param params.filter UID to find\r\n * @see {@link https://ampache.org/api/api-json-methods#live_stream}\r\n */\r\n liveStream (params: {\r\n filter: UID,\r\n }) {\r\n let query = 'live_stream';\r\n query += qs.stringify(params, '&');\r\n return this.request<LiveStream>(query);\r\n }\r\n\r\n /**\r\n * Create a live_stream (radio station) object.\r\n * ACCESS REQUIRED: 50 (Content Manager)\r\n * @remarks MINIMUM_API_VERSION=6.0.0\r\n * @param params.name Stream title\r\n * @param params.url URL of the http/s stream\r\n * @param params.codec Stream codec\r\n * @param params.catalog Catalog ID to associate with this stream\r\n * @param [params.site_url] Homepage URL of the stream\r\n * @see {@link https://ampache.org/api/api-json-methods#live_stream_create}\r\n */\r\n liveStreamCreate (params: {\r\n name: string,\r\n url: string,\r\n codec: 'mp3' | 'flac' | 'ogg' | 'vorbis' | 'opus' | 'aac' | 'alac',\r\n catalog: string,\r\n site_url?: string\r\n }) {\r\n let query = 'live_stream_create';\r\n query += qs.stringify(params, '&');\r\n return this.request<LiveStream>(query);\r\n }\r\n\r\n /**\r\n * Edit a live_stream (radio station) object.\r\n * ACCESS REQUIRED: 50 (Content Manager)\r\n * @remarks MINIMUM_API_VERSION=6.0.0\r\n * @param params.filter Object to find\r\n * @param [params.name] Stream title\r\n * @param [params.url] URL of the http/s stream\r\n * @param [params.codec] Stream codec\r\n * @param [params.catalog] Catalog ID to associate with this stream\r\n * @param [params.site_url] Homepage URL of the stream\r\n * @see {@link https://ampache.org/api/api-json-methods#live_stream_edit}\r\n */\r\n liveStreamEdit (params: {\r\n filter: string,\r\n name?: string,\r\n url?: string,\r\n codec?: 'mp3' | 'flac' | 'ogg' | 'vorbis' | 'opus' | 'aac' | 'alac',\r\n catalog?: string,\r\n site_url?: string\r\n }) {\r\n let query = 'live_stream_edit';\r\n query += qs.stringify(params, '&');\r\n return this.request<LiveStream>(query);\r\n }\r\n\r\n /**\r\n * Delete a live_stream (radio station) object (if it exists)\r\n * ACCESS REQUIRED: 50 (Content Manager)\r\n * @remarks MINIMUM_API_VERSION=6.0.0\r\n * @param params.filter Object to find\r\n * @see {@link https://ampache.org/api/api-json-methods#live_stream_delete}\r\n */\r\n liveStreamDelete (params: {\r\n filter: string,\r\n }) {\r\n let query = 'live_stream_delete';\r\n query += qs.stringify(params, '&');\r\n return this.request<Success>(query);\r\n }\r\n}","import qs from 'querystringify';\r\nimport { Playlist } from './types';\r\nimport { Song } from \"../songs/types\";\r\nimport { Base, BinaryBoolean, Pagination, Success, UID } from '../base';\r\n\r\nexport class Playlists extends Base {\r\n /**\r\n * This returns playlists based on the specified filter\r\n * @remarks MINIMUM_API_VERSION=380001\r\n * @param [params.filter] Filter results to match this string\r\n * @param [params.exact] 0, 1 (if true filter is exact = rather than fuzzy LIKE)\r\n * @param [params.add] ISO 8601 Date Format (2020-09-16) Find objects with an 'add' date newer than the specified date\r\n * @param [params.update] ISO 8601 Date Format (2020-09-16) Find objects with an 'update' time newer than the specified date\r\n * @param [params.hide_search] 0, 1 (if true do not include searches/smartlists in the result)\r\n * @param [params.show_dupes] 0, 1 (if true ignore 'api_hide_dupe_searches' setting)\r\n * @param [params.offset]\r\n * @param [params.limit]\r\n * @see {@link https://ampache.org/api/api-json-methods#playlists}\r\n */\r\n async playlists (params?: {\r\n filter?: string,\r\n exact?: BinaryBoolean,\r\n add?: Date,\r\n update?: Date,\r\n hide_search?: BinaryBoolean,\r\n show_dupes?: BinaryBoolean,\r\n } & Pagination) {\r\n let query = 'playlists';\r\n query += qs.stringify(params, '&');\r\n let data = await this.request<{playlist: Playlist[]}>(query);\r\n return (data.playlist) ? data.playlist : data;\r\n }\r\n\r\n /**\r\n * This returns smartlists based on the specified filter. NOTE: Filtered from Playlists() so pagination is invalid.\r\n * @remarks MINIMUM_API_VERSION=380001\r\n * @param [params.filter] Filter results to match this string\r\n * @param [params.exact] 0, 1 (if true filter is exact = rather than fuzzy LIKE)\r\n * @param [params.add] ISO 8601 Date Format (2020-09-16) Find objects with an 'add' date newer than the specified date\r\n * @param [params.update] ISO 8601 Date Format (2020-09-16) Find objects with an 'update' time newer than the specified date\r\n * @param [params.show_dupes] 0, 1 (if true ignore 'api_hide_dupe_searches' setting)\r\n * @see {@link https://ampache.org/api/api-json-methods#playlists}\r\n */\r\n async smartlists (params?: {\r\n filter?: string,\r\n exact?: BinaryBoolean,\r\n add?: Date,\r\n update?: Date,\r\n show_dupes?: BinaryBoolean,\r\n }) {\r\n let query = 'playlists';\r\n query += qs.stringify(params, '&');\r\n let data = await this.request<{playlist: Playlist[]}>(query);\r\n\r\n let results = (data.playlist) ? data.playlist : data;\r\n\r\n // filter out regular playlists\r\n if (Array.isArray(results)) {\r\n results = results.filter(function(item) {\r\n return item.id.toString().match(/^smart_/);\r\n })\r\n }\r\n\r\n return results;\r\n }\r\n\r\n /**\r\n * This returns a single playlist\r\n * @remarks MINIMUM_API_VERSION=380001\r\n * @param params.filter UID to find\r\n * @see {@link https://ampache.org/api/api-json-methods#playlist}\r\n */\r\n playlist (params: {\r\n filter: UID\r\n }) {\r\n let query = 'playlist';\r\n query += qs.stringify(params, '&');\r\n return this.request<Playlist>(query);\r\n }\r\n\r\n /**\r\n * This creates a new playlist and returns it\r\n * @remarks MINIMUM_API_VERSION=380001\r\n * @param params.name Playlist name\r\n * @param [params.type] public, private (Playlist type)\r\n * @see {@link https://ampache.org/api/api-json-methods#playlist_create}\r\n */\r\n playlistCreate (params: {\r\n name: string,\r\n type?: 'public' | 'private',\r\n }) {\r\n let query = 'playlist_create';\r\n query += qs.stringify(params, '&');\r\n return this.request<Playlist>(query);\r\n }\r\n\r\n /**\r\n * This modifies name and type of a playlist.\r\n * NOTE items and tracks must be sent together and be of equal length.\r\n * @remarks MINIMUM_API_VERSION=400001\r\n * @param params.filter UID to find\r\n * @param [params.name] Playlist name\r\n * @param [params.type] public, private (Playlist type)\r\n * @param [params.owner] Change playlist owner to the user id (-1 = System playlist)\r\n * @param [params.items] comma-separated song_id's (replaces existing items with a new id)\r\n * @param [params.tracks] comma-separated playlisttrack numbers matched to 'items' in order\r\n * @see {@link https://ampache.org/api/api-json-methods#playlist_edit}\r\n */\r\n playlistEdit (params: {\r\n filter: UID,\r\n name?: string,\r\n type?: 'public' | 'private',\r\n owner?: string,\r\n items?: string,\r\n tracks?: string,\r\n }) {\r\n let query = 'playlist_edit';\r\n query += qs.stringify(params, '&');\r\n return this.request<Success>(query);\r\n }\r\n\r\n /**\r\n * This deletes a playlist\r\n * @remarks MINIMUM_API_VERSION=380001\r\n * @param params.filter UID of playlist to delete\r\n * @see {@link https://ampache.org/api/api-json-methods#playlist_delete}\r\n */\r\n playlistDelete (params: {\r\n filter: UID,\r\n }) {\r\n let query = 'playlist_delete';\r\n query += qs.stringify(params, '&');\r\n return this.request<Success>(query);\r\n }\r\n\r\n /**\r\n * This adds a song to a playlist\r\n * @remarks MINIMUM_API_VERSION=380001; CHANGED_IN_API_VERSION=400003\r\n * @param params.filter UID of Playlist\r\n * @param params.song UID of song to add to playlist\r\n * @param [params.check] 0, 1 Whether to check and ignore duplicates (default = 0)\r\n * @see {@link https://ampache.org/api/api-json-methods#playlist_add_song}\r\n */\r\n playlistAddSong (params: {\r\n filter: UID,\r\n song: UID,\r\n check?: BinaryBoolean,\r\n }) {\r\n let query = 'playlist_add_song';\r\n query += qs.stringify(params, '&');\r\n return this.request<Success>(query);\r\n }\r\n\r\n /**\r\n * This remove a song from a playlist\r\n * @remarks MINIMUM_API_VERSION=380001; CHANGED_IN_API_VERSION=400001\r\n * @param params.filter UID of Playlist\r\n * @param [params.song] UID of song to remove from playlist\r\n * @param [params.track] Track number to remove from playlist\r\n * @see {@link https://ampache.org/api/api-json-methods#playlist_remove_song}\r\n */\r\n playlistRemoveSong (params: {\r\n filter: UID,\r\n song?: UID,\r\n track?: number,\r\n }) {\r\n let query = 'playlist_remove_song';\r\n query += qs.stringify(params, '&');\r\n return this.request<Success>(query);\r\n }\r\n\r\n /**\r\n * Get a list of song JSON, indexes or id's based on some simple search criteria\r\n * @remarks MINIMUM_API_VERSION=400001; CHANGED_IN_API_VERSION=400002; 'recent' will search for tracks played after 'Popular Threshold' days; 'forgotten' will search for tracks played before 'Popular Threshold' days; 'unplayed' added in 400002 for searching unplayed tracks\r\n * @param [params.mode] (default = 'random')\r\n * @param [params.filter] string LIKE matched to song title\r\n * @param [params.album] UID of album\r\n * @param [params.artist] UID of artist\r\n * @param [params.flag] 0, 1 (get flagged songs only. default = 0)\r\n * @param [params.format] song, index, id (default = 'song')\r\n * @param [params.offset]\r\n * @param [params.limit]\r\n * @see {@link https://ampache.org/api/api-json-methods#playlist_generate}\r\n */\r\n async playlistGenerate (params?: {\r\n mode?: 'recent' | 'forgotten' | 'unplayed' | 'random',\r\n filter?: string,\r\n album?: number,\r\n artist?: number,\r\n flag?: BinaryBoolean,\r\n format?: 'song' | 'index' | 'id',\r\n } & Pagination) {\r\n let query = 'playlist_generate';\r\n query += qs.stringify(params, '&');\r\n let data = await this.request<{song: Song[]}>(query);\r\n return (data.song) ? data.song : data;\r\n }\r\n}","import qs from 'querystringify';\r\nimport { Podcast, PodcastEpisode, DeletedPodcastEpisode } from './types';\r\nimport { Base, Pagination, Success, UID } from '../base';\r\n\r\nexport class Podcasts extends Base {\r\n /**\r\n * Get information about podcasts\r\n * @remarks MINIMUM_API_VERSION=420000\r\n * @param [params.filter] Value is Alpha Match for returned results, may be more than one letter/number\r\n * @param [params.include] episodes (include podcast_episodes in the response)\r\n * @param [params.offset]\r\n * @param [params.limit]\r\n * @see {@link https://ampache.org/api/api-json-methods#podcasts}\r\n */\r\n async podcasts (params?: {\r\n filter?: string,\r\n include?: 'episodes',\r\n } & Pagination) {\r\n let query = 'podcasts';\r\n query += qs.stringify(params, '&');\r\n let data = await this.request<{podcast: Podcast[]}>(query);\r\n return (data.podcast) ? data.podcast : data;\r\n }\r\n\r\n /**\r\n * Get information about podcasts\r\n * @remarks MINIMUM_API_VERSION=420000\r\n * @param params.filter UID to find\r\n * @param [params.include] episodes (include podcast_episodes in the response)\r\n * @param [params.offset]\r\n * @param [params.limit]\r\n * @see {@link https://ampache.org/api/api-json-methods#podcast}\r\n */\r\n async podcast (params?: {\r\n filter: UID,\r\n include?: 'episodes',\r\n } & Pagination) {\r\n let query = 'podcast';\r\n query += qs.stringify(params, '&');\r\n let data = await this.request<{podcast: Podcast[]}>(query);\r\n return (data.podcast) ? data.podcast : data;\r\n }\r\n\r\n /**\r\n * Create a podcast that can be used by anyone to stream media.\r\n * @remarks MINIMUM_API_VERSION=420000\r\n * @param params.url RSS url for podcast\r\n * @param params.catalog UID of podcast catalog\r\n * @see {@link https://ampache.org/api/api-json-methods#podcast_create}\r\n */\r\n podcastCreate (params: {\r\n url: string,\r\n catalog: UID,\r\n }) {\r\n let query = 'podcast_create';\r\n query += qs.stringify(params, '&');\r\n return this.request<Podcast>(query);\r\n }\r\n\r\n /**\r\n * Update the description and/or expiration date for an existing podcast.\r\n * @remarks MINIMUM_API_VERSION=420000\r\n * @param params.filter UID to find\r\n * @param [params.feed] RSS url for podcast\r\n * @param [params.title] Podcast title\r\n * @param [params.website] Source website URL\r\n * @param [params.description] Podcast description\r\n * @param [params.generator] Podcast generator\r\n * @param [params.copyright] Podcast copyright\r\n * @see {@link https://ampache.org/api/api-json-methods#podcast_edit}\r\n */\r\n podcastEdit (params: {\r\n filter: UID,\r\n feed?: string,\r\n title?: string,\r\n website?: string,\r\n description?: string,\r\n generator?: string,\r\n copyright?: string,\r\n }) {\r\n let query = 'podcast_edit';\r\n query += qs.stringify(params, '&');\r\n return this.request<Success>(query);\r\n }\r\n\r\n /**\r\n * Delete an existing podcast\r\n * @remarks MINIMUM_API_VERSION=420000\r\n * @param params.filter UID of podcast to delete\r\n * @see {@link https://ampache.org/api/api-json-methods#podcast_delete}\r\n */\r\n podcastDelete (params: {\r\n filter: UID\r\n }) {\r\n let query = 'podcast_delete';\r\n query += qs.stringify(params, '&');\r\n return this.request<Success>(query);\r\n }\r\n\r\n /**\r\n * This returns the episodes for a podcast\r\n * @remarks MINIMUM_API_VERSION=420000\r\n * @param params.filter UID of podcast\r\n * @param [params.offset]\r\n * @param [params.limit]\r\n * @see {@link https://ampache.org/api/api-json-methods#podcast_episodes}\r\n */\r\n async podcastEpisodes (params: {\r\n filter: UID,\r\n } & Pagination) {\r\n let query = 'podcast_episodes';\r\n query += qs.stringify(params, '&');\r\n let data = await this.request<{podcast_episode: PodcastEpisode[]}>(query);\r\n return (data.podcast_episode) ? data.podcast_episode : data;\r\n }\r\n\r\n /**\r\n * Get the podcast_episode from a UID\r\n * @remarks MINIMUM_API_VERSION=420000\r\n * @param params.filter UID of podcast\r\n * @see {@link https://ampache.org/api/api-json-methods#podcast_episode}\r\n */\r\n podcastEpisode (params: {\r\n filter: UID,\r\n }) {\r\n let query = 'podcast_episode';\r\n query += qs.stringify(params, '&');\r\n return this.request<PodcastEpisode>(query);\r\n }\r\n\r\n /**\r\n * Delete an existing podcast_episode\r\n * @remarks MINIMUM_API_VERSION=420000\r\n * @param params.filter UID of podcast episode to delete\r\n * @see {@link https://ampache.org/api/api-json-methods#podcast_episode_delete}\r\n */\r\n podcastEpisodeDelete (params: {\r\n filter: UID,\r\n }) {\r\n let query = 'podcast_episode_delete';\r\n query += qs.stringify(params, '&');\r\n return this.request<Success>(query);\r\n }\r\n\r\n /**\r\n * Sync and download new podcast episodes\r\n * ACCESS REQUIRED: 50 (Content Manager)\r\n * @remarks MINIMUM_API_VERSION=420000\r\n * @param params.id UID of podcast\r\n * @see {@link https://ampache.org/api/api-json-methods#update_podcast}\r\n */\r\n updatePodcast (params: {\r\n id: UID,\r\n }) {\r\n let query = 'update_podcast';\r\n query += qs.stringify(params, '&');\r\n return this.request<Success>(query);\r\n }\r\n\r\n /**\r\n * This returns the episodes for a podcast that have been deleted\r\n * @param [params.offset]\r\n * @param [params.limit]\r\n * @see {@link https://ampache.org/api/api-json-methods#deleted_podcast_episodes}\r\n */\r\n async deletedPodcastEpisodes (params?: {\r\n\r\n } & Pagination) {\r\n let query = 'deleted_podcast_episodes';\r\n query += qs.stringify(params, '&');\r\n let data = await this.request<{deleted_podcast_episode: DeletedPodcastEpisode[]}>(query);\r\n return (data.deleted_podcast_episode) ? data.deleted_podcast_episode : data;\r\n }\r\n}","import qs from 'querystringify';\r\nimport { Base, BinaryBoolean, Success } from '../base';\r\nimport { Preference } from \"./types\";\r\n\r\nexport class Preferences extends Base {\r\n /**\r\n * Get your server preferences\r\n * ACCESS REQUIRED: 100 (Admin)\r\n * @remarks MINIMUM_API_VERSION=5.0.0\r\n * @see {@link https://ampache.org/api/api-json-methods#system_preferences}\r\n */\r\n async systemPreferences () {\r\n let query = 'system_preferences';\r\n let data = await this.request<{preference: Preference[]}>(query);\r\n return (data.preference) ? data.preference : data;\r\n }\r\n\r\n /**\r\n * Get your system preference by name\r\n * ACCESS REQUIRED: 100 (Admin)\r\n * @remarks MINIMUM_API_VERSION=5.0.0\r\n * @param params.systemPreference Preference name e.g ('notify_email', 'ajax_load')\r\n * @see {@link https://ampache.org/api/api-json-methods#system_preference}\r\n */\r\n async systemPreference (params: {\r\n filter: string,\r\n }) {\r\n let query = 'system_preference';\r\n query += qs.stringify(params, '&');\r\n let data = await this.request<{Preference}>(query);\r\n return data[0];\r\n }\r\n\r\n /**\r\n * Get your user preferences\r\n * @remarks MINIMUM_API_VERSION=5.0.0\r\n * @see {@link https://ampache.org/api/api-json-methods#user_preferences}\r\n */\r\n async userPreferences () {\r\n let query = 'user_preferences';\r\n let data = await this.request<{preference: Preference[]}>(query);\r\n return (data.preference) ? data.preference : data;\r\n }\r\n\r\n /**\r\n * Get your user preference by name\r\n * @remarks MINIMUM_API_VERSION=5.0.0\r\n * @param params.filter Preference name e.g ('notify_email', 'ajax_load')\r\n * @see {@link https://ampache.org/api/api-json-methods#user_preference}\r\n */\r\n async userPreference (params: {\r\n filter: string,\r\n }) {\r\n let query = 'user_preference';\r\n query += qs.stringify(params, '&');\r\n let data = await this.request<{Preference}>(query);\r\n return data[0];\r\n }\r\n\r\n /**\r\n * Add a new preference to your server\r\n * ACCESS REQUIRED: 100 (Admin)\r\n * @param params.filter Preference name e.g ('notify_email', 'ajax_load')\r\n * @param params.type boolean, integer, string, special\r\n * @param params.default string or integer default value\r\n * @param params.category Category type\r\n * @param [params.description]\r\n * @param [params.subcategory]\r\n * @param [params.level] access level required to change the value (default 100)\r\n * @see {@link https://ampache.org/api/api-json-methods#preference_create}\r\n */\r\n preferenceCreate(params: {\r\n filter: string,\r\n type: 'boolean' | 'integer' | 'string' | 'special',\r\n default: string | number,\r\n category: 'interface' | 'internal' | 'options' | 'playlist' | 'plugins' | 'streaming',\r\n description?: string,\r\n subcategory?: string,\r\n level?: number,\r\n }) {\r\n let query = 'preference_create';\r\n query += qs.stringify(params, '&');\r\n return this.request<Success>(query);\r\n }\r\n\r\n /**\r\n * Edit a preference value and apply to all users if allowed\r\n * ACCESS REQUIRED: 100 (Admin)\r\n * @remarks MINIMUM_API_VERSION=5.0.0\r\n * @param params.filter Preference name e.g ('notify_email', 'ajax_load')\r\n * @param params.value (string/integer) Preference value\r\n * @param [params.all] 0, 1 apply to all users\r\n * @see {@link https://ampache.org/api/api-json-methods#preference_edit}\r\n */\r\n preferenceEdit(params: {\r\n filter: string,\r\n value: string | number,\r\n all?: BinaryBoolean,\r\n }) {\r\n let query = 'preference_edit';\r\n query += qs.stringify(params, '&');\r\n return this.request<Success>(query);\r\n }\r\n\r\n /**\r\n * Delete a non-system preference by name\r\n * ACCESS REQUIRED: 100 (Admin)\r\n * @param params.filter Preference name e.g ('notify_email', 'ajax_load')\r\n * @see {@link https://ampache.org/api/api-json-methods#preference_delete}\r\n */\r\n preferenceDelete(params: {\r\n filter: string,\r\n }) {\r\n let query = 'preference_delete';\r\n query += qs.stringify(params, '&');\r\n return this.request<Success>(query);\r\n }\r\n}","import qs from 'querystringify';\r\nimport { Share } from './types';\r\nimport { Base, BinaryBoolean, Pagination, Success, UID } from '../base';\r\n\r\nexport class Shares extends Base {\r\n /**\r\n * This searches the shares and returns... shares\r\n * @remarks MINIMUM_API_VERSION=420000\r\n * @param [params.filter] UID to find\r\n * @param [params.exact] 0, 1 boolean to match the exact filter string\r\n * @param [params.offset]\r\n * @param [params.limit]\r\n * @see {@link https://ampache.org/api/api-json-methods#shares}\r\n */\r\n async shares (params?: {\r\n filter?: string,\r\n exact?: BinaryBoolean,\r\n } & Pagination) {\r\n let query = 'shares';\r\n query += qs.stringify(params, '&');\r\n let data = await this.request<{share: Share[]}>(query);\r\n return (data.share) ? data.share : data;\r\n }\r\n\r\n /**\r\n * Return a share from UID\r\n * @remarks MINIMUM_API_VERSION=420000\r\n * @param params.filter UID to find\r\n * @see {@link https://ampache.org/api/api-json-methods#share}\r\n */\r\n share (params: {\r\n filter: UID,\r\n }) {\r\n let query = 'share';\r\n query += qs.stringify(params, '&');\r\n return this.request<Share>(query);\r\n }\r\n\r\n /**\r\n * Create a public url that can be used by anyone to stream media.\r\n * @remarks MINIMUM_API_VERSION=420000\r\n * @param params.filter UID of object you are sharing\r\n * @param params.type ('song', 'album', 'artist')\r\n * @param [params.description] description (will be filled for you if empty)\r\n * @param [params.expires] days to keep active\r\n * @see {@link https://ampache.org/api/api-json-methods#share_create}\r\n */\r\n shareCreate (params: {\r\n filter: UID,\r\n type: 'song' | 'album' | 'artist',\r\n description?: string,\r\n expires?: number,\r\n }) {\r\n let query = 'share_create';\r\n query += qs.stringify(params, '&');\r\n return this.request<Share>(query);\r\n }\r\n\r\n /**\r\n * Update the description and/or expiration date for an existing share\r\n * @remarks MINIMUM_API_VERSION=420000\r\n * @param params.filter UID to find\r\n * @param [params.stream] 0, 1\r\n * @param [params.download] 0, 1\r\n * @param [params.expires] days to keep active\r\n * @param [params.description] description\r\n * @see {@link https://ampache.org/api/api-json-methods#share_edit}\r\n */\r\n shareEdit (params: {\r\n filter: UID,\r\n stream?: BinaryBoolean,\r\n download?: BinaryBoolean,\r\n expires?: number,\r\n description?: string,\r\n }) {\r\n let query = 'share_edit';\r\n query += qs.stringify(params, '&');\r\n return this.request<Success>(query);\r\n }\r\n\r\n /**\r\n * Delete an existing share.\r\n * @remarks MINIMUM_API_VERSION=420000\r\n * @param params.filter UID of share to delete\r\n * @see {@link https://ampache.org/api/api-json-methods#share_delete}\r\n */\r\n shareDelete (params: {\r\n filter: UID,\r\n }) {\r\n let query = 'share_delete';\r\n query += qs.stringify(params, '&');\r\n return this.request<Success>(query);\r\n }\r\n}","import qs from 'querystringify';\r\nimport { Shout } from './types';\r\nimport { Base } from '../base';\r\n\r\nexport class Shouts extends Base {\r\n /**\r\n * This gets the latest posted shouts\r\n * @remarks MINIMUM_API_VERSION=380001\r\n * @param [params.username] Username to find\r\n * @param [params.limit] Maximum number of results to return\r\n * @see {@link https://ampache.org/api/api-json-methods#last_shouts}\r\n */\r\n async last_shouts (params?: {\r\n username?: string,\r\n limit?: number\r\n }) {\r\n let query = 'last_shouts';\r\n query += qs.stringify(params, '&');\r\n let data = await this.request<{shout: Shout[]}>(query);\r\n return (data.shout) ? data.shout : data;\r\n }\r\n}","import qs from 'querystringify';\r\nimport { Song, DeletedSong } from './types';\r\nimport { Base, BinaryBoolean, Pagination, Success, UID } from '../base';\r\n\r\nexport class Songs extends Base {\r\n /**\r\n * Returns songs based on the specified filter\r\n * @remarks MINIMUM_API_VERSION=380001\r\n * @param [params.filter] Filter results to match this string\r\n * @param [params.exact] 0, 1 (if true filter is exact = rather than fuzzy LIKE)\r\n * @param [params.add] ISO 8601 Date Format (2020-09-16) Find objects with an 'add' date newer than the specified date\r\n * @param [params.update] ISO 8601 Date Format (2020-09-16) Find objects with an 'update' time newer than the specified date\r\n * @param [params.offset]\r\n * @param [params.limit]\r\n * @see {@link https://ampache.org/api/api-json-methods#songs}\r\n */\r\n async songs (params?: {\r\n filter?: string,\r\n exact?: BinaryBoolean,\r\n add?: Date,\r\n update?: Date,\r\n } & Pagination) {\r\n let query = 'songs';\r\n query += qs.stringify(params, '&');\r\n let data = await this.request<{song: Song[]}>(query);\r\n return (data.song) ? data.song : data;\r\n }\r\n\r\n /**\r\n * Returns a single song\r\n * @remarks MINIMUM_API_VERSION=380001\r\n * @param params.filter UID to find\r\n * @see {@link https://ampache.org/api/api-json-methods#song}\r\n */\r\n song (params: {\r\n filter: UID,\r\n }) {\r\n let query = 'song';\r\n query += qs.stringify(params, '&');\r\n return this.request<Song>(query);\r\n }\r\n\r\n /**\r\n * Songs of the specified artist\r\n * @remarks MINIMUM_API_VERSION=380001\r\n * @param params.filter UID to find\r\n * @param [params.top50] 0, 1 (if true filter to the artist top 50)\r\n * @param [params.offset]\r\n * @param [params.limit]\r\n * @see {@link https://ampache.org/api/api-json-methods#artist_songs}\r\n */\r\n async artistSongs (params: {\r\n filter: UID,\r\n top50?: BinaryBoolean,\r\n } & Pagination) {\r\n let query = 'artist_songs';\r\n query += qs.stringify(params, '&');\r\n let data = await this.request<{song: Song[]}>(query);\r\n return (data.song) ? data.song : data;\r\n }\r\n\r\n /**\r\n * Songs of the specified album\r\n * @remarks MINIMUM_API_VERSION=380001\r\n * @param params.filter UID to find\r\n * @param [params.offset]\r\n * @param [params.limit]\r\n * @see {@link https://ampache.org/api/api-json-methods#album_songs}\r\n */\r\n async albumSongs (params: {\r\n filter: UID,\r\n } & Pagination) {\r\n let query = 'album_songs';\r\n query += qs.stringify(params, '&');\r\n let data = await this.request<{song: Song[]}>(query);\r\n return (data.song) ? data.song : data;\r\n }\r\n\r\n /**\r\n * Songs of the specified genre\r\n * @remarks MINIMUM_API_VERSION=380001\r\n * @param params.filter UID to find\r\n * @param [params.offset]\r\n * @param [params.limit]\r\n * @see {@link https://ampache.org/api/api-json-methods#genre_songs}\r\n */\r\n async genreSongs (params: {\r\n filter: UID,\r\n } & Pagination) {\r\n let query = 'genre_songs';\r\n query += qs.stringify(params, '&');\r\n let data = await this.request<{song: Song[]}>(query);\r\n return (data.song) ? data.song : data;\r\n }\r\n\r\n /**\r\n * This returns the songs for a playlist\r\n * @remarks MINIMUM_API_VERSION=380001\r\n * @param params.filter UID to find\r\n * @param [params.random] 0, 1 (if true get random songs using limit)\r\n * @param [params.offset]\r\n * @param [params.limit]\r\n * @see {@link https://ampache.org/api/api-json-methods#playlist_songs}\r\n */\r\n async playlistSongs (params: {\r\n filter: UID,\r\n random?: BinaryBoolean,\r\n } & Pagination) {\r\n let query = 'playlist_songs';\r\n query += qs.stringify(params, '&');\r\n let data = await this.request<{song: Song[]}>(query);\r\n return (data.song) ? data.song : data;\r\n }\r\n\r\n /**\r\n * This returns the songs for a license\r\n * @remarks MINIMUM_API_VERSION=420000\r\n * @param params.filter UID to find\r\n * @param [params.offset]\r\n * @param [params.limit]\r\n * @see {@link https://ampache.org/api/api-json-methods#license_songs}\r\n */\r\n async licenseSongs (params: {\r\n filter: UID,\r\n } & Pagination) {\r\n let query = 'license_songs';\r\n query += qs.stringify(params, '&');\r\n let data = await this.request<{song: Song[]}>(query);\r\n return (data.song) ? data.song : data;\r\n }\r\n\r\n /**\r\n * Delete an existing song. (if you are allowed to)\r\n * @remarks MINIMUM_API_VERSION=5.0.0\r\n * @param params.filter UID of song to delete\r\n * @see {@link https://ampache.org/api/api-json-methods#song_delete}\r\n */\r\n songDelete (params: {\r\n filter: UID,\r\n }) {\r\n let query = 'song_delete';\r\n query += qs.stringify(params, '&');\r\n return this.request<Success>(query);\r\n }\r\n\r\n /**\r\n * This takes a URL and returns the song object in question\r\n * @remarks MINIMUM_API_VERSION=380001\r\n * @param params.url Full Ampache URL from server\r\n * @see {@link https://ampache.org/api/api-json-methods#url_to_song}\r\n */\r\n urlToSong (params: {\r\n url: string,\r\n }) {\r\n let query = 'url_to_song';\r\n params.url = encodeURIComponent(params.url);\r\n query += qs.stringify(params, '&');\r\n return this.request<Song>(query);\r\n }\r\n\r\n /**\r\n * This searches the songs and returns... songs\r\n * @remarks MINIMUM_API_VERSION=380001\r\n * @param params.filter Filter results to match this string\r\n * @param [params.offset]\r\n * @param [params.limit]\r\n * @see {@link https://ampache.org/api/api-json-methods#search_songs}\r\n */\r\n async searchSongs (params: {\r\n filter: string,\r\n } & Pagination) {\r\n let query = 'search_songs';\r\n query += qs.stringify(params, '&');\r\n let data = await this.request<{song: Song[]}>(query);\r\n return (data.song) ? data.song : data;\r\n }\r\n\r\n /**\r\n * Returns songs that have been deleted from the server\r\n * @remarks MINIMUM_API_VERSION=500000\r\n * @param [params.offset]\r\n * @param [params.limit]\r\n * @see {@link https://ampache.org/api/api-json-methods#deleted_songs}\r\n */\r\n async deletedSongs (params?: {\r\n\r\n } & Pagination) {\r\n let query = 'deleted_songs';\r\n query += qs.stringify(params, '&');\r\n let data = await this.request<{deleted_song: DeletedSong[]}>(query);\r\n return (data.deleted_song) ? data.deleted_song : data;\r\n }\r\n}","import qs from 'querystringify';\r\nimport { Song } from \"../songs/types\";\r\nimport { Artist } from \"../artists/types\";\r\nimport { Base, BinaryBoolean, Pagination, Success, UID } from '../base';\r\nimport { Album } from '../albums/types';\r\nimport { Video } from '../videos/types';\r\nimport { Playlist } from '../playlists/types';\r\nimport { Podcast, PodcastEpisode } from '../podcasts/types';\r\nimport { LiveStream } from \"../live-streams/types\";\r\nimport { Label } from \"../labels/types\";\r\nimport { Genre } from \"../genres/types\";\r\nimport { User } from \"../users/types\";\r\nimport { IndexEntry } from \"./types\";\r\n\r\nexport class System extends Base {\r\n /**\r\n * Check Ampache for updates and run the update if there is one.\r\n * @remarks MINIMUM_API_VERSION=5.0.0\r\n * @see {@link https://ampache.org/api/api-json-methods#system_update}\r\n */\r\n systemUpdate () {\r\n let query = 'system_update';\r\n return this.request<Success>(query);\r\n }\r\n\r\n /**\r\n * This takes a collection of inputs and returns ID + name for the object type\r\n * @remarks MINIMUM_API_VERSION=400001\r\n * @param params.type type of object to find\r\n * @param [params.filter] search the name of the object_type\r\n * @param [params.add] ISO 8601 Date Format (2020-09-16) Find objects with an 'add' date newer than the specified date\r\n * @param [params.update] ISO 8601 Date Format (2020-09-16) Find objects with an 'update' time newer than the specified date\r\n * @param [params.include] 0, 1 (include songs in a playlist or episodes in a podcast)\r\n * @param [params.hide_search] 0, 1 (if true do not include searches/smartlists in the result)\r\n * @param [params.offset]\r\n * @param [params.limit]\r\n * @see {@link https://ampache.org/api/api-json-methods#get_indexes}\r\n * @deprecated Being removed in 7.0.0. Use `list` instead.\r\n */\r\n async getIndexes (params: {\r\n type: 'song' | 'album' | 'artist' | 'album_artist' | 'playlist' | 'podcast' | 'podcast_episode' | 'live_stream',\r\n filter?: string,\r\n add?: Date,\r\n update?: Date,\r\n include?: BinaryBoolean,\r\n hide_search?: BinaryBoolean\r\n } & Pagination) {\r\n let query = 'get_indexes';\r\n query += qs.stringify(params, '&');\r\n let data;\r\n\r\n switch (params.type) {\r\n case \"song\":\r\n data = await this.request<{song: Song[]}>(query);\r\n return (data.song) ? data.song : data;\r\n case \"album\":\r\n data = await this.request<{album: Album[]}>(query);\r\n return (data.album) ? data.album : data;\r\n case \"artist\":\r\n case \"album_artist\":\r\n data = await this.request<{artist: Artist[]}>(query);\r\n return (data.artist) ? data.artist : data;\r\n case \"playlist\":\r\n data = await this.request<{playlist: Playlist[]}>(query);\r\n return (data.playlist) ? data.playlist : data;\r\n case \"podcast\":\r\n data = await this.request<{podcast: Podcast[]}>(query);\r\n return (data.podcast) ? data.podcast : data;\r\n case \"podcast_episode\":\r\n data = await this.request<{podcast_episode: PodcastEpisode[]}>(query);\r\n return (data.podcast_episode) ? data.podcast_episode : data;\r\n case \"live_stream\":\r\n data = await this.request<{live_stream: LiveStream[]}>(query);\r\n return (data.live_stream) ? data.live_stream : data;\r\n default:\r\n return false;\r\n }\r\n }\r\n\r\n /**\r\n * This takes a named array of objects and returning `id`, `name`, `prefix` and `basename`\r\n * @remarks MINIMUM_API_VERSION=6.0.0\r\n * @param params.type type of object to find\r\n * @param [params.filter] Value is Alpha Match for returned results, may be more than one letter/number\r\n * @param [params.add] ISO 8601 Date Format (2020-09-16) Find objects with an 'add' date newer than the specified date\r\n * @param [params.update] ISO 8601 Date Format (2020-09-16) Find objects with an 'update' time newer than the specified date\r\n * @param [params.hide_search] 0, 1 (if true do not include searches/smartlists in the result)\r\n * @param [params.offset]\r\n * @param [params.limit]\r\n * @see {@link https://ampache.org/api/api-json-methods#list}\r\n */\r\n async list (params: {\r\n type: 'song' | 'album' | 'artist' | 'album_artist' | 'playlist' | 'podcast' | 'podcast_episode' | 'live_stream',\r\n filter?: string,\r\n add?: Date,\r\n update?: Date,\r\n hide_search?: BinaryBoolean\r\n } & Pagination) {\r\n let query = 'list';\r\n query += qs.stringify(params, '&');\r\n return this.request<{list: IndexEntry[]}>(query);\r\n }\r\n\r\n /**\r\n * Return children of a parent object in a folder traversal/browse style\r\n * If you don't send any parameters you'll get a catalog list (the 'root' path)\r\n * @remarks MINIMUM_API_VERSION=6.0.0\r\n * @param [params.filter] object_id\r\n * @param [params.type] type of object to find\r\n * @param [params.catalog] catalog ID you are browsing (required on 'artist', 'album', 'podcast')\r\n * @param [params.add] ISO 8601 Date Format (2020-09-16) Find objects with an 'add' date newer than the specified date\r\n * @param [params.update] ISO 8601 Date Format (2020-09-16) Find objects with an 'update' time newer than the specified date\r\n * @param [params.offset]\r\n * @param [params.limit]\r\n * @see {@link https://ampache.org/api/api-json-methods#browse}\r\n */\r\n async browse (params: {\r\n filter?: UID,\r\n type?: 'root' | 'catalog' | 'artist' | 'album' | 'podcast',\r\n catalog?: number,\r\n add?: Date,\r\n update?: Date,\r\n } & Pagination) {\r\n let query = 'browse';\r\n query += qs.stringify(params, '&');\r\n return this.request<{browse: IndexEntry[]}>(query);\r\n }\r\n\r\n /**\r\n * Return similar artist IDs or similar song IDs compared to the input filter\r\n * @remarks MINIMUM_API_VERSION=420000\r\n * @param params.type type of object to check against\r\n * @param params.filter UID to find\r\n * @param [params.offset]\r\n * @param [params.limit]\r\n * @see {@link https://ampache.org/api/api-json-methods#get_similar}\r\n */\r\n async getSimilar (params: {\r\n type: 'song' | 'artist',\r\n filter: UID,\r\n } & Pagination) {\r\n let query = 'get_similar';\r\n query += qs.stringify(params, '&');\r\n let data;\r\n\r\n switch (params.type) {\r\n case \"song\":\r\n data = await this.request<{song: Song[]}>(query);\r\n return (data.song) ? data.song : data;\r\n case \"artist\":\r\n data = await this.request<{artist: Artist[]}>(query);\r\n return (data.artist) ? data.artist : data;\r\n default:\r\n return false;\r\n }\r\n }\r\n\r\n /**\r\n * Get some items based on some simple search types and filters. (Random by default)\r\n * @remarks MINIMUM_API_VERSION=380001; CHANGED_IN_API_VERSION=400001\r\n * @param params.type Object type\r\n * @param [params.filter] newest, highest, frequent, recent, forgotten, flagged, random\r\n * @param [params.user_id] Filter results to a certain user by UID\r\n * @param [params.username] Filter results to a certain user by username\r\n * @param [params.offset]\r\n * @param [params.limit]\r\n * @see {@link https://ampache.org/api/api-json-methods#stats}\r\n */\r\n async stats (params: {\r\n type: 'song' | 'album' | 'artist' | 'video' | 'playlist' | 'podcast' | 'podcast_episode',\r\n filter?: 'newest' | 'highest' | 'frequent' | 'recent' | 'forgotten' | 'flagged' | 'random',\r\n user_id?: number,\r\n username?: string,\r\n } & Pagination) {\r\n let query = 'stats';\r\n query += qs.stringify(params, '&');\r\n let data;\r\n\r\n switch (params.type) {\r\n case \"song\":\r\n data = await this.request<{song: Song[]}>(query);\r\n return (data.song) ? data.song : data;\r\n case \"album\":\r\n data = await this.request<{album: Album[]}>(query);\r\n return (data.album) ? data.album : data;\r\n case \"artist\":\r\n data = await this.request<{artist: Artist[]}>(query);\r\n return (data.artist) ? data.artist : data;\r\n case \"video\":\r\n data = await this.request<{video: Video[]}>(query);\r\n return (data.video) ? data.video : data;\r\n case \"playlist\":\r\n data = await this.request<{playlist: Playlist[]}>(query);\r\n return (data.playlist) ? data.playlist : data;\r\n case \"podcast\":\r\n data = await this.request<{podcast: Podcast[]}>(query);\r\n return (data.podcast) ? data.podcast : data;\r\n case \"podcast_episode\":\r\n data = await this.request<{podcast_episode: PodcastEpisode[]}>(query);\r\n return (data.podcast_episode) ? data.podcast_episode : data;\r\n default:\r\n return false;\r\n }\r\n }\r\n\r\n /**\r\n * This rates a library item\r\n * @remarks MINIMUM_API_VERSION=380001\r\n * @param params.type Object type\r\n * @param params.id UID to find\r\n * @param params.rating Rating to apply\r\n * @see {@link https://ampache.org/api/api-json-methods#rate}\r\n */\r\n rate (params: {\r\n type: 'song' | 'album' | 'artist' | 'playlist' | 'podcast' | 'podcast_episode' | 'video' | 'tvshow' | 'tvshow_season',\r\n id: UID,\r\n rating: 0 | 1 | 2 | 3 | 4 | 5,\r\n }) {\r\n let query = 'rate';\r\n query += qs.stringify(params, '&');\r\n return this.request<Success>(query);\r\n }\r\n\r\n /**\r\n * This flags a library item as a favorite\r\n * @remarks MINIMUM_API_VERSION=400001\r\n * @param params.type Object type\r\n * @param params.id UID to find\r\n * @param params.flag 0, 1\r\n * @see {@link https://ampache.org/api/api-json-methods#flag}\r\n */\r\n flag (params: {\r\n type: 'song' | 'album' | 'artist' | 'playlist' | 'podcast' | 'podcast_episode' | 'video' | 'tvshow' | 'tvshow_season',\r\n id: UID,\r\n flag: BinaryBoolean,\r\n }) {\r\n let query = 'flag';\r\n query += qs.stringify(params, '&');\r\n return this.request<Success>(query);\r\n }\r\n\r\n /**\r\n * Take a song_id and update the object_count and user_activity table with a play. This allows other sources to record play history to Ampache.\r\n * If you don't supply a user id (optional) then just fall back to you.\r\n * ACCESS REQUIRED: 100 (Admin) permission to change another user's play history\r\n * @remarks MINIMUM_API_VERSION=400001\r\n * @param params.id UID of song\r\n * @param [params.user] UID of user\r\n * @param [params.client] Client string\r\n * @param [params.date] UNIXTIME\r\n * @see {@link https://ampache.org/api/api-json-methods#record_play}\r\n */\r\n recordPlay (params: {\r\n id: UID,\r\n user?: UID,\r\n client?: string,\r\n date?: number,\r\n }) {\r\n let query = 'record_play';\r\n query += qs.stringify(params, '&');\r\n return this.request<Success>(query);\r\n }\r\n\r\n /**\r\n * Search for a song using text info and then record a play if found. This allows other sources to record play history to ampache\r\n * @remarks MINIMUM_API_VERSION=400001\r\n * @param params.song HTML encoded string\r\n * @param params.artist HTML encoded string\r\n * @param params.album HTML encoded string\r\n * @param [params.songmbid] Song MBID\r\n * @param [params.artistmbid] Artist MBID\r\n * @param [params.albummbid] Album MBID\r\n * @param [params.song_mbid] Alias of songmbid\r\n * @param [params.artist_mbid] Alias of artistmbid\r\n * @param [params.album_mbid] Alias of albummbid\r\n * @param [params.date] UNIXTIME\r\n * @param [params.client] Client string\r\n * @see {@link https://ampache.org/api/api-json-methods#scrobble}\r\n */\r\n scrobble (params: {\r\n song: string,\r\n artist: string,\r\n album: string,\r\n songmbid?: string,\r\n artistmbid?: string,\r\n albummbid?: string,\r\n song_mbid?: string,\r\n artist_mbid?: string,\r\n album_mbid?: string,\r\n date?: number,\r\n client?: string,\r\n }) {\r\n let query = 'scrobble';\r\n query += qs.stringify(params, '&');\r\n return this.request<Success>(query);\r\n }\r\n\r\n /**\r\n * Update a single album, artist, song from the tag data\r\n * @remarks MINIMUM_API_VERSION=400001\r\n * @param params.type Object type\r\n * @param params.id UID to find\r\n * @see {@link https://ampache.org/api/api-json-methods#update_from_tags}\r\n */\r\n updateFromTags (params: {\r\n type: 'song' | 'artist' | 'album',\r\n id: UID,\r\n }) {\r\n let query = 'update_from_tags';\r\n query += qs.stringify(params, '&');\r\n return this.request<Success>(query);\r\n }\r\n\r\n /**\r\n * Update artist information and fetch similar artists from last.fm\r\n * Make sure lastfm_API_key is set in your configuration file\r\n * ACCESS REQUIRED: 75 (Catalog Manager)\r\n * @remarks MINIMUM_API_VERSION=400001\r\n * @param params.id UID to find\r\n * @see {@link https://ampache.org/api/api-json-methods#update_artist_info}\r\n */\r\n updateArtistInfo (params: {\r\n id: UID,\r\n }) {\r\n let query = 'update_artist_info';\r\n query += qs.stringify(params, '&');\r\n return this.request<Success>(query);\r\n }\r\n\r\n /**\r\n * Updates a single album, artist, song running the gather_art process.\r\n * Doesn't overwrite existing art by default.\r\n * ACCESS REQUIRED: 75 (Catalog Manager)\r\n * @remarks MINIMUM_API_VERSION=400001\r\n * @param params.id UID to update\r\n * @param params.type Object type\r\n * @param [params.overwrite]\r\n * @see {@link https://ampache.org/api/api-json-methods#update_art}\r\n */\r\n updateArt (params: {\r\n id: UID,\r\n type: 'artist' | 'album' | 'song',\r\n overwrite?: BinaryBoolean,\r\n }) {\r\n let query = 'update_art';\r\n query += qs.stringify(params, '&');\r\n return this.request<Success>(query);\r\n }\r\n\r\n /**\r\n * Streams a given media file. Takes the file id in parameter with optional max bit rate, file format, time offset,\r\n * size and estimate content length option.\r\n * NOTE search and playlist will only stream a random object from the list.\r\n * @remarks MINIMUM_API_VERSION=400001\r\n * @param params.id UID to find\r\n * @param params.type Object type\r\n * @param [params.bitrate] Max bitrate for transcoding\r\n * @param [params.format] mp3, ogg, raw, etc (raw returns the original format)\r\n * @param [params.offset] Time offset\r\n * @param [params.length] 0, 1 (estimate content length)\r\n * @see {@link https://ampache.org/api/api-json-methods#stream}\r\n */\r\n stream (params: {\r\n id: UID,\r\n type: 'song' | 'podcast_episode' | 'search' | 'playlist',\r\n bitrate?: number,\r\n format?: string,\r\n offset?: number,\r\n length?: BinaryBoolean,\r\n }) {\r\n let query = 'stream';\r\n query += qs.stringify(params, '&');\r\n return this.binary(query);\r\n }\r\n\r\n /**\r\n * Downloads a given media file. set format=raw to download the full file\r\n * NOTE search and playlist will only download a random object from the list\r\n * @remarks MINIMUM_API_VERSION=400001\r\n * @param params.id UID to find\r\n * @param params.type Object type\r\n * @param [params.format] mp3, ogg, raw, etc (raw returns the original format)\r\n * @see {@link https://ampache.org/api/api-json-methods#download}\r\n */\r\n download (params: {\r\n id: UID,\r\n type: 'song' | 'podcast_episode' | 'search' | 'playlist',\r\n format?: string,\r\n }) {\r\n let query = 'download';\r\n query += qs.stringify(params, '&');\r\n return this.binary(query);\r\n }\r\n\r\n /**\r\n * Get an art image file.\r\n * @remarks MINIMUM_API_VERSION=400001\r\n * @param params.id UID to find\r\n * @param params.type Object type\r\n * @see {@link https://ampache.org/api/api-json-methods#get_art}\r\n */\r\n getArt (params: {\r\n id: UID,\r\n type: 'song' | 'artist' | 'album' | 'playlist' | 'search' | 'podcast',\r\n }) {\r\n let query = 'get_art';\r\n query += qs.stringify(params, '&');\r\n return this.binary(query);\r\n }\r\n\r\n /**\r\n * This is for controlling localplay\r\n * @param params.command The command to send to the localplay controller\r\n * @param [params.oid] Object UID\r\n * @param [params.type] Object type\r\n * @param [params.clear] 0, 1 (Clear the current playlist before adding)\r\n * @remarks MINIMUM_API_VERSION=380001; CHANGED_IN_API_VERSION=5.0.0\r\n * @see {@link https://ampache.org/api/api-json-methods#localplay}\r\n */\r\n localplay (params: {\r\n command: 'next' | 'prev' | 'stop' | 'play' | 'pause' | 'add' | 'volume_up' | 'volume_down' | 'volume_mute' | 'delete_all' | 'skip' | 'status',\r\n oid?: number,\r\n type?: 'song' | 'video' | 'podcast_episode' | 'channel' | 'broadcast' | 'democratic' | 'live_stream',\r\n clear?: BinaryBoolean,\r\n }) {\r\n let query = 'localplay';\r\n query += qs.stringify(params, '&');\r\n return this.request(query);\r\n }\r\n\r\n /**\r\n * Get the list of songs in your localplay playlist\r\n * @remarks MINIMUM_API_VERSION=5.0.0\r\n * @see {@link https://ampache.org/api/api-json-methods#localplay_songs}\r\n */\r\n localplaySongs () {\r\n let query = 'localplay_songs';\r\n return this.request(query);\r\n }\r\n\r\n /**\r\n * This is for controlling democratic play (Songs only). VOTE: +1 vote for the oid. DEVOTE: -1 vote for the oid.\r\n * PLAYLIST: Return an array of song items with an additional VOTE COUNT element.\r\n * PLAY: Returns the URL for playing democratic play.\r\n * @remarks MINIMUM_API_VERSION=380001\r\n * @param params.oid UID of song\r\n * @param params.method vote, devote, playlist, play\r\n * @see {@link https://ampache.org/api/api-json-methods#democratic}\r\n */\r\n democratic (params: {\r\n oid: UID,\r\n method: 'vote' | 'devote' | 'playlist' | 'play',\r\n }) {\r\n let query = 'democratic';\r\n query += qs.stringify(params, '&');\r\n return this.request(query);\r\n }\r\n\r\n /**\r\n * Perform an advanced search given passed rules.\r\n * You'll want to consult the docs for this.\r\n * @remarks MINIMUM_API_VERSION=380001\r\n * @param params.operator and, or (whether to match one rule or all)\r\n * @param params.type Object type to return\r\n * @param params.rules An array of rules\r\n * @param [params.random] 0, 1 (random order of results; default to 0)\r\n * @param [params.offset]\r\n * @param [params.limit]\r\n * @see {@link https://ampache.org/api/api-json-methods#advanced_search}\r\n */\r\n async advancedSearch (params: {\r\n operator: 'and' | 'or',\r\n type: 'song' | 'album' | 'album_disk' | 'artist' | 'label' | 'playlist' | 'podcast' | 'podcast_episode' | 'genre' | 'user' | 'video',\r\n rules: Array<Array<string>>,\r\n random?: BinaryBoolean,\r\n } & Pagination) {\r\n let query = 'advanced_search';\r\n\r\n for (let i = 0; i < params.rules.length; i++) {\r\n const thisRule = params.rules[i];\r\n const ruleNumber = i + 1;\r\n\r\n params['rule_' + ruleNumber] = thisRule[0];\r\n params['rule_' + ruleNumber + '_operator'] = thisRule[1];\r\n params['rule_' + ruleNumber + '_input'] = thisRule[2];\r\n\r\n if (thisRule[0] === 'metadata') {\r\n params['rule_' + ruleNumber + '_subtype'] = thisRule[3];\r\n }\r\n }\r\n\r\n // drop the initial 'rules' as it was split into its parts\r\n delete params.rules;\r\n\r\n query += qs.stringify(params, '&');\r\n\r\n let data;\r\n\r\n switch (params.type) {\r\n case \"song\":\r\n data = await this.request<{song: Song[]}>(query);\r\n return (data.song) ? data.song : data;\r\n case \"album\":\r\n data = await this.request<{album: Album[]}>(query);\r\n return (data.album) ? data.album : data;\r\n case \"artist\":\r\n data = await this.request<{artist: Artist[]}>(query);\r\n return (data.artist) ? data.artist : data;\r\n case \"label\":\r\n data = await this.request<{label: Label[]}>(query);\r\n return (data.label) ? data.label : data;\r\n case \"playlist\":\r\n data = await this.request<{playlist: Playlist[]}>(query);\r\n return (data.playlist) ? data.playlist : data;\r\n case \"podcast\":\r\n data = await this.request<{podcast: Podcast[]}>(query);\r\n return (data.podcast) ? data.podcast : data;\r\n case \"podcast_episode\":\r\n data = await this.request<{podcast_episode: PodcastEpisode[]}>(query);\r\n return (data.podcast_episode) ? data.podcast_episode : data;\r\n case \"genre\":\r\n data = await this.request<{genre: Genre[]}>(query);\r\n return (data.genre) ? data.genre : data;\r\n case \"user\":\r\n data = await this.request<{user: User[]}>(query);\r\n return (data.user) ? data.user : data;\r\n case \"video\":\r\n data = await this.request<{video: Video[]}>(query);\r\n return (data.video) ? data.video : data;\r\n default:\r\n return false;\r\n }\r\n }\r\n}","import qs from 'querystringify';\r\nimport { User, UserSummary, Activity } from './types';\r\nimport { Base, BinaryBoolean, Success } from '../base';\r\n\r\nexport class Users extends Base {\r\n /**\r\n * Get ids and usernames for your site\r\n * @remarks MINIMUM_API_VERSION=5.0.0\r\n * @see {@link https://ampache.org/api/api-json-methods#users}\r\n */\r\n async users() {\r\n let query = 'users';\r\n let data = await this.request<{user: UserSummary[]}>(query);\r\n return (data.user) ? data.user : data;\r\n }\r\n\r\n /**\r\n * This get a user's public information\r\n * @remarks MINIMUM_API_VERSION=380001\r\n * @param params.username UID to find\r\n * @see {@link https://ampache.org/api/api-json-methods#user}\r\n */\r\n async user (params: {\r\n username: string\r\n }) {\r\n let query = 'user';\r\n query += qs.stringify(params, '&');\r\n return await this.request<User>(query);\r\n }\r\n\r\n /**\r\n * Create a new user\r\n * ACCESS REQUIRED: 100 (Admin)\r\n * @remarks MINIMUM_API_VERSION=400001\r\n * @param params.username Username\r\n * @param params.password SHA256 hashed password\r\n * @param params.email Email\r\n * @param [params.fullname] Full Name\r\n * @param [params.disable] 0, 1\r\n * @param [params.catalog_filter_group] Catalog filter group, default = 0\r\n * @see {@link https://ampache.org/api/api-json-methods#user_create}\r\n */\r\n userCreate (params: {\r\n username: string,\r\n password: string,\r\n email: string,\r\n fullname?: string,\r\n disable?: BinaryBoolean,\r\n catalog_filter_group?: number\r\n }) {\r\n let query = 'user_create';\r\n query += qs.stringify(params, '&');\r\n return this.request<Success>(query);\r\n }\r\n\r\n /**\r\n * Register as a new user if allowed.\r\n * @remarks MINIMUM_API_VERSION=6.0.0\r\n * @param params.username Username\r\n * @param params.password SHA256 hashed password\r\n * @param params.email Email\r\n * @param [params.fullname] Full Name\r\n * @see {@link https://ampache.org/api/api-json-methods/#register}\r\n */\r\n register (params: {\r\n username: string,\r\n password: string,\r\n email: string,\r\n fullname?: string\r\n }) {\r\n let query = 'register';\r\n query += qs.stringify(params, '&');\r\n return this.request<Success>(query);\r\n }\r\n\r\n /**\r\n * Update an existing user\r\n * ACCESS REQUIRED: 100 (Admin)\r\n * @remarks MINIMUM_API_VERSION=400001\r\n * @param params.username Username\r\n * @param [params.password] Password\r\n * @param [params.email] Email\r\n * @param [params.fullname] Full Name\r\n * @param [params.website] Website\r\n * @param [params.state] State\r\n * @param [params.city] City\r\n * @param [params.disable] 0, 1\r\n * @param [params.maxbitrate] Max bitrate for transcoding\r\n * @see {@link https://ampache.org/api/api-json-methods#user_update}\r\n * @deprecated Being removed in 7.0.0. Use `user_edit` instead.\r\n */\r\n userUpdate (params: {\r\n username: string,\r\n password?: string,\r\n email?: string,\r\n fullname?: string,\r\n website?: string,\r\n state?: string,\r\n city?: string,\r\n disable?: BinaryBoolean,\r\n maxbitrate?: string\r\n }) {\r\n let query = 'user_update';\r\n query += qs.stringify(params, '&');\r\n return this.request<Success>(query);\r\n }\r\n\r\n /**\r\n * Update an existing user\r\n * ACCESS REQUIRED: 100 (Admin)\r\n * @remarks MINIMUM_API_VERSION=6.0.0\r\n * @param params.username Username\r\n * @param [params.password] Password\r\n * @param [params.email] Email\r\n * @param [params.fullname] Full Name\r\n * @param [params.website] Website\r\n * @param [params.state] State\r\n * @param [params.city] City\r\n * @param [params.disable] 0, 1\r\n * @param [params.maxbitrate] Max bitrate for transcoding\r\n * @param [params.group] Catalog filter group, default = 0\r\n * @param [params.fullname_public] show fullname in public display\r\n * @param [params.reset_apikey] reset user Api Key\r\n * @param [params.reset_streamtoken] reset user Stream Token\r\n * @param [params.clear_stats] reset all stats for this user\r\n * @see {@link https://ampache.org/api/api-json-methods#user_edit}\r\n */\r\n userEdit (params: {\r\n username: string,\r\n password?: string,\r\n email?: string,\r\n fullname?: string,\r\n website?: string,\r\n state?: string,\r\n city?: string,\r\n maxbitrate?: string,\r\n group?: number,\r\n disable?: BinaryBoolean,\r\n fullname_public?: BinaryBoolean,\r\n reset_apikey?: BinaryBoolean,\r\n reset_streamtoken?: BinaryBoolean,\r\n clear_stats?: BinaryBoolean,\r\n }) {\r\n let query = 'user_edit';\r\n query += qs.stringify(params, '&');\r\n return this.request<Success>(query);\r\n }\r\n\r\n /**\r\n * Delete an existing user.\r\n * ACCESS REQUIRED: 100 (Admin)\r\n * @remarks MINIMUM_API_VERSION=400001\r\n * @param params.filter UID of user to delete\r\n * @see {@link https://ampache.org/api/api-json-methods#user_delete}\r\n */\r\n userDelete (params: {\r\n filter: string,\r\n }) {\r\n let query = 'user_delete';\r\n query += qs.stringify(params, '&');\r\n return this.request<Success>(query);\r\n }\r\n\r\n /**\r\n * This gets the followers for the requested username\r\n * @remarks MINIMUM_API_VERSION=380001\r\n * @param params.username UID to find\r\n * @see {@link https://ampache.org/api/api-json-methods#followers}\r\n */\r\n async followers (params: {\r\n username: string,\r\n }) {\r\n let query = 'followers';\r\n query += qs.stringify(params, '&');\r\n let data = await this.request<{user: UserSummary[]}>(query);\r\n return (data.user) ? data.user : data;\r\n }\r\n\r\n /**\r\n * Get a list of people that this user follows\r\n * @remarks MINIMUM_API_VERSION=380001\r\n * @see {@link https://ampache.org/api/api-json-methods#following}\r\n */\r\n async following (params: {\r\n username: string,\r\n }) {\r\n let query = 'following';\r\n query += qs.stringify(params, '&');\r\n let data = await this.request<{user: UserSummary[]}>(query);\r\n return (data.user) ? data.user : data;\r\n }\r\n\r\n /**\r\n * This will follow/unfollow a user\r\n * @param params.username Username string to find\r\n * @see {@link https://ampache.org/api/api-json-methods#toggle_follow}\r\n */\r\n toggleFollow(params: {\r\n username: string,\r\n }) {\r\n let query = 'toggle_follow';\r\n query += qs.stringify(params, '&');\r\n return this.request<Success>(query);\r\n }\r\n\r\n /**\r\n * This get a user timeline\r\n * @remarks MINIMUM_API_VERSION=380001\r\n * @param params.username Username to find\r\n * @param [params.limit] Max results to return\r\n * @param [params.since] UNIXTIME\r\n * @see {@link https://ampache.org/api/api-json-methods#timeline}\r\n */\r\n async timeline (params: {\r\n username: string,\r\n limit?: number,\r\n since?: number,\r\n }) {\r\n let query = 'timeline';\r\n query += qs.stringify(params, '&');\r\n let data = await this.request<{activity: Activity[]}>(query);\r\n return (data.activity) ? data.activity : data;\r\n }\r\n\r\n /**\r\n * This get current user friends timeline\r\n * @remarks MINIMUM_API_VERSION=380001\r\n * @param [params.limit] Max results to return\r\n * @param [params.since] UNIXTIME\r\n * @see {@link https://ampache.org/api/api-json-methods#friends_timeline}\r\n */\r\n async friendsTimeline (params?: {\r\n limit?: number,\r\n since?: number,\r\n }) {\r\n let query = 'friends_timeline';\r\n query += qs.stringify(params, '&');\r\n let data = await this.request<{activity: Activity[]}>(query);\r\n return (data.activity) ? data.activity : data;\r\n }\r\n}","import qs from 'querystringify';\r\nimport { Video, DeletedVideo } from './types';\r\nimport { Base, BinaryBoolean, Pagination, UID } from '../base';\r\n\r\nexport class Videos extends Base {\r\n /**\r\n * Get videos\r\n * @remarks MINIMUM_API_VERSION=380001\r\n * @param [params.filter] Filter results to match this string\r\n * @param [params.exact] 0, 1 (if true filter is exact = rather than fuzzy LIKE)\r\n * @param [params.offset]\r\n * @param [params.limit]\r\n * @see {@link https://ampache.org/api/api-json-methods#videos}\r\n */\r\n async videos (params?: {\r\n filter?: string,\r\n exact?: BinaryBoolean,\r\n } & Pagination) {\r\n let query = 'videos';\r\n query += qs.stringify(params, '&');\r\n let data = await this.request<{video: Video[]}>(query);\r\n return (data.video) ? data.video : data;\r\n }\r\n\r\n /**\r\n * This returns a single video\r\n * @remarks MINIMUM_API_VERSION=380001\r\n * @param params.filter UID to find\r\n * @see {@link https://ampache.org/api/api-json-methods#video}\r\n */\r\n video (params: {\r\n filter: UID,\r\n }) {\r\n let query = 'video';\r\n query += qs.stringify(params, '&');\r\n return this.request<Video>(query);\r\n }\r\n\r\n /**\r\n * This returns video objects that have been deleted\r\n * @param [params.offset]\r\n * @param [params.limit]\r\n * @see {@link https://ampache.org/api/api-json-methods#deleted_videos}\r\n */\r\n async deletedVideos (params?: {\r\n\r\n } & Pagination) {\r\n let query = 'deleted_videos';\r\n query += qs.stringify(params, '&');\r\n let data = await this.request<{deleted_video: DeletedVideo[]}>(query);\r\n return (data.deleted_video) ? data.deleted_video : data;\r\n }\r\n}"],"names":["has","Object","prototype","hasOwnProperty","encode","input","encodeURIComponent","e","obj","prefix","value","key","pairs","call","isNaN","push","length","join","n","Promise","t","r","s","XMLHttpRequest","o","u","i","a","ok","status","statusText","url","responseURL","text","resolve","responseText","json","then","JSON","parse","blob","Blob","response","clone","headers","keys","entries","get","toLowerCase","l","open","method","onload","getAllResponseHeaders","replace","onerror","withCredentials","credentials","setRequestHeader","send","body","browser","self","fetch","require$$0","default","Base","constructor","config","sessionKey","this","version","debug","request","endpoint","includeAuth","console","Error","binary","setSessionKey","h","f","binLen","c","parseInt","substr","w","E","A","charCodeAt","p","indexOf","search","charAt","ArrayBuffer","Uint8Array","outputUpper","toUpperCase","b64Pad","String","fromCharCode","outputLen","shakeLen","encoding","numRounds","U","R","update","T","F","m","g","slice","getHash","H","B","v","C","Y","S","I","setHMACKey","L","M","getHMAC","N","d","y","b","super","hmacKey","format","AmpacheAPI","applyMixins","derivedCtor","baseCtors","async","params","query","qs","data","album","artist","Auth","handshake","timestamp","Math","floor","Date","getTime","user","auth","ping","goodbye","encryptPassword","getSHA256","password","time","shaObj","JsSHA","bookmark","getBookmark","bookmarkCreate","bookmarkEdit","bookmarkDelete","catalog","catalogAction","catalogFile","catalogAdd","catalogDelete","genre","label","license","live_stream","liveStream","liveStreamCreate","liveStreamEdit","liveStreamDelete","playlist","Array","isArray","results","filter","item","id","toString","match","playlistCreate","playlistEdit","playlistDelete","playlistAddSong","playlistRemoveSong","song","Podcasts","podcast","podcastCreate","podcastEdit","podcastDelete","podcast_episode","podcastEpisode","podcastEpisodeDelete","updatePodcast","deleted_podcast_episode","preference","preferenceCreate","preferenceEdit","preferenceDelete","share","shareCreate","shareEdit","shareDelete","shout","Songs","songDelete","urlToSong","deleted_song","systemUpdate","type","video","rate","flag","recordPlay","scrobble","updateFromTags","updateArtistInfo","updateArt","stream","download","getArt","localplay","localplaySongs","democratic","rules","thisRule","ruleNumber","userCreate","register","userUpdate","userEdit","userDelete","toggleFollow","activity","Videos","deleted_video","forEach","baseCtor","getOwnPropertyNames","name","defineProperty","getOwnPropertyDescriptor"],"mappings":"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"}
1
+ {"version":3,"file":"index.modern.mjs","sources":["../node_modules/querystringify/index.js","../node_modules/unfetch/dist/unfetch.module.js","../node_modules/isomorphic-unfetch/browser.js","../src/base.ts","../node_modules/jssha/dist/sha256.mjs","../src/index.ts","../src/utils.ts","../src/albums/index.ts","../src/artists/index.ts","../src/auth/index.ts","../src/bookmarks/index.ts","../src/catalogs/index.ts","../src/genres/index.ts","../src/labels/index.ts","../src/licenses/index.ts","../src/live-streams/index.ts","../src/playlists/index.ts","../src/podcasts/index.ts","../src/preferences/index.ts","../src/shares/index.ts","../src/shouts/index.ts","../src/songs/index.ts","../src/system/index.ts","../src/users/index.ts","../src/videos/index.ts"],"sourcesContent":["'use strict';\n\nvar has = Object.prototype.hasOwnProperty\n , undef;\n\n/**\n * Decode a URI encoded string.\n *\n * @param {String} input The URI encoded string.\n * @returns {String|Null} The decoded string.\n * @api private\n */\nfunction decode(input) {\n try {\n return decodeURIComponent(input.replace(/\\+/g, ' '));\n } catch (e) {\n return null;\n }\n}\n\n/**\n * Attempts to encode a given input.\n *\n * @param {String} input The string that needs to be encoded.\n * @returns {String|Null} The encoded string.\n * @api private\n */\nfunction encode(input) {\n try {\n return encodeURIComponent(input);\n } catch (e) {\n return null;\n }\n}\n\n/**\n * Simple query string parser.\n *\n * @param {String} query The query string that needs to be parsed.\n * @returns {Object}\n * @api public\n */\nfunction querystring(query) {\n var parser = /([^=?#&]+)=?([^&]*)/g\n , result = {}\n , part;\n\n while (part = parser.exec(query)) {\n var key = decode(part[1])\n , value = decode(part[2]);\n\n //\n // Prevent overriding of existing properties. This ensures that build-in\n // methods like `toString` or __proto__ are not overriden by malicious\n // querystrings.\n //\n // In the case if failed decoding, we want to omit the key/value pairs\n // from the result.\n //\n if (key === null || value === null || key in result) continue;\n result[key] = value;\n }\n\n return result;\n}\n\n/**\n * Transform a query string to an object.\n *\n * @param {Object} obj Object that should be transformed.\n * @param {String} prefix Optional prefix.\n * @returns {String}\n * @api public\n */\nfunction querystringify(obj, prefix) {\n prefix = prefix || '';\n\n var pairs = []\n , value\n , key;\n\n //\n // Optionally prefix with a '?' if needed\n //\n if ('string' !== typeof prefix) prefix = '?';\n\n for (key in obj) {\n if (has.call(obj, key)) {\n value = obj[key];\n\n //\n // Edge cases where we actually want to encode the value to an empty\n // string instead of the stringified value.\n //\n if (!value && (value === null || value === undef || isNaN(value))) {\n value = '';\n }\n\n key = encode(key);\n value = encode(value);\n\n //\n // If we failed to encode the strings, we should bail out as we don't\n // want to add invalid strings to the query.\n //\n if (key === null || value === null) continue;\n pairs.push(key +'='+ value);\n }\n }\n\n return pairs.length ? prefix + pairs.join('&') : '';\n}\n\n//\n// Expose the module.\n//\nexports.stringify = querystringify;\nexports.parse = querystring;\n","export default function(e,n){return n=n||{},new Promise(function(t,r){var s=new XMLHttpRequest,o=[],u=[],i={},a=function(){return{ok:2==(s.status/100|0),statusText:s.statusText,status:s.status,url:s.responseURL,text:function(){return Promise.resolve(s.responseText)},json:function(){return Promise.resolve(s.responseText).then(JSON.parse)},blob:function(){return Promise.resolve(new Blob([s.response]))},clone:a,headers:{keys:function(){return o},entries:function(){return u},get:function(e){return i[e.toLowerCase()]},has:function(e){return e.toLowerCase()in i}}}};for(var l in s.open(n.method||\"get\",e,!0),s.onload=function(){s.getAllResponseHeaders().replace(/^(.*?):[^\\S\\n]*([\\s\\S]*?)$/gm,function(e,n,t){o.push(n=n.toLowerCase()),u.push([n,t]),i[n]=i[n]?i[n]+\",\"+t:t}),t(a())},s.onerror=r,s.withCredentials=\"include\"==n.credentials,n.headers)s.setRequestHeader(l,n.headers[l]);s.send(n.body||null)})}\n//# sourceMappingURL=unfetch.module.js.map\n","module.exports = self.fetch || (self.fetch = require('unfetch').default || require('unfetch'));\n","import fetch from 'isomorphic-unfetch';\r\n\r\ntype Config = {\r\n url: string,\r\n sessionKey?: string,\r\n debug?: boolean,\r\n}\r\n\r\nexport type Success = {\r\n success: string,\r\n}\r\n\r\n/**\r\n * @param [offset] Return results starting from this index position\r\n * @param [limit] Maximum number of results to return\r\n */\r\nexport type Pagination = {\r\n offset?: number,\r\n limit?: number,\r\n}\r\n\r\nexport type BinaryBoolean = 0 | 1;\r\n\r\nexport type UID = string | number;\r\n\r\nexport abstract class Base {\r\n sessionKey: string;\r\n url: string;\r\n version: string = '6.0.0';// default to latest version\r\n debug: boolean;\r\n\r\n constructor(config: Config) {\r\n this.sessionKey = config.sessionKey || null;\r\n this.url = config.url;\r\n this.debug = config.debug || false;\r\n }\r\n\r\n protected request<T> (endpoint: string, includeAuth: boolean = true): Promise<T> {\r\n let url = this.url + \"/server/json.server.php?action=\" + endpoint;\r\n\r\n // some endpoints like ping() or goodbye() can pass their own auth\r\n if (includeAuth) {\r\n url += \"&auth=\" + this.sessionKey + \"&version=\" + this.version;\r\n }\r\n\r\n if (this.debug) {\r\n console.debug(\r\n \"javascript-ampache query URL %c\" + url,\r\n \"color: black; font-style: italic; background-color: orange;padding: 2px\"\r\n );\r\n }\r\n\r\n return fetch(url).then(r => {\r\n if (r.ok) {\r\n return r.json();\r\n }\r\n throw new Error(r.statusText);\r\n })\r\n }\r\n\r\n protected binary<T> (endpoint: string, includeAuth: boolean = true): Promise<Blob> {\r\n let url = this.url + \"/server/json.server.php?action=\" + endpoint;\r\n\r\n if (includeAuth) {\r\n url += \"&auth=\" + this.sessionKey + \"&version=\" + this.version;\r\n }\r\n\r\n if (this.debug) {\r\n console.debug(\r\n \"javascript-ampache query URL %c\" + url,\r\n \"color: black; font-style: italic; background-color: orange;padding: 2px\"\r\n );\r\n }\r\n\r\n return fetch(url)\r\n .then(response => response.blob())\r\n .then(r => {\r\n return r;\r\n })\r\n }\r\n\r\n public setSessionKey(sessionKey: string) {\r\n this.sessionKey = sessionKey;\r\n }\r\n}","/**\n * A JavaScript implementation of the SHA family of hashes - defined in FIPS PUB 180-4, FIPS PUB 202,\n * and SP 800-185 - as well as the corresponding HMAC implementation as defined in FIPS PUB 198-1.\n *\n * Copyright 2008-2023 Brian Turek, 1998-2009 Paul Johnston & Contributors\n * Distributed under the BSD License\n * See http://caligatio.github.com/jsSHA/ for more information\n */\nconst t=\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\",r=\"ARRAYBUFFER not supported by this environment\",n=\"UINT8ARRAY not supported by this environment\";function i(t,r,n,i){let e,s,o;const h=r||[0],u=(n=n||0)>>>3,f=-1===i?3:0;for(e=0;e<t.length;e+=1)o=e+u,s=o>>>2,h.length<=s&&h.push(0),h[s]|=t[e]<<8*(f+i*(o%4));return{value:h,binLen:8*t.length+n}}function e(e,s,o){switch(s){case\"UTF8\":case\"UTF16BE\":case\"UTF16LE\":break;default:throw new Error(\"encoding must be UTF8, UTF16BE, or UTF16LE\")}switch(e){case\"HEX\":return function(t,r,n){return function(t,r,n,i){let e,s,o,h;if(0!=t.length%2)throw new Error(\"String of HEX type must be in byte increments\");const u=r||[0],f=(n=n||0)>>>3,c=-1===i?3:0;for(e=0;e<t.length;e+=2){if(s=parseInt(t.substr(e,2),16),isNaN(s))throw new Error(\"String of HEX type contains invalid characters\");for(h=(e>>>1)+f,o=h>>>2;u.length<=o;)u.push(0);u[o]|=s<<8*(c+i*(h%4))}return{value:u,binLen:4*t.length+n}}(t,r,n,o)};case\"TEXT\":return function(t,r,n){return function(t,r,n,i,e){let s,o,h,u,f,c,a,w,E=0;const l=n||[0],A=(i=i||0)>>>3;if(\"UTF8\"===r)for(a=-1===e?3:0,h=0;h<t.length;h+=1)for(s=t.charCodeAt(h),o=[],128>s?o.push(s):2048>s?(o.push(192|s>>>6),o.push(128|63&s)):55296>s||57344<=s?o.push(224|s>>>12,128|s>>>6&63,128|63&s):(h+=1,s=65536+((1023&s)<<10|1023&t.charCodeAt(h)),o.push(240|s>>>18,128|s>>>12&63,128|s>>>6&63,128|63&s)),u=0;u<o.length;u+=1){for(c=E+A,f=c>>>2;l.length<=f;)l.push(0);l[f]|=o[u]<<8*(a+e*(c%4)),E+=1}else for(a=-1===e?2:0,w=\"UTF16LE\"===r&&1!==e||\"UTF16LE\"!==r&&1===e,h=0;h<t.length;h+=1){for(s=t.charCodeAt(h),!0===w&&(u=255&s,s=u<<8|s>>>8),c=E+A,f=c>>>2;l.length<=f;)l.push(0);l[f]|=s<<8*(a+e*(c%4)),E+=2}return{value:l,binLen:8*E+i}}(t,s,r,n,o)};case\"B64\":return function(r,n,i){return function(r,n,i,e){let s,o,h,u,f,c,a,w=0;const E=n||[0],l=(i=i||0)>>>3,A=-1===e?3:0,p=r.indexOf(\"=\");if(-1===r.search(/^[a-zA-Z0-9=+/]+$/))throw new Error(\"Invalid character in base-64 string\");if(r=r.replace(/=/g,\"\"),-1!==p&&p<r.length)throw new Error(\"Invalid '=' found in base-64 string\");for(o=0;o<r.length;o+=4){for(f=r.substr(o,4),u=0,h=0;h<f.length;h+=1)s=t.indexOf(f.charAt(h)),u|=s<<18-6*h;for(h=0;h<f.length-1;h+=1){for(a=w+l,c=a>>>2;E.length<=c;)E.push(0);E[c]|=(u>>>16-8*h&255)<<8*(A+e*(a%4)),w+=1}}return{value:E,binLen:8*w+i}}(r,n,i,o)};case\"BYTES\":return function(t,r,n){return function(t,r,n,i){let e,s,o,h;const u=r||[0],f=(n=n||0)>>>3,c=-1===i?3:0;for(s=0;s<t.length;s+=1)e=t.charCodeAt(s),h=s+f,o=h>>>2,u.length<=o&&u.push(0),u[o]|=e<<8*(c+i*(h%4));return{value:u,binLen:8*t.length+n}}(t,r,n,o)};case\"ARRAYBUFFER\":try{new ArrayBuffer(0)}catch(t){throw new Error(r)}return function(t,r,n){return function(t,r,n,e){return i(new Uint8Array(t),r,n,e)}(t,r,n,o)};case\"UINT8ARRAY\":try{new Uint8Array(0)}catch(t){throw new Error(n)}return function(t,r,n){return i(t,r,n,o)};default:throw new Error(\"format must be HEX, TEXT, B64, BYTES, ARRAYBUFFER, or UINT8ARRAY\")}}function s(i,e,s,o){switch(i){case\"HEX\":return function(t){return function(t,r,n,i){const e=\"0123456789abcdef\";let s,o,h=\"\";const u=r/8,f=-1===n?3:0;for(s=0;s<u;s+=1)o=t[s>>>2]>>>8*(f+n*(s%4)),h+=e.charAt(o>>>4&15)+e.charAt(15&o);return i.outputUpper?h.toUpperCase():h}(t,e,s,o)};case\"B64\":return function(r){return function(r,n,i,e){let s,o,h,u,f,c=\"\";const a=n/8,w=-1===i?3:0;for(s=0;s<a;s+=3)for(u=s+1<a?r[s+1>>>2]:0,f=s+2<a?r[s+2>>>2]:0,h=(r[s>>>2]>>>8*(w+i*(s%4))&255)<<16|(u>>>8*(w+i*((s+1)%4))&255)<<8|f>>>8*(w+i*((s+2)%4))&255,o=0;o<4;o+=1)c+=8*s+6*o<=n?t.charAt(h>>>6*(3-o)&63):e.b64Pad;return c}(r,e,s,o)};case\"BYTES\":return function(t){return function(t,r,n){let i,e,s=\"\";const o=r/8,h=-1===n?3:0;for(i=0;i<o;i+=1)e=t[i>>>2]>>>8*(h+n*(i%4))&255,s+=String.fromCharCode(e);return s}(t,e,s)};case\"ARRAYBUFFER\":try{new ArrayBuffer(0)}catch(t){throw new Error(r)}return function(t){return function(t,r,n){let i;const e=r/8,s=new ArrayBuffer(e),o=new Uint8Array(s),h=-1===n?3:0;for(i=0;i<e;i+=1)o[i]=t[i>>>2]>>>8*(h+n*(i%4))&255;return s}(t,e,s)};case\"UINT8ARRAY\":try{new Uint8Array(0)}catch(t){throw new Error(n)}return function(t){return function(t,r,n){let i;const e=r/8,s=-1===n?3:0,o=new Uint8Array(e);for(i=0;i<e;i+=1)o[i]=t[i>>>2]>>>8*(s+n*(i%4))&255;return o}(t,e,s)};default:throw new Error(\"format must be HEX, B64, BYTES, ARRAYBUFFER, or UINT8ARRAY\")}}const o=[1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298],h=[3238371032,914150663,812702999,4144912697,4290775857,1750603025,1694076839,3204075428],u=[1779033703,3144134277,1013904242,2773480762,1359893119,2600822924,528734635,1541459225];function f(t){const r={outputUpper:!1,b64Pad:\"=\",outputLen:-1},n=t||{},i=\"Output length must be a multiple of 8\";if(r.outputUpper=n.outputUpper||!1,n.b64Pad&&(r.b64Pad=n.b64Pad),n.outputLen){if(n.outputLen%8!=0)throw new Error(i);r.outputLen=n.outputLen}else if(n.shakeLen){if(n.shakeLen%8!=0)throw new Error(i);r.outputLen=n.shakeLen}if(\"boolean\"!=typeof r.outputUpper)throw new Error(\"Invalid outputUpper formatting option\");if(\"string\"!=typeof r.b64Pad)throw new Error(\"Invalid b64Pad formatting option\");return r}class c{constructor(t,r,n){const i=n||{};if(this.t=r,this.i=i.encoding||\"UTF8\",this.numRounds=i.numRounds||1,isNaN(this.numRounds)||this.numRounds!==parseInt(this.numRounds,10)||1>this.numRounds)throw new Error(\"numRounds must a integer >= 1\");this.o=t,this.h=[],this.u=0,this.l=!1,this.A=0,this.p=!1,this.U=[],this.R=[]}update(t){let r,n=0;const i=this.T>>>5,e=this.F(t,this.h,this.u),s=e.binLen,o=e.value,h=s>>>5;for(r=0;r<h;r+=i)n+this.T<=s&&(this.m=this.g(o.slice(r,r+i),this.m),n+=this.T);return this.A+=n,this.h=o.slice(n>>>5),this.u=s%this.T,this.l=!0,this}getHash(t,r){let n,i,e=this.H;const o=f(r);if(this.B){if(-1===o.outputLen)throw new Error(\"Output length must be specified in options\");e=o.outputLen}const h=s(t,e,this.v,o);if(this.p&&this.C)return h(this.C(o));for(i=this.Y(this.h.slice(),this.u,this.A,this.S(this.m),e),n=1;n<this.numRounds;n+=1)this.B&&e%32!=0&&(i[i.length-1]&=16777215>>>24-e%32),i=this.Y(i,e,0,this.I(this.o),e);return h(i)}setHMACKey(t,r,n){if(!this.L)throw new Error(\"Variant does not support HMAC\");if(this.l)throw new Error(\"Cannot set MAC key after calling update\");const i=e(r,(n||{}).encoding||\"UTF8\",this.v);this.M(i(t))}M(t){const r=this.T>>>3,n=r/4-1;let i;if(1!==this.numRounds)throw new Error(\"Cannot set numRounds with MAC\");if(this.p)throw new Error(\"MAC key already set\");for(r<t.binLen/8&&(t.value=this.Y(t.value,t.binLen,0,this.I(this.o),this.H));t.value.length<=n;)t.value.push(0);for(i=0;i<=n;i+=1)this.U[i]=909522486^t.value[i],this.R[i]=1549556828^t.value[i];this.m=this.g(this.U,this.m),this.A=this.T,this.p=!0}getHMAC(t,r){const n=f(r);return s(t,this.H,this.v,n)(this.N())}N(){let t;if(!this.p)throw new Error(\"Cannot call getHMAC without first setting MAC key\");const r=this.Y(this.h.slice(),this.u,this.A,this.S(this.m),this.H);return t=this.g(this.R,this.I(this.o)),t=this.Y(r,this.H,this.T,t,this.H),t}}function a(t,r){return t>>>r|t<<32-r}function w(t,r){return t>>>r}function E(t,r,n){return t&r^~t&n}function l(t,r,n){return t&r^t&n^r&n}function A(t){return a(t,2)^a(t,13)^a(t,22)}function p(t,r){const n=(65535&t)+(65535&r);return(65535&(t>>>16)+(r>>>16)+(n>>>16))<<16|65535&n}function U(t,r,n,i){const e=(65535&t)+(65535&r)+(65535&n)+(65535&i);return(65535&(t>>>16)+(r>>>16)+(n>>>16)+(i>>>16)+(e>>>16))<<16|65535&e}function d(t,r,n,i,e){const s=(65535&t)+(65535&r)+(65535&n)+(65535&i)+(65535&e);return(65535&(t>>>16)+(r>>>16)+(n>>>16)+(i>>>16)+(e>>>16)+(s>>>16))<<16|65535&s}function R(t){return a(t,7)^a(t,18)^w(t,3)}function y(t){return a(t,6)^a(t,11)^a(t,25)}function T(t){let r;return r=\"SHA-224\"==t?h.slice():u.slice(),r}function F(t,r){let n,i,e,s,h,u,f,c,T,F,b;const m=[];for(n=r[0],i=r[1],e=r[2],s=r[3],h=r[4],u=r[5],f=r[6],c=r[7],b=0;b<64;b+=1)m[b]=b<16?t[b]:U(a(g=m[b-2],17)^a(g,19)^w(g,10),m[b-7],R(m[b-15]),m[b-16]),T=d(c,y(h),E(h,u,f),o[b],m[b]),F=p(A(n),l(n,i,e)),c=f,f=u,u=h,h=p(s,T),s=e,e=i,i=n,n=p(T,F);var g;return r[0]=p(n,r[0]),r[1]=p(i,r[1]),r[2]=p(e,r[2]),r[3]=p(s,r[3]),r[4]=p(h,r[4]),r[5]=p(u,r[5]),r[6]=p(f,r[6]),r[7]=p(c,r[7]),r}class b extends c{constructor(t,r,n){if(\"SHA-224\"!==t&&\"SHA-256\"!==t)throw new Error(\"Chosen SHA variant is not supported\");super(t,r,n);const i=n||{};this.C=this.N,this.L=!0,this.v=-1,this.F=e(this.t,this.i,this.v),this.g=F,this.S=function(t){return t.slice()},this.I=T,this.Y=function(r,n,i,e){return function(t,r,n,i,e){let s,o;const h=15+(r+65>>>9<<4),u=r+n;for(;t.length<=h;)t.push(0);for(t[r>>>5]|=128<<24-r%32,t[h]=4294967295&u,t[h-1]=u/4294967296|0,s=0;s<t.length;s+=16)i=F(t.slice(s,s+16),i);return o=\"SHA-224\"===e?[i[0],i[1],i[2],i[3],i[4],i[5],i[6]]:i,o}(r,n,i,e,t)},this.m=T(t),this.T=512,this.H=\"SHA-224\"===t?224:256,this.B=!1,i.hmacKey&&this.M(function(t,r,n,i){const s=t+\" must include a value and format\";if(!r){if(!i)throw new Error(s);return i}if(void 0===r.value||!r.format)throw new Error(s);return e(r.format,r.encoding||\"UTF8\",n)(r.value)}(\"hmacKey\",i.hmacKey,this.v))}}export{b as default};\n","import { Albums } from './albums';\r\nimport { Artists } from './artists';\r\nimport { Auth } from './auth';\r\nimport { Bookmarks } from './bookmarks';\r\nimport { Catalogs } from './catalogs';\r\nimport { Genres } from './genres';\r\nimport { Labels } from './labels';\r\nimport { Licenses } from './licenses';\r\nimport { LiveStreams } from './live-streams';\r\nimport { Playlists } from './playlists';\r\nimport { Podcasts } from './podcasts';\r\nimport { Preferences } from './preferences';\r\nimport { Shares } from './shares';\r\nimport { Shouts } from './shouts';\r\nimport { Songs } from './songs';\r\nimport { System } from './system';\r\nimport { Users } from './users';\r\nimport { Videos } from './videos';\r\nimport { applyMixins } from './utils';\r\nimport { Base } from './base';\r\n\r\nclass AmpacheAPI extends Base {}\r\ninterface AmpacheAPI extends Albums, Artists, Auth, Bookmarks, Catalogs, Genres, Labels, Licenses, LiveStreams, Playlists, Podcasts, Preferences, Shares, Shouts, Songs, System, Users, Videos {}\r\napplyMixins(AmpacheAPI, [Albums, Artists, Auth, Bookmarks, Catalogs, Genres, Labels, Licenses, LiveStreams, Playlists, Podcasts, Preferences, Shares, Shouts, Songs, System, Users, Videos]);\r\n\r\nexport default AmpacheAPI\r\n","import JsSHA from \"jssha/dist/sha256\";\r\n\r\nexport function applyMixins(derivedCtor: any, baseCtors: any[]) {\r\n baseCtors.forEach(baseCtor => {\r\n Object.getOwnPropertyNames(baseCtor.prototype).forEach(name => {\r\n Object.defineProperty(\r\n derivedCtor.prototype,\r\n name,\r\n Object.getOwnPropertyDescriptor(baseCtor.prototype, name)\r\n );\r\n });\r\n });\r\n}\r\n\r\nexport function encryptPassword(password: string, time: number) {\r\n let key = getSHA256(password);\r\n return getSHA256(time + key);\r\n\r\n function getSHA256(text) {\r\n let shaObj = new JsSHA(\"SHA-256\", \"TEXT\", { encoding: \"UTF8\" });\r\n shaObj.update(text);\r\n\r\n return shaObj.getHash(\"HEX\");\r\n }\r\n}\r\n","import qs from 'querystringify';\r\nimport { Album } from './types';\r\nimport { Base, BinaryBoolean, Pagination, UID } from '../base';\r\n\r\nexport class Albums extends Base {\r\n /**\r\n * This returns albums based on the provided search filters\r\n * @remarks MINIMUM_API_VERSION=380001\r\n * @param [params.filter] UID to find\r\n * @param [params.exact] 0, 1 (if true filter is exact = rather than fuzzy LIKE)\r\n * @param [params.add] ISO 8601 Date Format (2020-09-16) Find objects with an 'add' date newer than the specified date\r\n * @param [params.update] ISO 8601 Date Format (2020-09-16) Find objects with an 'update' time newer than the specified date\r\n * @param [params.include] albums, songs (include child objects in the response)\r\n * @param [params.offset]\r\n * @param [params.limit]\r\n * @see {@link https://ampache.org/api/api-json-methods#albums}\r\n */\r\n async albums (params?: {\r\n filter?: number,\r\n exact?: BinaryBoolean,\r\n add?: Date,\r\n update?: Date,\r\n include?: \"albums\" | \"songs\",\r\n } & Pagination) {\r\n let query = 'albums';\r\n query += qs.stringify(params, '&');\r\n let data = await this.request<{album: Album[]}>(query);\r\n return (data.album) ? data.album : data;\r\n }\r\n\r\n /**\r\n * This returns a single album based on the UID provided\r\n * @remarks MINIMUM_API_VERSION=380001\r\n * @param params.filter UID to find\r\n * @param [params.include] songs (include child objects in the response)\r\n * @see {@link https://ampache.org/api/api-json-methods#album}\r\n */\r\n album (params: {\r\n filter: UID,\r\n include?: 'songs'\r\n }) {\r\n let query = 'album';\r\n query += qs.stringify(params, '&');\r\n return this.request<Album>(query);\r\n }\r\n\r\n /**\r\n * This returns the albums of an artist\r\n * @remarks MINIMUM_API_VERSION=380001\r\n * @param params.filter UID to find\r\n * @param [params.offset]\r\n * @param [params.limit]\r\n * @see {@link https://ampache.org/api/api-json-methods#artist_albums}\r\n */\r\n async artistAlbums (params: {\r\n filter: UID\r\n } & Pagination) {\r\n let query = 'artist_albums';\r\n query += qs.stringify(params, '&');\r\n let data = await this.request<{album: Album[]}>(query);\r\n return (data.album) ? data.album : data;\r\n }\r\n\r\n /**\r\n * This returns the albums associated with the genre in question\r\n * @remarks MINIMUM_API_VERSION=380001\r\n * @param params.filter UID to find\r\n * @param [params.offset]\r\n * @param [params.limit]\r\n * @see {@link https://ampache.org/api/api-json-methods#genre_albums}\r\n */\r\n async genreAlbums (params?: {\r\n filter: UID\r\n } & Pagination) {\r\n let query = 'genre_albums';\r\n query += qs.stringify(params, '&');\r\n let data = await this.request<{album: Album[]}>(query);\r\n return (data.album) ? data.album : data;\r\n }\r\n}\r\n","import qs from 'querystringify';\r\nimport { Artist } from './types';\r\nimport { Base, BinaryBoolean, Pagination, UID } from '../base';\r\n\r\nexport class Artists extends Base {\r\n /**\r\n * This takes a collection of inputs and returns artist objects\r\n * @remarks MINIMUM_API_VERSION=380001\r\n * @param [params.filter] Filter results to match this string\r\n * @param [params.exact] 0, 1 (if true filter is exact = rather than fuzzy LIKE)\r\n * @param [params.add] ISO 8601 Date Format (2020-09-16) Find objects with an 'add' date newer than the specified date\r\n * @param [params.update] ISO 8601 Date Format (2020-09-16) Find objects with an 'update' time newer than the specified date\r\n * @param [params.include] (albums | songs) include child objects in the response\r\n * @param [params.album_artist] 0, 1 (if true filter for album artists only)\r\n * @param [params.offset]\r\n * @param [params.limit]\r\n * @see {@link https://ampache.org/api/api-json-methods#artists}\r\n */\r\n async artists (params?: {\r\n filter?: string,\r\n exact?: BinaryBoolean,\r\n add?: Date,\r\n update?: Date,\r\n include?: 'albums' | 'songs',\r\n album_artist?: BinaryBoolean,\r\n } & Pagination) {\r\n let query = 'artists';\r\n query += qs.stringify(params, '&');\r\n let data = await this.request<{artist: Artist[]}>(query);\r\n return (data.artist) ? data.artist : data;\r\n }\r\n\r\n /**\r\n * This returns a single artist based on the UID of said artist\r\n * @remarks MINIMUM_API_VERSION=380001\r\n * @param params.filter UID to find\r\n * @param [params.include] (albums | songs) include child objects in the response\r\n * @see {@link https://ampache.org/api/api-json-methods#artist}\r\n */\r\n artist (params: {\r\n filter: UID,\r\n include?: 'albums' | 'songs',\r\n }) {\r\n let query = 'artist';\r\n query += qs.stringify(params, '&');\r\n return this.request<Artist>(query);\r\n }\r\n\r\n /**\r\n * This returns the artists associated with the genre in question as defined by the UID\r\n * @remarks MINIMUM_API_VERSION=380001\r\n * @param params.filter UID to find\r\n * @param [params.offset]\r\n * @param [params.limit]\r\n * @see {@link https://ampache.org/api/api-json-methods#genre_artists}\r\n */\r\n async genreArtists (params: {\r\n filter: UID\r\n } & Pagination) {\r\n let query = 'genre_artists';\r\n query += qs.stringify(params, '&');\r\n let data = await this.request<{artist: Artist[]}>(query);\r\n return (data.artist) ? data.artist : data;\r\n }\r\n\r\n /**\r\n * This returns the artists associated with the label in question as defined by the UID\r\n * @remarks MINIMUM_API_VERSION=420000\r\n * @param params.filter UID of find\r\n * @param [params.offset]\r\n * @param [params.limit]\r\n * @see {@link https://ampache.org/api/api-json-methods#label_artists}\r\n */\r\n async labelArtists (params: {\r\n filter: UID\r\n } & Pagination) {\r\n let query = 'label_artists';\r\n query += qs.stringify(params, '&');\r\n let data = await this.request<{artist: Artist[]}>(query);\r\n return (data.artist) ? data.artist : data;\r\n }\r\n}","import JsSHA from \"jssha/dist/sha256\";\r\nimport qs from 'querystringify';\r\nimport fetch from \"isomorphic-unfetch\";\r\nimport { Base, Success } from \"../base\";\r\nimport { AuthResponse } from './types'\r\n\r\nexport class Auth extends Base {\r\n /**\r\n * Handles verifying a new handshake\r\n * @remarks MINIMUM_API_VERSION=380001\r\n * @param params.auth encrypted apikey OR password if using password auth\r\n * @param [params.user] username\r\n * @param [params.timestamp] UNIXTIME()\r\n * @param [params.version] version of Ampache API to establish connection with\r\n * @see {@link https://ampache.org/api/api-json-methods#handshake}\r\n */\r\n handshake (params: {\r\n auth: string,\r\n user?: string,\r\n timestamp?: number,\r\n version?: string\r\n }) {\r\n // generate a timestamp if one wasn't provided\r\n if (!params.timestamp) {\r\n params.timestamp = Math.floor(new Date().getTime() / 1000);\r\n }\r\n\r\n // override the fallback API version with specified\r\n if (params.version) {\r\n this.version = params.version;\r\n }\r\n\r\n // drop timestamp if no user provided (i.e. logging in with API key)\r\n if (!params.user) {\r\n delete params.timestamp;\r\n }\r\n\r\n let query = this.url + \"/server/json.server.php?action=handshake\";\r\n query += qs.stringify(params, '&');\r\n\r\n return fetch(query)\r\n .then(response => response.json())\r\n .then(data => {\r\n if (data.auth) {\r\n this.sessionKey = data.auth;\r\n }\r\n return <AuthResponse>data;\r\n })\r\n }\r\n\r\n /**\r\n * This can be called without being authenticated, it is useful for determining if what the status\r\n * of the server is, and what version it is running/compatible with\r\n * @remarks MINIMUM_API_VERSION=380001\r\n * @param [params.auth] (Session ID) returns version information and extends the session if passed\r\n * @param [params.version] API Version that the application understands\r\n * @see {@link https://ampache.org/api/api-json-methods#ping}\r\n */\r\n ping (params?: { auth?: string, version?: string }) {\r\n let query = 'ping';\r\n query += qs.stringify(params, '&');\r\n return this.request<AuthResponse>(query, false);\r\n }\r\n\r\n /**\r\n * Destroy a session using the session auth parameter\r\n * @remarks MINIMUM_API_VERSION=400001\r\n * @param params.auth Session ID to destroy\r\n * @see {@link https://ampache.org/api/api-json-methods#goodbye}\r\n */\r\n goodbye (params: { auth }) {\r\n let query = 'goodbye';\r\n query += qs.stringify(params, '&');\r\n return this.request<Success>(query, false);\r\n }\r\n\r\n /**\r\n * Encrypt your password into the accepted format.\r\n */\r\n encryptPassword (params: { password: string, time: number }) {\r\n let key = getSHA256(params.password);\r\n return getSHA256(params.time + key);\r\n\r\n function getSHA256(text) {\r\n let shaObj = new JsSHA(\"SHA-256\", \"TEXT\", { encoding: \"UTF8\" });\r\n shaObj.update(text);\r\n\r\n return shaObj.getHash(\"HEX\");\r\n }\r\n }\r\n}","import qs from 'querystringify';\r\nimport { Bookmark } from './types';\r\nimport { Base, Success, UID } from '../base';\r\n\r\nexport class Bookmarks extends Base {\r\n /**\r\n * Get information about bookmarked media this user is allowed to manage\r\n * @remarks MINIMUM_API_VERSION=5.0.0\r\n * @see {@link https://ampache.org/api/api-json-methods#bookmarks}\r\n */\r\n async bookmarks () {\r\n let query = 'bookmarks';\r\n let data = await this.request<{bookmark: Bookmark[]}>(query);\r\n return (data.bookmark) ? data.bookmark : data;\r\n }\r\n\r\n /**\r\n * Get the bookmark from it's object_id and object_type.\r\n * @remarks MINIMUM_API_VERSION=5.0.0\r\n * @param params.filter UID to find\r\n * @param params.type Object type\r\n * @see {@link https://ampache.org/api/api-json-methods#get_bookmark}\r\n */\r\n getBookmark (params: {\r\n filter: UID,\r\n type: 'song' | 'video' | 'podcast_episode',\r\n }) {\r\n let query = 'get_bookmark';\r\n query += qs.stringify(params, '&');\r\n return this.request<Bookmark>(query);\r\n }\r\n\r\n /**\r\n * Create a placeholder for the current media that you can return to later.\r\n * @remarks MINIMUM_API_VERSION=5.0.0\r\n * @param params.filter UID to find\r\n * @param params.type Object type\r\n * @param params.position current track time in seconds\r\n * @param [params.client] Agent string. (Default: 'AmpacheAPI')\r\n * @param [params.date] update time (Default: UNIXTIME())\r\n * @see {@link https://ampache.org/api/api-json-methods#bookmark_create}\r\n */\r\n bookmarkCreate (params: {\r\n filter: UID,\r\n type: 'song' | 'video' | 'podcast_episode',\r\n position: number,\r\n client?: string,\r\n date?: number,\r\n }) {\r\n let query = 'bookmark_create';\r\n query += qs.stringify(params, '&');\r\n return this.request<Bookmark>(query);\r\n }\r\n\r\n /**\r\n * Edit a placeholder for the current media that you can return to later.\r\n * @remarks MINIMUM_API_VERSION=5.0.0\r\n * @param params.filter UID to find\r\n * @param params.type Object type\r\n * @param params.position current track time in seconds\r\n * @param [params.client] Agent string. (Default: 'AmpacheAPI')\r\n * @param [params.date] update time (Default: UNIXTIME())\r\n * @see {@link https://ampache.org/api/api-json-methods#bookmark_edit}\r\n */\r\n bookmarkEdit (params: {\r\n filter: UID,\r\n type: 'song' | 'video' | 'podcast_episode',\r\n position: number,\r\n client?: string,\r\n date?: number,\r\n }) {\r\n let query = 'bookmark_edit';\r\n query += qs.stringify(params, '&');\r\n return this.request<Bookmark>(query);\r\n }\r\n\r\n /**\r\n * Delete an existing bookmark. (if it exists)\r\n * @remarks MINIMUM_API_VERSION=5.0.0\r\n * @param params.filter UID to find\r\n * @param params.type Object type\r\n * @param [params.client] Agent string. (Default: 'AmpacheAPI')\r\n @see {@link https://ampache.org/api/api-json-methods#bookmark_delete}\r\n */\r\n bookmarkDelete (params: {\r\n filter: UID,\r\n type: 'song' | 'video' | 'podcast_episode',\r\n client?: string,\r\n }) {\r\n let query = 'bookmark_delete';\r\n query += qs.stringify(params, '&');\r\n return this.request<Success>(query);\r\n }\r\n}","import qs from 'querystringify';\r\nimport { Catalog } from './types';\r\nimport { Base, Success, UID } from '../base';\r\n\r\nexport class Catalogs extends Base {\r\n /**\r\n * This searches the catalogs and returns... catalogs\r\n * @remarks MINIMUM_API_VERSION=420000\r\n * @param [params.filter] Catalog type\r\n * @see {@link https://ampache.org/api/api-json-methods#catalogs}\r\n */\r\n async catalogs (params?: {\r\n filter?: 'music' | 'clip' | 'tvshow' | 'movie' | 'personal_video' | 'podcast',\r\n }) {\r\n let query = 'catalogs';\r\n query += qs.stringify(params, '&');\r\n let data = await this.request<{catalog: Catalog[]}>(query);\r\n return (data.catalog) ? data.catalog : data;\r\n }\r\n\r\n /**\r\n * Return catalog by UID\r\n * @remarks MINIMUM_API_VERSION=420000\r\n * @param params.filter UID to find\r\n * @see {@link https://ampache.org/api/api-json-methods#catalog}\r\n */\r\n catalog (params: {\r\n filter: UID,\r\n }) {\r\n let query = 'catalog';\r\n query += qs.stringify(params, '&');\r\n return this.request<Catalog>(query);\r\n }\r\n\r\n /**\r\n * Kick off a catalog update or clean for the selected catalog\r\n * ACCESS REQUIRED: 75 (Catalog Manager)\r\n * @remarks MINIMUM_API_VERSION=400001\r\n * @param params.task add_to_catalog, clean_catalog\r\n * @param params.catalog UID of catalog\r\n * @see {@link https://ampache.org/api/api-json-methods#catalog_action}\r\n */\r\n catalogAction(params: {\r\n task: 'add_to_catalog' | 'clean_catalog',\r\n catalog: UID,\r\n }) {\r\n let query = 'catalog_action';\r\n query += qs.stringify(params, '&');\r\n return this.request<Success>(query);\r\n }\r\n\r\n /**\r\n * Perform actions on local catalog files. Single file versions of catalog add, clean, verify and remove (delete).\r\n * Make sure you remember to urlencode those file names!\r\n * ACCESS REQUIRED: 50 (Content Manager)\r\n * @remarks MINIMUM_API_VERSION=420000\r\n * @param params.file FULL path to local file\r\n * @param params.task add, clean, verify, remove, (can include comma-separated values)\r\n * @param params.catalog UID of catalog\r\n * @see {@link https://ampache.org/api/api-json-methods#catalog_file}\r\n */\r\n catalogFile(params: {\r\n file: string,\r\n task: string,\r\n catalog: UID,\r\n }) {\r\n let query = 'catalog_file';\r\n query += qs.stringify(params, '&');\r\n return this.request<Success>(query);\r\n }\r\n\r\n /**\r\n * Create a new catalog.\r\n * ACCESS REQUIRED: 75 (Catalog Manager)\r\n * @remarks MINIMUM_API_VERSION=6.0.0\r\n * @param params.name Name for the catalog\r\n * @param params.path URL or folder path for your catalog\r\n * @param [params.type] Default: 'local'\r\n * @param [params.media_type] Default: 'music'\r\n * @param [params.file_pattern] Pattern used identify tags from the file name. Default: '%T - %t'\r\n * @param [params.folder_pattern] Pattern used identify tags from the folder name. Default: '%a/%A'\r\n * @param [params.username] login to remote catalog\r\n * @param [params.password] password to remote catalog\r\n * @see {@link https://ampache.org/api/api-json-methods#catalog_add}\r\n */\r\n catalogAdd(params: {\r\n name: string,\r\n path: string,\r\n type?: 'local' | 'beets' | 'remote' | 'subsonic' | 'seafile' | 'beetsremote',\r\n media_type?: 'music' | 'podcast' | 'clip' | 'tvshow' | 'movie' | 'personal_video',\r\n file_pattern?: string,\r\n folder_pattern?: string,\r\n username?: string,\r\n password?: string,\r\n }) {\r\n let query = 'catalog_add';\r\n query += qs.stringify(params, '&');\r\n return this.request<Catalog>(query);\r\n }\r\n\r\n /**\r\n * Delete an existing catalog. (if it exists)\r\n * ACCESS REQUIRED: 75 (Catalog Manager)\r\n * @remarks MINIMUM_API_VERSION=6.0.0\r\n * @param params.filter ID of the catalog\r\n * @see {@link https://ampache.org/api/api-json-methods#catalog_delete}\r\n */\r\n catalogDelete(params: {\r\n filter: UID,\r\n }) {\r\n let query = 'catalog_delete';\r\n query += qs.stringify(params, '&');\r\n return this.request<Success>(query);\r\n }\r\n}","import qs from 'querystringify';\r\nimport { Genre } from './types';\r\nimport { Base, BinaryBoolean, Pagination, UID } from '../base';\r\n\r\nexport class Genres extends Base {\r\n /**\r\n * This returns the genres (Tags) based on the specified filter\r\n * @remarks MINIMUM_API_VERSION=380001\r\n * @param [params.filter] UID to find\r\n * @param [params.exact] 0, 1 (if true filter is exact = rather than fuzzy LIKE)\r\n * @param [params.offset]\r\n * @param [params.limit]\r\n * @see {@link https://ampache.org/api/api-json-methods#genres}\r\n */\r\n async genres (params?: {\r\n filter?: string,\r\n exact?: BinaryBoolean,\r\n } & Pagination) {\r\n let query = 'genres';\r\n query += qs.stringify(params, '&');\r\n let data = await this.request<{genre: Genre[]}>(query);\r\n return (data.genre) ? data.genre : data;\r\n }\r\n\r\n /**\r\n * This returns a single genre based on UID\r\n * @remarks MINIMUM_API_VERSION=380001\r\n * @param params.filter UID to find\r\n * @see {@link https://ampache.org/api/api-json-methods#genre}\r\n */\r\n async genre (params: {\r\n filter: UID,\r\n }) {\r\n let query = 'genre';\r\n query += qs.stringify(params, '&');\r\n return this.request<Genre>(query);\r\n }\r\n}","import qs from 'querystringify';\r\nimport { Label } from './types';\r\nimport { Base, BinaryBoolean, Pagination, UID } from '../base';\r\n\r\nexport class Labels extends Base {\r\n /**\r\n * This returns labels based on the specified filter\r\n * @remarks MINIMUM_API_VERSION=420000\r\n * @param [params.filter] Filter results to match this string\r\n * @param [params.exact] 0, 1 (if true filter is exact = rather than fuzzy LIKE)\r\n * @param [params.add] ISO 8601 Date Format (2020-09-16) Find objects with an 'add' date newer than the specified date\r\n * @param [params.update] ISO 8601 Date Format (2020-09-16) Find objects with an 'update' time newer than the specified date\r\n * @param [params.offset]\r\n * @param [params.limit]\r\n * @see {@link https://ampache.org/api/api-json-methods#labels}\r\n */\r\n async labels (params?: {\r\n filter?: string,\r\n exact?: BinaryBoolean,\r\n add?: Date,\r\n update?: Date,\r\n } & Pagination) {\r\n let query = 'labels';\r\n query += qs.stringify(params, '&');\r\n let data = await this.request<{label: Label[]}>(query);\r\n return (data.label) ? data.label : data;\r\n }\r\n\r\n /**\r\n * This returns a single label\r\n * @remarks MINIMUM_API_VERSION=420000\r\n * @param params.filter UID to find\r\n * @see {@link https://ampache.org/api/api-json-methods#label}\r\n */\r\n label (params: {\r\n filter: UID,\r\n }) {\r\n let query = 'label';\r\n query += qs.stringify(params, '&');\r\n return this.request<Label>(query);\r\n }\r\n}","import qs from 'querystringify';\r\nimport { License } from './types';\r\nimport { Base, BinaryBoolean, Pagination, UID } from '../base';\r\n\r\nexport class Licenses extends Base {\r\n /**\r\n * This returns licenses based on the specified filter\r\n * @remarks MINIMUM_API_VERSION=420000\r\n * @param [params.filter] Filter results to match this string\r\n * @param [params.exact] 0, 1 (if true filter is exact = rather than fuzzy LIKE)\r\n * @param [params.add] ISO 8601 Date Format (2020-09-16) Find objects with an 'add' date newer than the specified date\r\n * @param [params.update] ISO 8601 Date Format (2020-09-16) Find objects with an 'update' time newer than the specified date\r\n * @param [params.offset]\r\n * @param [params.limit]\r\n * @see {@link https://ampache.org/api/api-json-methods#licenses}\r\n */\r\n async licenses (params?: {\r\n filter?: string,\r\n exact?: BinaryBoolean,\r\n add?: Date,\r\n update?: Date,\r\n } & Pagination) {\r\n let query = 'licenses';\r\n query += qs.stringify(params, '&');\r\n let data = await this.request<{license: License[]}>(query);\r\n return (data.license) ? data.license : data;\r\n }\r\n\r\n /**\r\n * This returns a single license\r\n * @remarks MINIMUM_API_VERSION=420000\r\n * @param params.filter UID to find\r\n * @see {@link https://ampache.org/api/api-json-methods#license}\r\n */\r\n license (params: {\r\n filter: UID,\r\n }) {\r\n let query = 'license';\r\n query += qs.stringify(params, '&');\r\n return this.request<License>(query);\r\n }\r\n}","import qs from 'querystringify';\r\nimport { LiveStream } from './types';\r\nimport { Base, BinaryBoolean, Pagination, Success, UID } from '../base';\r\n\r\nexport class LiveStreams extends Base {\r\n /**\r\n * This returns live_streams based on the specified filter\r\n * @remarks MINIMUM_API_VERSION=5.1.0\r\n * @param [params.filter] Filter results to match this string\r\n * @param [params.exact] 0, 1 (if true filter is exact = rather than fuzzy LIKE)\r\n * @param [params.add] ISO 8601 Date Format (2020-09-16) Find objects with an 'add' date newer than the specified date\r\n * @param [params.update] ISO 8601 Date Format (2020-09-16) Find objects with an 'update' time newer than the specified date\r\n * @param [params.offset]\r\n * @param [params.limit]\r\n * @see {@link https://ampache.org/api/api-json-methods#live_streams}\r\n */\r\n async liveStreams (params?: {\r\n filter?: string,\r\n exact?: BinaryBoolean,\r\n add?: Date,\r\n update?: Date,\r\n } & Pagination) {\r\n let query = 'live_streams';\r\n query += qs.stringify(params, '&');\r\n let data = await this.request<{live_stream: LiveStream[]}>(query);\r\n return (data.live_stream) ? data.live_stream : data;\r\n }\r\n\r\n /**\r\n * This returns a single live_stream\r\n * @remarks MINIMUM_API_VERSION=5.1.0\r\n * @param params.filter UID to find\r\n * @see {@link https://ampache.org/api/api-json-methods#live_stream}\r\n */\r\n liveStream (params: {\r\n filter: UID,\r\n }) {\r\n let query = 'live_stream';\r\n query += qs.stringify(params, '&');\r\n return this.request<LiveStream>(query);\r\n }\r\n\r\n /**\r\n * Create a live_stream (radio station) object.\r\n * ACCESS REQUIRED: 50 (Content Manager)\r\n * @remarks MINIMUM_API_VERSION=6.0.0\r\n * @param params.name Stream title\r\n * @param params.url URL of the http/s stream\r\n * @param params.codec Stream codec\r\n * @param params.catalog Catalog ID to associate with this stream\r\n * @param [params.site_url] Homepage URL of the stream\r\n * @see {@link https://ampache.org/api/api-json-methods#live_stream_create}\r\n */\r\n liveStreamCreate (params: {\r\n name: string,\r\n url: string,\r\n codec: 'mp3' | 'flac' | 'ogg' | 'vorbis' | 'opus' | 'aac' | 'alac',\r\n catalog: string,\r\n site_url?: string\r\n }) {\r\n let query = 'live_stream_create';\r\n query += qs.stringify(params, '&');\r\n return this.request<LiveStream>(query);\r\n }\r\n\r\n /**\r\n * Edit a live_stream (radio station) object.\r\n * ACCESS REQUIRED: 50 (Content Manager)\r\n * @remarks MINIMUM_API_VERSION=6.0.0\r\n * @param params.filter Object to find\r\n * @param [params.name] Stream title\r\n * @param [params.url] URL of the http/s stream\r\n * @param [params.codec] Stream codec\r\n * @param [params.catalog] Catalog ID to associate with this stream\r\n * @param [params.site_url] Homepage URL of the stream\r\n * @see {@link https://ampache.org/api/api-json-methods#live_stream_edit}\r\n */\r\n liveStreamEdit (params: {\r\n filter: string,\r\n name?: string,\r\n url?: string,\r\n codec?: 'mp3' | 'flac' | 'ogg' | 'vorbis' | 'opus' | 'aac' | 'alac',\r\n catalog?: string,\r\n site_url?: string\r\n }) {\r\n let query = 'live_stream_edit';\r\n query += qs.stringify(params, '&');\r\n return this.request<LiveStream>(query);\r\n }\r\n\r\n /**\r\n * Delete a live_stream (radio station) object (if it exists)\r\n * ACCESS REQUIRED: 50 (Content Manager)\r\n * @remarks MINIMUM_API_VERSION=6.0.0\r\n * @param params.filter Object to find\r\n * @see {@link https://ampache.org/api/api-json-methods#live_stream_delete}\r\n */\r\n liveStreamDelete (params: {\r\n filter: string,\r\n }) {\r\n let query = 'live_stream_delete';\r\n query += qs.stringify(params, '&');\r\n return this.request<Success>(query);\r\n }\r\n}","import qs from 'querystringify';\r\nimport { Playlist } from './types';\r\nimport { Song } from \"../songs/types\";\r\nimport { Base, BinaryBoolean, Pagination, Success, UID } from '../base';\r\n\r\nexport class Playlists extends Base {\r\n /**\r\n * This returns playlists based on the specified filter\r\n * @remarks MINIMUM_API_VERSION=380001\r\n * @param [params.filter] Filter results to match this string\r\n * @param [params.exact] 0, 1 (if true filter is exact = rather than fuzzy LIKE)\r\n * @param [params.add] ISO 8601 Date Format (2020-09-16) Find objects with an 'add' date newer than the specified date\r\n * @param [params.update] ISO 8601 Date Format (2020-09-16) Find objects with an 'update' time newer than the specified date\r\n * @param [params.hide_search] 0, 1 (if true do not include searches/smartlists in the result)\r\n * @param [params.show_dupes] 0, 1 (if true ignore 'api_hide_dupe_searches' setting)\r\n * @param [params.offset]\r\n * @param [params.limit]\r\n * @see {@link https://ampache.org/api/api-json-methods#playlists}\r\n */\r\n async playlists (params?: {\r\n filter?: string,\r\n exact?: BinaryBoolean,\r\n add?: Date,\r\n update?: Date,\r\n hide_search?: BinaryBoolean,\r\n show_dupes?: BinaryBoolean,\r\n } & Pagination) {\r\n let query = 'playlists';\r\n query += qs.stringify(params, '&');\r\n let data = await this.request<{playlist: Playlist[]}>(query);\r\n return (data.playlist) ? data.playlist : data;\r\n }\r\n\r\n /**\r\n * This returns smartlists based on the specified filter. NOTE: Filtered from Playlists() so pagination is invalid.\r\n * @remarks MINIMUM_API_VERSION=380001\r\n * @param [params.filter] Filter results to match this string\r\n * @param [params.exact] 0, 1 (if true filter is exact = rather than fuzzy LIKE)\r\n * @param [params.add] ISO 8601 Date Format (2020-09-16) Find objects with an 'add' date newer than the specified date\r\n * @param [params.update] ISO 8601 Date Format (2020-09-16) Find objects with an 'update' time newer than the specified date\r\n * @param [params.show_dupes] 0, 1 (if true ignore 'api_hide_dupe_searches' setting)\r\n * @see {@link https://ampache.org/api/api-json-methods#playlists}\r\n */\r\n async smartlists (params?: {\r\n filter?: string,\r\n exact?: BinaryBoolean,\r\n add?: Date,\r\n update?: Date,\r\n show_dupes?: BinaryBoolean,\r\n }) {\r\n let query = 'playlists';\r\n query += qs.stringify(params, '&');\r\n let data = await this.request<{playlist: Playlist[]}>(query);\r\n\r\n let results = (data.playlist) ? data.playlist : data;\r\n\r\n // filter out regular playlists\r\n if (Array.isArray(results)) {\r\n results = results.filter(function(item) {\r\n return item.id.toString().match(/^smart_/);\r\n })\r\n }\r\n\r\n return results;\r\n }\r\n\r\n /**\r\n * This returns a single playlist\r\n * @remarks MINIMUM_API_VERSION=380001\r\n * @param params.filter UID to find\r\n * @see {@link https://ampache.org/api/api-json-methods#playlist}\r\n */\r\n playlist (params: {\r\n filter: UID\r\n }) {\r\n let query = 'playlist';\r\n query += qs.stringify(params, '&');\r\n return this.request<Playlist>(query);\r\n }\r\n\r\n /**\r\n * This creates a new playlist and returns it\r\n * @remarks MINIMUM_API_VERSION=380001\r\n * @param params.name Playlist name\r\n * @param [params.type] public, private (Playlist type)\r\n * @see {@link https://ampache.org/api/api-json-methods#playlist_create}\r\n */\r\n playlistCreate (params: {\r\n name: string,\r\n type?: 'public' | 'private',\r\n }) {\r\n let query = 'playlist_create';\r\n query += qs.stringify(params, '&');\r\n return this.request<Playlist>(query);\r\n }\r\n\r\n /**\r\n * This modifies name and type of a playlist.\r\n * NOTE items and tracks must be sent together and be of equal length.\r\n * @remarks MINIMUM_API_VERSION=400001\r\n * @param params.filter UID to find\r\n * @param [params.name] Playlist name\r\n * @param [params.type] public, private (Playlist type)\r\n * @param [params.owner] Change playlist owner to the user id (-1 = System playlist)\r\n * @param [params.items] comma-separated song_id's (replaces existing items with a new id)\r\n * @param [params.tracks] comma-separated playlisttrack numbers matched to 'items' in order\r\n * @see {@link https://ampache.org/api/api-json-methods#playlist_edit}\r\n */\r\n playlistEdit (params: {\r\n filter: UID,\r\n name?: string,\r\n type?: 'public' | 'private',\r\n owner?: string,\r\n items?: string,\r\n tracks?: string,\r\n }) {\r\n let query = 'playlist_edit';\r\n query += qs.stringify(params, '&');\r\n return this.request<Success>(query);\r\n }\r\n\r\n /**\r\n * This deletes a playlist\r\n * @remarks MINIMUM_API_VERSION=380001\r\n * @param params.filter UID of playlist to delete\r\n * @see {@link https://ampache.org/api/api-json-methods#playlist_delete}\r\n */\r\n playlistDelete (params: {\r\n filter: UID,\r\n }) {\r\n let query = 'playlist_delete';\r\n query += qs.stringify(params, '&');\r\n return this.request<Success>(query);\r\n }\r\n\r\n /**\r\n * This adds a song to a playlist\r\n * @remarks MINIMUM_API_VERSION=380001; CHANGED_IN_API_VERSION=400003\r\n * @param params.filter UID of Playlist\r\n * @param params.song UID of song to add to playlist\r\n * @param [params.check] 0, 1 Whether to check and ignore duplicates (default = 0)\r\n * @see {@link https://ampache.org/api/api-json-methods#playlist_add_song}\r\n */\r\n playlistAddSong (params: {\r\n filter: UID,\r\n song: UID,\r\n check?: BinaryBoolean,\r\n }) {\r\n let query = 'playlist_add_song';\r\n query += qs.stringify(params, '&');\r\n return this.request<Success>(query);\r\n }\r\n\r\n /**\r\n * This remove a song from a playlist\r\n * @remarks MINIMUM_API_VERSION=380001; CHANGED_IN_API_VERSION=400001\r\n * @param params.filter UID of Playlist\r\n * @param [params.song] UID of song to remove from playlist\r\n * @param [params.track] Track number to remove from playlist\r\n * @see {@link https://ampache.org/api/api-json-methods#playlist_remove_song}\r\n */\r\n playlistRemoveSong (params: {\r\n filter: UID,\r\n song?: UID,\r\n track?: number,\r\n }) {\r\n let query = 'playlist_remove_song';\r\n query += qs.stringify(params, '&');\r\n return this.request<Success>(query);\r\n }\r\n\r\n /**\r\n * Get a list of song JSON, indexes or id's based on some simple search criteria\r\n * @remarks MINIMUM_API_VERSION=400001; CHANGED_IN_API_VERSION=400002; 'recent' will search for tracks played after 'Popular Threshold' days; 'forgotten' will search for tracks played before 'Popular Threshold' days; 'unplayed' added in 400002 for searching unplayed tracks\r\n * @param [params.mode] (default = 'random')\r\n * @param [params.filter] string LIKE matched to song title\r\n * @param [params.album] UID of album\r\n * @param [params.artist] UID of artist\r\n * @param [params.flag] 0, 1 (get flagged songs only. default = 0)\r\n * @param [params.format] song, index, id (default = 'song')\r\n * @param [params.offset]\r\n * @param [params.limit]\r\n * @see {@link https://ampache.org/api/api-json-methods#playlist_generate}\r\n */\r\n async playlistGenerate (params?: {\r\n mode?: 'recent' | 'forgotten' | 'unplayed' | 'random',\r\n filter?: string,\r\n album?: number,\r\n artist?: number,\r\n flag?: BinaryBoolean,\r\n format?: 'song' | 'index' | 'id',\r\n } & Pagination) {\r\n let query = 'playlist_generate';\r\n query += qs.stringify(params, '&');\r\n let data = await this.request<{song: Song[]}>(query);\r\n return (data.song) ? data.song : data;\r\n }\r\n}","import qs from 'querystringify';\r\nimport { Podcast, PodcastEpisode, DeletedPodcastEpisode } from './types';\r\nimport { Base, Pagination, Success, UID } from '../base';\r\n\r\nexport class Podcasts extends Base {\r\n /**\r\n * Get information about podcasts\r\n * @remarks MINIMUM_API_VERSION=420000\r\n * @param [params.filter] Value is Alpha Match for returned results, may be more than one letter/number\r\n * @param [params.include] episodes (include podcast_episodes in the response)\r\n * @param [params.offset]\r\n * @param [params.limit]\r\n * @see {@link https://ampache.org/api/api-json-methods#podcasts}\r\n */\r\n async podcasts (params?: {\r\n filter?: string,\r\n include?: 'episodes',\r\n } & Pagination) {\r\n let query = 'podcasts';\r\n query += qs.stringify(params, '&');\r\n let data = await this.request<{podcast: Podcast[]}>(query);\r\n return (data.podcast) ? data.podcast : data;\r\n }\r\n\r\n /**\r\n * Get information about podcasts\r\n * @remarks MINIMUM_API_VERSION=420000\r\n * @param params.filter UID to find\r\n * @param [params.include] episodes (include podcast_episodes in the response)\r\n * @param [params.offset]\r\n * @param [params.limit]\r\n * @see {@link https://ampache.org/api/api-json-methods#podcast}\r\n */\r\n async podcast (params?: {\r\n filter: UID,\r\n include?: 'episodes',\r\n } & Pagination) {\r\n let query = 'podcast';\r\n query += qs.stringify(params, '&');\r\n return this.request<Podcast>(query);\r\n }\r\n\r\n /**\r\n * Create a podcast that can be used by anyone to stream media.\r\n * @remarks MINIMUM_API_VERSION=420000\r\n * @param params.url RSS url for podcast\r\n * @param params.catalog UID of podcast catalog\r\n * @see {@link https://ampache.org/api/api-json-methods#podcast_create}\r\n */\r\n podcastCreate (params: {\r\n url: string,\r\n catalog: UID,\r\n }) {\r\n let query = 'podcast_create';\r\n query += qs.stringify(params, '&');\r\n return this.request<Podcast>(query);\r\n }\r\n\r\n /**\r\n * Update the description and/or expiration date for an existing podcast.\r\n * @remarks MINIMUM_API_VERSION=420000\r\n * @param params.filter UID to find\r\n * @param [params.feed] RSS url for podcast\r\n * @param [params.title] Podcast title\r\n * @param [params.website] Source website URL\r\n * @param [params.description] Podcast description\r\n * @param [params.generator] Podcast generator\r\n * @param [params.copyright] Podcast copyright\r\n * @see {@link https://ampache.org/api/api-json-methods#podcast_edit}\r\n */\r\n podcastEdit (params: {\r\n filter: UID,\r\n feed?: string,\r\n title?: string,\r\n website?: string,\r\n description?: string,\r\n generator?: string,\r\n copyright?: string,\r\n }) {\r\n let query = 'podcast_edit';\r\n query += qs.stringify(params, '&');\r\n return this.request<Success>(query);\r\n }\r\n\r\n /**\r\n * Delete an existing podcast\r\n * @remarks MINIMUM_API_VERSION=420000\r\n * @param params.filter UID of podcast to delete\r\n * @see {@link https://ampache.org/api/api-json-methods#podcast_delete}\r\n */\r\n podcastDelete (params: {\r\n filter: UID\r\n }) {\r\n let query = 'podcast_delete';\r\n query += qs.stringify(params, '&');\r\n return this.request<Success>(query);\r\n }\r\n\r\n /**\r\n * This returns the episodes for a podcast\r\n * @remarks MINIMUM_API_VERSION=420000\r\n * @param params.filter UID of podcast\r\n * @param [params.offset]\r\n * @param [params.limit]\r\n * @see {@link https://ampache.org/api/api-json-methods#podcast_episodes}\r\n */\r\n async podcastEpisodes (params: {\r\n filter: UID,\r\n } & Pagination) {\r\n let query = 'podcast_episodes';\r\n query += qs.stringify(params, '&');\r\n let data = await this.request<{podcast_episode: PodcastEpisode[]}>(query);\r\n return (data.podcast_episode) ? data.podcast_episode : data;\r\n }\r\n\r\n /**\r\n * Get the podcast_episode from a UID\r\n * @remarks MINIMUM_API_VERSION=420000\r\n * @param params.filter UID of podcast\r\n * @see {@link https://ampache.org/api/api-json-methods#podcast_episode}\r\n */\r\n podcastEpisode (params: {\r\n filter: UID,\r\n }) {\r\n let query = 'podcast_episode';\r\n query += qs.stringify(params, '&');\r\n return this.request<PodcastEpisode>(query);\r\n }\r\n\r\n /**\r\n * Delete an existing podcast_episode\r\n * @remarks MINIMUM_API_VERSION=420000\r\n * @param params.filter UID of podcast episode to delete\r\n * @see {@link https://ampache.org/api/api-json-methods#podcast_episode_delete}\r\n */\r\n podcastEpisodeDelete (params: {\r\n filter: UID,\r\n }) {\r\n let query = 'podcast_episode_delete';\r\n query += qs.stringify(params, '&');\r\n return this.request<Success>(query);\r\n }\r\n\r\n /**\r\n * Sync and download new podcast episodes\r\n * ACCESS REQUIRED: 50 (Content Manager)\r\n * @remarks MINIMUM_API_VERSION=420000\r\n * @param params.id UID of podcast\r\n * @see {@link https://ampache.org/api/api-json-methods#update_podcast}\r\n */\r\n updatePodcast (params: {\r\n id: UID,\r\n }) {\r\n let query = 'update_podcast';\r\n query += qs.stringify(params, '&');\r\n return this.request<Success>(query);\r\n }\r\n\r\n /**\r\n * This returns the episodes for a podcast that have been deleted\r\n * @param [params.offset]\r\n * @param [params.limit]\r\n * @see {@link https://ampache.org/api/api-json-methods#deleted_podcast_episodes}\r\n */\r\n async deletedPodcastEpisodes (params?: {\r\n\r\n } & Pagination) {\r\n let query = 'deleted_podcast_episodes';\r\n query += qs.stringify(params, '&');\r\n let data = await this.request<{deleted_podcast_episode: DeletedPodcastEpisode[]}>(query);\r\n return (data.deleted_podcast_episode) ? data.deleted_podcast_episode : data;\r\n }\r\n}","import qs from 'querystringify';\r\nimport { Base, BinaryBoolean, Success } from '../base';\r\nimport { Preference } from \"./types\";\r\n\r\nexport class Preferences extends Base {\r\n /**\r\n * Get your server preferences\r\n * ACCESS REQUIRED: 100 (Admin)\r\n * @remarks MINIMUM_API_VERSION=5.0.0\r\n * @see {@link https://ampache.org/api/api-json-methods#system_preferences}\r\n */\r\n async systemPreferences () {\r\n let query = 'system_preferences';\r\n let data = await this.request<{preference: Preference[]}>(query);\r\n return (data.preference) ? data.preference : data;\r\n }\r\n\r\n /**\r\n * Get your system preference by name\r\n * ACCESS REQUIRED: 100 (Admin)\r\n * @remarks MINIMUM_API_VERSION=5.0.0\r\n * @param params.systemPreference Preference name e.g ('notify_email', 'ajax_load')\r\n * @see {@link https://ampache.org/api/api-json-methods#system_preference}\r\n */\r\n async systemPreference (params: {\r\n filter: string,\r\n }) {\r\n let query = 'system_preference';\r\n query += qs.stringify(params, '&');\r\n let data = await this.request<{Preference}>(query);\r\n return data[0];\r\n }\r\n\r\n /**\r\n * Get your user preferences\r\n * @remarks MINIMUM_API_VERSION=5.0.0\r\n * @see {@link https://ampache.org/api/api-json-methods#user_preferences}\r\n */\r\n async userPreferences () {\r\n let query = 'user_preferences';\r\n let data = await this.request<{preference: Preference[]}>(query);\r\n return (data.preference) ? data.preference : data;\r\n }\r\n\r\n /**\r\n * Get your user preference by name\r\n * @remarks MINIMUM_API_VERSION=5.0.0\r\n * @param params.filter Preference name e.g ('notify_email', 'ajax_load')\r\n * @see {@link https://ampache.org/api/api-json-methods#user_preference}\r\n */\r\n async userPreference (params: {\r\n filter: string,\r\n }) {\r\n let query = 'user_preference';\r\n query += qs.stringify(params, '&');\r\n let data = await this.request<{Preference}>(query);\r\n return data[0];\r\n }\r\n\r\n /**\r\n * Add a new preference to your server\r\n * ACCESS REQUIRED: 100 (Admin)\r\n * @param params.filter Preference name e.g ('notify_email', 'ajax_load')\r\n * @param params.type boolean, integer, string, special\r\n * @param params.default string or integer default value\r\n * @param params.category Category type\r\n * @param [params.description]\r\n * @param [params.subcategory]\r\n * @param [params.level] access level required to change the value (default 100)\r\n * @see {@link https://ampache.org/api/api-json-methods#preference_create}\r\n */\r\n preferenceCreate(params: {\r\n filter: string,\r\n type: 'boolean' | 'integer' | 'string' | 'special',\r\n default: string | number,\r\n category: 'interface' | 'internal' | 'options' | 'playlist' | 'plugins' | 'streaming',\r\n description?: string,\r\n subcategory?: string,\r\n level?: number,\r\n }) {\r\n let query = 'preference_create';\r\n query += qs.stringify(params, '&');\r\n return this.request<Success>(query);\r\n }\r\n\r\n /**\r\n * Edit a preference value and apply to all users if allowed\r\n * ACCESS REQUIRED: 100 (Admin)\r\n * @remarks MINIMUM_API_VERSION=5.0.0\r\n * @param params.filter Preference name e.g ('notify_email', 'ajax_load')\r\n * @param params.value (string/integer) Preference value\r\n * @param [params.all] 0, 1 apply to all users\r\n * @see {@link https://ampache.org/api/api-json-methods#preference_edit}\r\n */\r\n preferenceEdit(params: {\r\n filter: string,\r\n value: string | number,\r\n all?: BinaryBoolean,\r\n }) {\r\n let query = 'preference_edit';\r\n query += qs.stringify(params, '&');\r\n return this.request<Success>(query);\r\n }\r\n\r\n /**\r\n * Delete a non-system preference by name\r\n * ACCESS REQUIRED: 100 (Admin)\r\n * @param params.filter Preference name e.g ('notify_email', 'ajax_load')\r\n * @see {@link https://ampache.org/api/api-json-methods#preference_delete}\r\n */\r\n preferenceDelete(params: {\r\n filter: string,\r\n }) {\r\n let query = 'preference_delete';\r\n query += qs.stringify(params, '&');\r\n return this.request<Success>(query);\r\n }\r\n}","import qs from 'querystringify';\r\nimport { Share } from './types';\r\nimport { Base, BinaryBoolean, Pagination, Success, UID } from '../base';\r\n\r\nexport class Shares extends Base {\r\n /**\r\n * This searches the shares and returns... shares\r\n * @remarks MINIMUM_API_VERSION=420000\r\n * @param [params.filter] UID to find\r\n * @param [params.exact] 0, 1 boolean to match the exact filter string\r\n * @param [params.offset]\r\n * @param [params.limit]\r\n * @see {@link https://ampache.org/api/api-json-methods#shares}\r\n */\r\n async shares (params?: {\r\n filter?: string,\r\n exact?: BinaryBoolean,\r\n } & Pagination) {\r\n let query = 'shares';\r\n query += qs.stringify(params, '&');\r\n let data = await this.request<{share: Share[]}>(query);\r\n return (data.share) ? data.share : data;\r\n }\r\n\r\n /**\r\n * Return a share from UID\r\n * @remarks MINIMUM_API_VERSION=420000\r\n * @param params.filter UID to find\r\n * @see {@link https://ampache.org/api/api-json-methods#share}\r\n */\r\n share (params: {\r\n filter: UID,\r\n }) {\r\n let query = 'share';\r\n query += qs.stringify(params, '&');\r\n return this.request<Share>(query);\r\n }\r\n\r\n /**\r\n * Create a public url that can be used by anyone to stream media.\r\n * @remarks MINIMUM_API_VERSION=420000\r\n * @param params.filter UID of object you are sharing\r\n * @param params.type ('song', 'album', 'artist')\r\n * @param [params.description] description (will be filled for you if empty)\r\n * @param [params.expires] days to keep active\r\n * @see {@link https://ampache.org/api/api-json-methods#share_create}\r\n */\r\n shareCreate (params: {\r\n filter: UID,\r\n type: 'song' | 'album' | 'artist',\r\n description?: string,\r\n expires?: number,\r\n }) {\r\n let query = 'share_create';\r\n query += qs.stringify(params, '&');\r\n return this.request<Share>(query);\r\n }\r\n\r\n /**\r\n * Update the description and/or expiration date for an existing share\r\n * @remarks MINIMUM_API_VERSION=420000\r\n * @param params.filter UID to find\r\n * @param [params.stream] 0, 1\r\n * @param [params.download] 0, 1\r\n * @param [params.expires] days to keep active\r\n * @param [params.description] description\r\n * @see {@link https://ampache.org/api/api-json-methods#share_edit}\r\n */\r\n shareEdit (params: {\r\n filter: UID,\r\n stream?: BinaryBoolean,\r\n download?: BinaryBoolean,\r\n expires?: number,\r\n description?: string,\r\n }) {\r\n let query = 'share_edit';\r\n query += qs.stringify(params, '&');\r\n return this.request<Success>(query);\r\n }\r\n\r\n /**\r\n * Delete an existing share.\r\n * @remarks MINIMUM_API_VERSION=420000\r\n * @param params.filter UID of share to delete\r\n * @see {@link https://ampache.org/api/api-json-methods#share_delete}\r\n */\r\n shareDelete (params: {\r\n filter: UID,\r\n }) {\r\n let query = 'share_delete';\r\n query += qs.stringify(params, '&');\r\n return this.request<Success>(query);\r\n }\r\n}","import qs from 'querystringify';\r\nimport { Shout } from './types';\r\nimport { Base } from '../base';\r\n\r\nexport class Shouts extends Base {\r\n /**\r\n * This gets the latest posted shouts\r\n * @remarks MINIMUM_API_VERSION=380001\r\n * @param [params.username] Username to find\r\n * @param [params.limit] Maximum number of results to return\r\n * @see {@link https://ampache.org/api/api-json-methods#last_shouts}\r\n */\r\n async last_shouts (params?: {\r\n username?: string,\r\n limit?: number\r\n }) {\r\n let query = 'last_shouts';\r\n query += qs.stringify(params, '&');\r\n let data = await this.request<{shout: Shout[]}>(query);\r\n return (data.shout) ? data.shout : data;\r\n }\r\n}","import qs from 'querystringify';\r\nimport { Song, DeletedSong } from './types';\r\nimport { Base, BinaryBoolean, Pagination, Success, UID } from '../base';\r\n\r\nexport class Songs extends Base {\r\n /**\r\n * Returns songs based on the specified filter\r\n * @remarks MINIMUM_API_VERSION=380001\r\n * @param [params.filter] Filter results to match this string\r\n * @param [params.exact] 0, 1 (if true filter is exact = rather than fuzzy LIKE)\r\n * @param [params.add] ISO 8601 Date Format (2020-09-16) Find objects with an 'add' date newer than the specified date\r\n * @param [params.update] ISO 8601 Date Format (2020-09-16) Find objects with an 'update' time newer than the specified date\r\n * @param [params.offset]\r\n * @param [params.limit]\r\n * @see {@link https://ampache.org/api/api-json-methods#songs}\r\n */\r\n async songs (params?: {\r\n filter?: string,\r\n exact?: BinaryBoolean,\r\n add?: Date,\r\n update?: Date,\r\n } & Pagination) {\r\n let query = 'songs';\r\n query += qs.stringify(params, '&');\r\n let data = await this.request<{song: Song[]}>(query);\r\n return (data.song) ? data.song : data;\r\n }\r\n\r\n /**\r\n * Returns a single song\r\n * @remarks MINIMUM_API_VERSION=380001\r\n * @param params.filter UID to find\r\n * @see {@link https://ampache.org/api/api-json-methods#song}\r\n */\r\n song (params: {\r\n filter: UID,\r\n }) {\r\n let query = 'song';\r\n query += qs.stringify(params, '&');\r\n return this.request<Song>(query);\r\n }\r\n\r\n /**\r\n * Songs of the specified artist\r\n * @remarks MINIMUM_API_VERSION=380001\r\n * @param params.filter UID to find\r\n * @param [params.top50] 0, 1 (if true filter to the artist top 50)\r\n * @param [params.offset]\r\n * @param [params.limit]\r\n * @see {@link https://ampache.org/api/api-json-methods#artist_songs}\r\n */\r\n async artistSongs (params: {\r\n filter: UID,\r\n top50?: BinaryBoolean,\r\n } & Pagination) {\r\n let query = 'artist_songs';\r\n query += qs.stringify(params, '&');\r\n let data = await this.request<{song: Song[]}>(query);\r\n return (data.song) ? data.song : data;\r\n }\r\n\r\n /**\r\n * Songs of the specified album\r\n * @remarks MINIMUM_API_VERSION=380001\r\n * @param params.filter UID to find\r\n * @param [params.offset]\r\n * @param [params.limit]\r\n * @see {@link https://ampache.org/api/api-json-methods#album_songs}\r\n */\r\n async albumSongs (params: {\r\n filter: UID,\r\n } & Pagination) {\r\n let query = 'album_songs';\r\n query += qs.stringify(params, '&');\r\n let data = await this.request<{song: Song[]}>(query);\r\n return (data.song) ? data.song : data;\r\n }\r\n\r\n /**\r\n * Songs of the specified genre\r\n * @remarks MINIMUM_API_VERSION=380001\r\n * @param params.filter UID to find\r\n * @param [params.offset]\r\n * @param [params.limit]\r\n * @see {@link https://ampache.org/api/api-json-methods#genre_songs}\r\n */\r\n async genreSongs (params: {\r\n filter: UID,\r\n } & Pagination) {\r\n let query = 'genre_songs';\r\n query += qs.stringify(params, '&');\r\n let data = await this.request<{song: Song[]}>(query);\r\n return (data.song) ? data.song : data;\r\n }\r\n\r\n /**\r\n * This returns the songs for a playlist\r\n * @remarks MINIMUM_API_VERSION=380001\r\n * @param params.filter UID to find\r\n * @param [params.random] 0, 1 (if true get random songs using limit)\r\n * @param [params.offset]\r\n * @param [params.limit]\r\n * @see {@link https://ampache.org/api/api-json-methods#playlist_songs}\r\n */\r\n async playlistSongs (params: {\r\n filter: UID,\r\n random?: BinaryBoolean,\r\n } & Pagination) {\r\n let query = 'playlist_songs';\r\n query += qs.stringify(params, '&');\r\n let data = await this.request<{song: Song[]}>(query);\r\n return (data.song) ? data.song : data;\r\n }\r\n\r\n /**\r\n * This returns the songs for a license\r\n * @remarks MINIMUM_API_VERSION=420000\r\n * @param params.filter UID to find\r\n * @param [params.offset]\r\n * @param [params.limit]\r\n * @see {@link https://ampache.org/api/api-json-methods#license_songs}\r\n */\r\n async licenseSongs (params: {\r\n filter: UID,\r\n } & Pagination) {\r\n let query = 'license_songs';\r\n query += qs.stringify(params, '&');\r\n let data = await this.request<{song: Song[]}>(query);\r\n return (data.song) ? data.song : data;\r\n }\r\n\r\n /**\r\n * Delete an existing song. (if you are allowed to)\r\n * @remarks MINIMUM_API_VERSION=5.0.0\r\n * @param params.filter UID of song to delete\r\n * @see {@link https://ampache.org/api/api-json-methods#song_delete}\r\n */\r\n songDelete (params: {\r\n filter: UID,\r\n }) {\r\n let query = 'song_delete';\r\n query += qs.stringify(params, '&');\r\n return this.request<Success>(query);\r\n }\r\n\r\n /**\r\n * This takes a URL and returns the song object in question\r\n * @remarks MINIMUM_API_VERSION=380001\r\n * @param params.url Full Ampache URL from server\r\n * @see {@link https://ampache.org/api/api-json-methods#url_to_song}\r\n */\r\n urlToSong (params: {\r\n url: string,\r\n }) {\r\n let query = 'url_to_song';\r\n params.url = encodeURIComponent(params.url);\r\n query += qs.stringify(params, '&');\r\n return this.request<Song>(query);\r\n }\r\n\r\n /**\r\n * This searches the songs and returns... songs\r\n * @remarks MINIMUM_API_VERSION=380001\r\n * @param params.filter Filter results to match this string\r\n * @param [params.offset]\r\n * @param [params.limit]\r\n * @see {@link https://ampache.org/api/api-json-methods#search_songs}\r\n */\r\n async searchSongs (params: {\r\n filter: string,\r\n } & Pagination) {\r\n let query = 'search_songs';\r\n query += qs.stringify(params, '&');\r\n let data = await this.request<{song: Song[]}>(query);\r\n return (data.song) ? data.song : data;\r\n }\r\n\r\n /**\r\n * Returns songs that have been deleted from the server\r\n * @remarks MINIMUM_API_VERSION=500000\r\n * @param [params.offset]\r\n * @param [params.limit]\r\n * @see {@link https://ampache.org/api/api-json-methods#deleted_songs}\r\n */\r\n async deletedSongs (params?: {\r\n\r\n } & Pagination) {\r\n let query = 'deleted_songs';\r\n query += qs.stringify(params, '&');\r\n let data = await this.request<{deleted_song: DeletedSong[]}>(query);\r\n return (data.deleted_song) ? data.deleted_song : data;\r\n }\r\n}","import qs from 'querystringify';\r\nimport { Song } from \"../songs/types\";\r\nimport { Artist } from \"../artists/types\";\r\nimport { Base, BinaryBoolean, Pagination, Success, UID } from '../base';\r\nimport { Album } from '../albums/types';\r\nimport { Video } from '../videos/types';\r\nimport { Playlist } from '../playlists/types';\r\nimport { Podcast, PodcastEpisode } from '../podcasts/types';\r\nimport { LiveStream } from \"../live-streams/types\";\r\nimport { Label } from \"../labels/types\";\r\nimport { Genre } from \"../genres/types\";\r\nimport { User } from \"../users/types\";\r\nimport { IndexEntry } from \"./types\";\r\n\r\nexport class System extends Base {\r\n /**\r\n * Check Ampache for updates and run the update if there is one.\r\n * @remarks MINIMUM_API_VERSION=5.0.0\r\n * @see {@link https://ampache.org/api/api-json-methods#system_update}\r\n */\r\n systemUpdate () {\r\n let query = 'system_update';\r\n return this.request<Success>(query);\r\n }\r\n\r\n /**\r\n * This takes a collection of inputs and returns ID + name for the object type\r\n * @remarks MINIMUM_API_VERSION=400001\r\n * @param params.type type of object to find\r\n * @param [params.filter] search the name of the object_type\r\n * @param [params.add] ISO 8601 Date Format (2020-09-16) Find objects with an 'add' date newer than the specified date\r\n * @param [params.update] ISO 8601 Date Format (2020-09-16) Find objects with an 'update' time newer than the specified date\r\n * @param [params.include] 0, 1 (include songs in a playlist or episodes in a podcast)\r\n * @param [params.hide_search] 0, 1 (if true do not include searches/smartlists in the result)\r\n * @param [params.offset]\r\n * @param [params.limit]\r\n * @see {@link https://ampache.org/api/api-json-methods#get_indexes}\r\n * @deprecated Being removed in 7.0.0. Use `list` instead.\r\n */\r\n async getIndexes (params: {\r\n type: 'song' | 'album' | 'artist' | 'album_artist' | 'playlist' | 'podcast' | 'podcast_episode' | 'live_stream',\r\n filter?: string,\r\n add?: Date,\r\n update?: Date,\r\n include?: BinaryBoolean,\r\n hide_search?: BinaryBoolean\r\n } & Pagination) {\r\n let query = 'get_indexes';\r\n query += qs.stringify(params, '&');\r\n let data;\r\n\r\n switch (params.type) {\r\n case \"song\":\r\n data = await this.request<{song: Song[]}>(query);\r\n return (data.song) ? data.song : data;\r\n case \"album\":\r\n data = await this.request<{album: Album[]}>(query);\r\n return (data.album) ? data.album : data;\r\n case \"artist\":\r\n case \"album_artist\":\r\n data = await this.request<{artist: Artist[]}>(query);\r\n return (data.artist) ? data.artist : data;\r\n case \"playlist\":\r\n data = await this.request<{playlist: Playlist[]}>(query);\r\n return (data.playlist) ? data.playlist : data;\r\n case \"podcast\":\r\n data = await this.request<{podcast: Podcast[]}>(query);\r\n return (data.podcast) ? data.podcast : data;\r\n case \"podcast_episode\":\r\n data = await this.request<{podcast_episode: PodcastEpisode[]}>(query);\r\n return (data.podcast_episode) ? data.podcast_episode : data;\r\n case \"live_stream\":\r\n data = await this.request<{live_stream: LiveStream[]}>(query);\r\n return (data.live_stream) ? data.live_stream : data;\r\n default:\r\n return false;\r\n }\r\n }\r\n\r\n /**\r\n * This takes a named array of objects and returning `id`, `name`, `prefix` and `basename`\r\n * @remarks MINIMUM_API_VERSION=6.0.0\r\n * @param params.type type of object to find\r\n * @param [params.filter] Value is Alpha Match for returned results, may be more than one letter/number\r\n * @param [params.add] ISO 8601 Date Format (2020-09-16) Find objects with an 'add' date newer than the specified date\r\n * @param [params.update] ISO 8601 Date Format (2020-09-16) Find objects with an 'update' time newer than the specified date\r\n * @param [params.hide_search] 0, 1 (if true do not include searches/smartlists in the result)\r\n * @param [params.offset]\r\n * @param [params.limit]\r\n * @see {@link https://ampache.org/api/api-json-methods#list}\r\n */\r\n async list (params: {\r\n type: 'song' | 'album' | 'artist' | 'album_artist' | 'playlist' | 'podcast' | 'podcast_episode' | 'live_stream',\r\n filter?: string,\r\n add?: Date,\r\n update?: Date,\r\n hide_search?: BinaryBoolean\r\n } & Pagination) {\r\n let query = 'list';\r\n query += qs.stringify(params, '&');\r\n return this.request<{list: IndexEntry[]}>(query);\r\n }\r\n\r\n /**\r\n * Return children of a parent object in a folder traversal/browse style\r\n * If you don't send any parameters you'll get a catalog list (the 'root' path)\r\n * @remarks MINIMUM_API_VERSION=6.0.0\r\n * @param [params.filter] object_id\r\n * @param [params.type] type of object to find\r\n * @param [params.catalog] catalog ID you are browsing (required on 'artist', 'album', 'podcast')\r\n * @param [params.add] ISO 8601 Date Format (2020-09-16) Find objects with an 'add' date newer than the specified date\r\n * @param [params.update] ISO 8601 Date Format (2020-09-16) Find objects with an 'update' time newer than the specified date\r\n * @param [params.offset]\r\n * @param [params.limit]\r\n * @see {@link https://ampache.org/api/api-json-methods#browse}\r\n */\r\n async browse (params: {\r\n filter?: UID,\r\n type?: 'root' | 'catalog' | 'artist' | 'album' | 'podcast',\r\n catalog?: number,\r\n add?: Date,\r\n update?: Date,\r\n } & Pagination) {\r\n let query = 'browse';\r\n query += qs.stringify(params, '&');\r\n return this.request<{browse: IndexEntry[]}>(query);\r\n }\r\n\r\n /**\r\n * Return similar artist IDs or similar song IDs compared to the input filter\r\n * @remarks MINIMUM_API_VERSION=420000\r\n * @param params.type type of object to check against\r\n * @param params.filter UID to find\r\n * @param [params.offset]\r\n * @param [params.limit]\r\n * @see {@link https://ampache.org/api/api-json-methods#get_similar}\r\n */\r\n async getSimilar (params: {\r\n type: 'song' | 'artist',\r\n filter: UID,\r\n } & Pagination) {\r\n let query = 'get_similar';\r\n query += qs.stringify(params, '&');\r\n let data;\r\n\r\n switch (params.type) {\r\n case \"song\":\r\n data = await this.request<{song: Song[]}>(query);\r\n return (data.song) ? data.song : data;\r\n case \"artist\":\r\n data = await this.request<{artist: Artist[]}>(query);\r\n return (data.artist) ? data.artist : data;\r\n default:\r\n return false;\r\n }\r\n }\r\n\r\n /**\r\n * Get some items based on some simple search types and filters. (Random by default)\r\n * @remarks MINIMUM_API_VERSION=380001; CHANGED_IN_API_VERSION=400001\r\n * @param params.type Object type\r\n * @param [params.filter] newest, highest, frequent, recent, forgotten, flagged, random\r\n * @param [params.user_id] Filter results to a certain user by UID\r\n * @param [params.username] Filter results to a certain user by username\r\n * @param [params.offset]\r\n * @param [params.limit]\r\n * @see {@link https://ampache.org/api/api-json-methods#stats}\r\n */\r\n async stats (params: {\r\n type: 'song' | 'album' | 'artist' | 'video' | 'playlist' | 'podcast' | 'podcast_episode',\r\n filter?: 'newest' | 'highest' | 'frequent' | 'recent' | 'forgotten' | 'flagged' | 'random',\r\n user_id?: number,\r\n username?: string,\r\n } & Pagination) {\r\n let query = 'stats';\r\n query += qs.stringify(params, '&');\r\n let data;\r\n\r\n switch (params.type) {\r\n case \"song\":\r\n data = await this.request<{song: Song[]}>(query);\r\n return (data.song) ? data.song : data;\r\n case \"album\":\r\n data = await this.request<{album: Album[]}>(query);\r\n return (data.album) ? data.album : data;\r\n case \"artist\":\r\n data = await this.request<{artist: Artist[]}>(query);\r\n return (data.artist) ? data.artist : data;\r\n case \"video\":\r\n data = await this.request<{video: Video[]}>(query);\r\n return (data.video) ? data.video : data;\r\n case \"playlist\":\r\n data = await this.request<{playlist: Playlist[]}>(query);\r\n return (data.playlist) ? data.playlist : data;\r\n case \"podcast\":\r\n data = await this.request<{podcast: Podcast[]}>(query);\r\n return (data.podcast) ? data.podcast : data;\r\n case \"podcast_episode\":\r\n data = await this.request<{podcast_episode: PodcastEpisode[]}>(query);\r\n return (data.podcast_episode) ? data.podcast_episode : data;\r\n default:\r\n return false;\r\n }\r\n }\r\n\r\n /**\r\n * This rates a library item\r\n * @remarks MINIMUM_API_VERSION=380001\r\n * @param params.type Object type\r\n * @param params.id UID to find\r\n * @param params.rating Rating to apply\r\n * @see {@link https://ampache.org/api/api-json-methods#rate}\r\n */\r\n rate (params: {\r\n type: 'song' | 'album' | 'artist' | 'playlist' | 'podcast' | 'podcast_episode' | 'video' | 'tvshow' | 'tvshow_season',\r\n id: UID,\r\n rating: 0 | 1 | 2 | 3 | 4 | 5,\r\n }) {\r\n let query = 'rate';\r\n query += qs.stringify(params, '&');\r\n return this.request<Success>(query);\r\n }\r\n\r\n /**\r\n * This flags a library item as a favorite\r\n * @remarks MINIMUM_API_VERSION=400001\r\n * @param params.type Object type\r\n * @param params.id UID to find\r\n * @param params.flag 0, 1\r\n * @see {@link https://ampache.org/api/api-json-methods#flag}\r\n */\r\n flag (params: {\r\n type: 'song' | 'album' | 'artist' | 'playlist' | 'podcast' | 'podcast_episode' | 'video' | 'tvshow' | 'tvshow_season',\r\n id: UID,\r\n flag: BinaryBoolean,\r\n }) {\r\n let query = 'flag';\r\n query += qs.stringify(params, '&');\r\n return this.request<Success>(query);\r\n }\r\n\r\n /**\r\n * Take a song_id and update the object_count and user_activity table with a play. This allows other sources to record play history to Ampache.\r\n * If you don't supply a user id (optional) then just fall back to you.\r\n * ACCESS REQUIRED: 100 (Admin) permission to change another user's play history\r\n * @remarks MINIMUM_API_VERSION=400001\r\n * @param params.id UID of song\r\n * @param [params.user] UID of user\r\n * @param [params.client] Client string\r\n * @param [params.date] UNIXTIME\r\n * @see {@link https://ampache.org/api/api-json-methods#record_play}\r\n */\r\n recordPlay (params: {\r\n id: UID,\r\n user?: UID,\r\n client?: string,\r\n date?: number,\r\n }) {\r\n let query = 'record_play';\r\n query += qs.stringify(params, '&');\r\n return this.request<Success>(query);\r\n }\r\n\r\n /**\r\n * Search for a song using text info and then record a play if found. This allows other sources to record play history to ampache\r\n * @remarks MINIMUM_API_VERSION=400001\r\n * @param params.song HTML encoded string\r\n * @param params.artist HTML encoded string\r\n * @param params.album HTML encoded string\r\n * @param [params.songmbid] Song MBID\r\n * @param [params.artistmbid] Artist MBID\r\n * @param [params.albummbid] Album MBID\r\n * @param [params.song_mbid] Alias of songmbid\r\n * @param [params.artist_mbid] Alias of artistmbid\r\n * @param [params.album_mbid] Alias of albummbid\r\n * @param [params.date] UNIXTIME\r\n * @param [params.client] Client string\r\n * @see {@link https://ampache.org/api/api-json-methods#scrobble}\r\n */\r\n scrobble (params: {\r\n song: string,\r\n artist: string,\r\n album: string,\r\n songmbid?: string,\r\n artistmbid?: string,\r\n albummbid?: string,\r\n song_mbid?: string,\r\n artist_mbid?: string,\r\n album_mbid?: string,\r\n date?: number,\r\n client?: string,\r\n }) {\r\n let query = 'scrobble';\r\n query += qs.stringify(params, '&');\r\n return this.request<Success>(query);\r\n }\r\n\r\n /**\r\n * Update a single album, artist, song from the tag data\r\n * @remarks MINIMUM_API_VERSION=400001\r\n * @param params.type Object type\r\n * @param params.id UID to find\r\n * @see {@link https://ampache.org/api/api-json-methods#update_from_tags}\r\n */\r\n updateFromTags (params: {\r\n type: 'song' | 'artist' | 'album',\r\n id: UID,\r\n }) {\r\n let query = 'update_from_tags';\r\n query += qs.stringify(params, '&');\r\n return this.request<Success>(query);\r\n }\r\n\r\n /**\r\n * Update artist information and fetch similar artists from last.fm\r\n * Make sure lastfm_API_key is set in your configuration file\r\n * ACCESS REQUIRED: 75 (Catalog Manager)\r\n * @remarks MINIMUM_API_VERSION=400001\r\n * @param params.id UID to find\r\n * @see {@link https://ampache.org/api/api-json-methods#update_artist_info}\r\n */\r\n updateArtistInfo (params: {\r\n id: UID,\r\n }) {\r\n let query = 'update_artist_info';\r\n query += qs.stringify(params, '&');\r\n return this.request<Success>(query);\r\n }\r\n\r\n /**\r\n * Updates a single album, artist, song running the gather_art process.\r\n * Doesn't overwrite existing art by default.\r\n * ACCESS REQUIRED: 75 (Catalog Manager)\r\n * @remarks MINIMUM_API_VERSION=400001\r\n * @param params.id UID to update\r\n * @param params.type Object type\r\n * @param [params.overwrite]\r\n * @see {@link https://ampache.org/api/api-json-methods#update_art}\r\n */\r\n updateArt (params: {\r\n id: UID,\r\n type: 'artist' | 'album' | 'song',\r\n overwrite?: BinaryBoolean,\r\n }) {\r\n let query = 'update_art';\r\n query += qs.stringify(params, '&');\r\n return this.request<Success>(query);\r\n }\r\n\r\n /**\r\n * Streams a given media file. Takes the file id in parameter with optional max bit rate, file format, time offset,\r\n * size and estimate content length option.\r\n * NOTE search and playlist will only stream a random object from the list.\r\n * @remarks MINIMUM_API_VERSION=400001\r\n * @param params.id UID to find\r\n * @param params.type Object type\r\n * @param [params.bitrate] Max bitrate for transcoding\r\n * @param [params.format] mp3, ogg, raw, etc (raw returns the original format)\r\n * @param [params.offset] Time offset\r\n * @param [params.length] 0, 1 (estimate content length)\r\n * @see {@link https://ampache.org/api/api-json-methods#stream}\r\n */\r\n stream (params: {\r\n id: UID,\r\n type: 'song' | 'podcast_episode' | 'search' | 'playlist',\r\n bitrate?: number,\r\n format?: string,\r\n offset?: number,\r\n length?: BinaryBoolean,\r\n }) {\r\n let query = 'stream';\r\n query += qs.stringify(params, '&');\r\n return this.binary(query);\r\n }\r\n\r\n /**\r\n * Downloads a given media file. set format=raw to download the full file\r\n * NOTE search and playlist will only download a random object from the list\r\n * @remarks MINIMUM_API_VERSION=400001\r\n * @param params.id UID to find\r\n * @param params.type Object type\r\n * @param [params.format] mp3, ogg, raw, etc (raw returns the original format)\r\n * @see {@link https://ampache.org/api/api-json-methods#download}\r\n */\r\n download (params: {\r\n id: UID,\r\n type: 'song' | 'podcast_episode' | 'search' | 'playlist',\r\n format?: string,\r\n }) {\r\n let query = 'download';\r\n query += qs.stringify(params, '&');\r\n return this.binary(query);\r\n }\r\n\r\n /**\r\n * Get an art image file.\r\n * @remarks MINIMUM_API_VERSION=400001\r\n * @param params.id UID to find\r\n * @param params.type Object type\r\n * @see {@link https://ampache.org/api/api-json-methods#get_art}\r\n */\r\n getArt (params: {\r\n id: UID,\r\n type: 'song' | 'artist' | 'album' | 'playlist' | 'search' | 'podcast',\r\n }) {\r\n let query = 'get_art';\r\n query += qs.stringify(params, '&');\r\n return this.binary(query);\r\n }\r\n\r\n /**\r\n * This is for controlling localplay\r\n * @param params.command The command to send to the localplay controller\r\n * @param [params.oid] Object UID\r\n * @param [params.type] Object type\r\n * @param [params.clear] 0, 1 (Clear the current playlist before adding)\r\n * @remarks MINIMUM_API_VERSION=380001; CHANGED_IN_API_VERSION=5.0.0\r\n * @see {@link https://ampache.org/api/api-json-methods#localplay}\r\n */\r\n localplay (params: {\r\n command: 'next' | 'prev' | 'stop' | 'play' | 'pause' | 'add' | 'volume_up' | 'volume_down' | 'volume_mute' | 'delete_all' | 'skip' | 'status',\r\n oid?: number,\r\n type?: 'song' | 'video' | 'podcast_episode' | 'channel' | 'broadcast' | 'democratic' | 'live_stream',\r\n clear?: BinaryBoolean,\r\n }) {\r\n let query = 'localplay';\r\n query += qs.stringify(params, '&');\r\n return this.request(query);\r\n }\r\n\r\n /**\r\n * Get the list of songs in your localplay playlist\r\n * @remarks MINIMUM_API_VERSION=5.0.0\r\n * @see {@link https://ampache.org/api/api-json-methods#localplay_songs}\r\n */\r\n localplaySongs () {\r\n let query = 'localplay_songs';\r\n return this.request(query);\r\n }\r\n\r\n /**\r\n * This is for controlling democratic play (Songs only). VOTE: +1 vote for the oid. DEVOTE: -1 vote for the oid.\r\n * PLAYLIST: Return an array of song items with an additional VOTE COUNT element.\r\n * PLAY: Returns the URL for playing democratic play.\r\n * @remarks MINIMUM_API_VERSION=380001\r\n * @param params.oid UID of song\r\n * @param params.method vote, devote, playlist, play\r\n * @see {@link https://ampache.org/api/api-json-methods#democratic}\r\n */\r\n democratic (params: {\r\n oid: UID,\r\n method: 'vote' | 'devote' | 'playlist' | 'play',\r\n }) {\r\n let query = 'democratic';\r\n query += qs.stringify(params, '&');\r\n return this.request(query);\r\n }\r\n\r\n /**\r\n * Perform an advanced search given passed rules.\r\n * You'll want to consult the docs for this.\r\n * @remarks MINIMUM_API_VERSION=380001\r\n * @param params.operator and, or (whether to match one rule or all)\r\n * @param params.type Object type to return\r\n * @param params.rules An array of rules\r\n * @param [params.random] 0, 1 (random order of results; default to 0)\r\n * @param [params.offset]\r\n * @param [params.limit]\r\n * @see {@link https://ampache.org/api/api-json-methods#advanced_search}\r\n */\r\n async advancedSearch (params: {\r\n operator: 'and' | 'or',\r\n type: 'song' | 'album' | 'album_disk' | 'artist' | 'album_artist' | 'song_artist' | 'label' | 'playlist' | 'podcast' | 'podcast_episode' | 'genre' | 'user' | 'video',\r\n rules: Array<Array<string>>,\r\n random?: BinaryBoolean,\r\n } & Pagination) {\r\n let query = 'advanced_search';\r\n\r\n for (let i = 0; i < params.rules.length; i++) {\r\n const thisRule = params.rules[i];\r\n const ruleNumber = i + 1;\r\n\r\n params['rule_' + ruleNumber] = thisRule[0];\r\n params['rule_' + ruleNumber + '_operator'] = thisRule[1];\r\n params['rule_' + ruleNumber + '_input'] = thisRule[2];\r\n\r\n if (thisRule[0] === 'metadata') {\r\n params['rule_' + ruleNumber + '_subtype'] = thisRule[3];\r\n }\r\n }\r\n\r\n // drop the initial 'rules' as it was split into its parts\r\n delete params.rules;\r\n\r\n query += qs.stringify(params, '&');\r\n\r\n let data;\r\n\r\n switch (params.type) {\r\n case \"song\":\r\n data = await this.request<{song: Song[]}>(query);\r\n return (data.song) ? data.song : data;\r\n case \"album\":\r\n data = await this.request<{album: Album[]}>(query);\r\n return (data.album) ? data.album : data;\r\n case \"artist\":\r\n case \"album_artist\":\r\n case \"song_artist\":\r\n data = await this.request<{artist: Artist[]}>(query);\r\n return (data.artist) ? data.artist : data;\r\n case \"label\":\r\n data = await this.request<{label: Label[]}>(query);\r\n return (data.label) ? data.label : data;\r\n case \"playlist\":\r\n data = await this.request<{playlist: Playlist[]}>(query);\r\n return (data.playlist) ? data.playlist : data;\r\n case \"podcast\":\r\n data = await this.request<{podcast: Podcast[]}>(query);\r\n return (data.podcast) ? data.podcast : data;\r\n case \"podcast_episode\":\r\n data = await this.request<{podcast_episode: PodcastEpisode[]}>(query);\r\n return (data.podcast_episode) ? data.podcast_episode : data;\r\n case \"genre\":\r\n data = await this.request<{genre: Genre[]}>(query);\r\n return (data.genre) ? data.genre : data;\r\n case \"user\":\r\n data = await this.request<{user: User[]}>(query);\r\n return (data.user) ? data.user : data;\r\n case \"video\":\r\n data = await this.request<{video: Video[]}>(query);\r\n return (data.video) ? data.video : data;\r\n default:\r\n return false;\r\n }\r\n }\r\n}","import qs from 'querystringify';\r\nimport { User, UserSummary, Activity } from './types';\r\nimport { Base, BinaryBoolean, Success } from '../base';\r\n\r\nexport class Users extends Base {\r\n /**\r\n * Get ids and usernames for your site\r\n * @remarks MINIMUM_API_VERSION=5.0.0\r\n * @see {@link https://ampache.org/api/api-json-methods#users}\r\n */\r\n async users() {\r\n let query = 'users';\r\n let data = await this.request<{user: UserSummary[]}>(query);\r\n return (data.user) ? data.user : data;\r\n }\r\n\r\n /**\r\n * This get a user's public information\r\n * @remarks MINIMUM_API_VERSION=380001\r\n * @param params.username UID to find\r\n * @see {@link https://ampache.org/api/api-json-methods#user}\r\n */\r\n async user (params: {\r\n username: string\r\n }) {\r\n let query = 'user';\r\n query += qs.stringify(params, '&');\r\n return await this.request<User>(query);\r\n }\r\n\r\n /**\r\n * Create a new user\r\n * ACCESS REQUIRED: 100 (Admin)\r\n * @remarks MINIMUM_API_VERSION=400001\r\n * @param params.username Username\r\n * @param params.password SHA256 hashed password\r\n * @param params.email Email\r\n * @param [params.fullname] Full Name\r\n * @param [params.disable] 0, 1\r\n * @param [params.catalog_filter_group] Catalog filter group, default = 0\r\n * @see {@link https://ampache.org/api/api-json-methods#user_create}\r\n */\r\n userCreate (params: {\r\n username: string,\r\n password: string,\r\n email: string,\r\n fullname?: string,\r\n disable?: BinaryBoolean,\r\n catalog_filter_group?: number\r\n }) {\r\n let query = 'user_create';\r\n query += qs.stringify(params, '&');\r\n return this.request<Success>(query);\r\n }\r\n\r\n /**\r\n * Register as a new user if allowed.\r\n * @remarks MINIMUM_API_VERSION=6.0.0\r\n * @param params.username Username\r\n * @param params.password SHA256 hashed password\r\n * @param params.email Email\r\n * @param [params.fullname] Full Name\r\n * @see {@link https://ampache.org/api/api-json-methods/#register}\r\n */\r\n register (params: {\r\n username: string,\r\n password: string,\r\n email: string,\r\n fullname?: string\r\n }) {\r\n let query = 'register';\r\n query += qs.stringify(params, '&');\r\n return this.request<Success>(query);\r\n }\r\n\r\n /**\r\n * Update an existing user\r\n * ACCESS REQUIRED: 100 (Admin)\r\n * @remarks MINIMUM_API_VERSION=400001\r\n * @param params.username Username\r\n * @param [params.password] Password\r\n * @param [params.email] Email\r\n * @param [params.fullname] Full Name\r\n * @param [params.website] Website\r\n * @param [params.state] State\r\n * @param [params.city] City\r\n * @param [params.disable] 0, 1\r\n * @param [params.maxbitrate] Max bitrate for transcoding\r\n * @see {@link https://ampache.org/api/api-json-methods#user_update}\r\n * @deprecated Being removed in 7.0.0. Use `user_edit` instead.\r\n */\r\n userUpdate (params: {\r\n username: string,\r\n password?: string,\r\n email?: string,\r\n fullname?: string,\r\n website?: string,\r\n state?: string,\r\n city?: string,\r\n disable?: BinaryBoolean,\r\n maxbitrate?: string\r\n }) {\r\n let query = 'user_update';\r\n query += qs.stringify(params, '&');\r\n return this.request<Success>(query);\r\n }\r\n\r\n /**\r\n * Update an existing user\r\n * ACCESS REQUIRED: 100 (Admin)\r\n * @remarks MINIMUM_API_VERSION=6.0.0\r\n * @param params.username Username\r\n * @param [params.password] Password\r\n * @param [params.email] Email\r\n * @param [params.fullname] Full Name\r\n * @param [params.website] Website\r\n * @param [params.state] State\r\n * @param [params.city] City\r\n * @param [params.disable] 0, 1\r\n * @param [params.maxbitrate] Max bitrate for transcoding\r\n * @param [params.group] Catalog filter group, default = 0\r\n * @param [params.fullname_public] show fullname in public display\r\n * @param [params.reset_apikey] reset user Api Key\r\n * @param [params.reset_streamtoken] reset user Stream Token\r\n * @param [params.clear_stats] reset all stats for this user\r\n * @see {@link https://ampache.org/api/api-json-methods#user_edit}\r\n */\r\n userEdit (params: {\r\n username: string,\r\n password?: string,\r\n email?: string,\r\n fullname?: string,\r\n website?: string,\r\n state?: string,\r\n city?: string,\r\n maxbitrate?: string,\r\n group?: number,\r\n disable?: BinaryBoolean,\r\n fullname_public?: BinaryBoolean,\r\n reset_apikey?: BinaryBoolean,\r\n reset_streamtoken?: BinaryBoolean,\r\n clear_stats?: BinaryBoolean,\r\n }) {\r\n let query = 'user_edit';\r\n query += qs.stringify(params, '&');\r\n return this.request<Success>(query);\r\n }\r\n\r\n /**\r\n * Delete an existing user.\r\n * ACCESS REQUIRED: 100 (Admin)\r\n * @remarks MINIMUM_API_VERSION=400001\r\n * @param params.filter UID of user to delete\r\n * @see {@link https://ampache.org/api/api-json-methods#user_delete}\r\n */\r\n userDelete (params: {\r\n filter: string,\r\n }) {\r\n let query = 'user_delete';\r\n query += qs.stringify(params, '&');\r\n return this.request<Success>(query);\r\n }\r\n\r\n /**\r\n * This gets the followers for the requested username\r\n * @remarks MINIMUM_API_VERSION=380001\r\n * @param params.username UID to find\r\n * @see {@link https://ampache.org/api/api-json-methods#followers}\r\n */\r\n async followers (params: {\r\n username: string,\r\n }) {\r\n let query = 'followers';\r\n query += qs.stringify(params, '&');\r\n let data = await this.request<{user: UserSummary[]}>(query);\r\n return (data.user) ? data.user : data;\r\n }\r\n\r\n /**\r\n * Get a list of people that this user follows\r\n * @remarks MINIMUM_API_VERSION=380001\r\n * @see {@link https://ampache.org/api/api-json-methods#following}\r\n */\r\n async following (params: {\r\n username: string,\r\n }) {\r\n let query = 'following';\r\n query += qs.stringify(params, '&');\r\n let data = await this.request<{user: UserSummary[]}>(query);\r\n return (data.user) ? data.user : data;\r\n }\r\n\r\n /**\r\n * This will follow/unfollow a user\r\n * @param params.username Username string to find\r\n * @see {@link https://ampache.org/api/api-json-methods#toggle_follow}\r\n */\r\n toggleFollow(params: {\r\n username: string,\r\n }) {\r\n let query = 'toggle_follow';\r\n query += qs.stringify(params, '&');\r\n return this.request<Success>(query);\r\n }\r\n\r\n /**\r\n * This get a user timeline\r\n * @remarks MINIMUM_API_VERSION=380001\r\n * @param params.username Username to find\r\n * @param [params.limit] Max results to return\r\n * @param [params.since] UNIXTIME\r\n * @see {@link https://ampache.org/api/api-json-methods#timeline}\r\n */\r\n async timeline (params: {\r\n username: string,\r\n limit?: number,\r\n since?: number,\r\n }) {\r\n let query = 'timeline';\r\n query += qs.stringify(params, '&');\r\n let data = await this.request<{activity: Activity[]}>(query);\r\n return (data.activity) ? data.activity : data;\r\n }\r\n\r\n /**\r\n * This get current user friends timeline\r\n * @remarks MINIMUM_API_VERSION=380001\r\n * @param [params.limit] Max results to return\r\n * @param [params.since] UNIXTIME\r\n * @see {@link https://ampache.org/api/api-json-methods#friends_timeline}\r\n */\r\n async friendsTimeline (params?: {\r\n limit?: number,\r\n since?: number,\r\n }) {\r\n let query = 'friends_timeline';\r\n query += qs.stringify(params, '&');\r\n let data = await this.request<{activity: Activity[]}>(query);\r\n return (data.activity) ? data.activity : data;\r\n }\r\n}","import qs from 'querystringify';\r\nimport { Video, DeletedVideo } from './types';\r\nimport { Base, BinaryBoolean, Pagination, UID } from '../base';\r\n\r\nexport class Videos extends Base {\r\n /**\r\n * Get videos\r\n * @remarks MINIMUM_API_VERSION=380001\r\n * @param [params.filter] Filter results to match this string\r\n * @param [params.exact] 0, 1 (if true filter is exact = rather than fuzzy LIKE)\r\n * @param [params.offset]\r\n * @param [params.limit]\r\n * @see {@link https://ampache.org/api/api-json-methods#videos}\r\n */\r\n async videos (params?: {\r\n filter?: string,\r\n exact?: BinaryBoolean,\r\n } & Pagination) {\r\n let query = 'videos';\r\n query += qs.stringify(params, '&');\r\n let data = await this.request<{video: Video[]}>(query);\r\n return (data.video) ? data.video : data;\r\n }\r\n\r\n /**\r\n * This returns a single video\r\n * @remarks MINIMUM_API_VERSION=380001\r\n * @param params.filter UID to find\r\n * @see {@link https://ampache.org/api/api-json-methods#video}\r\n */\r\n video (params: {\r\n filter: UID,\r\n }) {\r\n let query = 'video';\r\n query += qs.stringify(params, '&');\r\n return this.request<Video>(query);\r\n }\r\n\r\n /**\r\n * This returns video objects that have been deleted\r\n * @param [params.offset]\r\n * @param [params.limit]\r\n * @see {@link https://ampache.org/api/api-json-methods#deleted_videos}\r\n */\r\n async deletedVideos (params?: {\r\n\r\n } & Pagination) {\r\n let query = 'deleted_videos';\r\n query += qs.stringify(params, '&');\r\n let data = await this.request<{deleted_video: DeletedVideo[]}>(query);\r\n return (data.deleted_video) ? data.deleted_video : data;\r\n }\r\n}"],"names":["has","Object","prototype","hasOwnProperty","encode","input","encodeURIComponent","e","obj","prefix","value","key","pairs","call","isNaN","push","length","join","n","Promise","t","r","s","XMLHttpRequest","o","u","i","a","ok","status","statusText","url","responseURL","text","resolve","responseText","json","then","JSON","parse","blob","Blob","response","clone","headers","keys","entries","get","toLowerCase","l","open","method","onload","getAllResponseHeaders","replace","onerror","withCredentials","credentials","setRequestHeader","send","body","browser","self","fetch","require$$0","default","Base","constructor","config","sessionKey","this","version","debug","request","endpoint","includeAuth","console","Error","binary","setSessionKey","h","f","binLen","c","parseInt","substr","w","E","A","charCodeAt","p","indexOf","search","charAt","ArrayBuffer","Uint8Array","outputUpper","toUpperCase","b64Pad","String","fromCharCode","outputLen","shakeLen","encoding","numRounds","U","R","update","T","F","m","g","slice","getHash","H","B","v","C","Y","S","I","setHMACKey","L","M","getHMAC","N","d","y","b","super","hmacKey","format","AmpacheAPI","applyMixins","derivedCtor","baseCtors","async","params","query","qs","data","album","artist","Auth","handshake","timestamp","Math","floor","Date","getTime","user","auth","ping","goodbye","encryptPassword","getSHA256","password","time","shaObj","JsSHA","bookmark","getBookmark","bookmarkCreate","bookmarkEdit","bookmarkDelete","catalog","catalogAction","catalogFile","catalogAdd","catalogDelete","Genres","genre","label","license","live_stream","liveStream","liveStreamCreate","liveStreamEdit","liveStreamDelete","playlist","Array","isArray","results","filter","item","id","toString","match","playlistCreate","playlistEdit","playlistDelete","playlistAddSong","playlistRemoveSong","song","podcast","podcastCreate","podcastEdit","podcastDelete","podcast_episode","podcastEpisode","podcastEpisodeDelete","updatePodcast","deleted_podcast_episode","preference","preferenceCreate","preferenceEdit","preferenceDelete","share","shareCreate","shareEdit","shareDelete","shout","Songs","songDelete","urlToSong","deleted_song","systemUpdate","type","video","rate","flag","recordPlay","scrobble","updateFromTags","updateArtistInfo","updateArt","stream","download","getArt","localplay","localplaySongs","democratic","rules","thisRule","ruleNumber","userCreate","register","userUpdate","userEdit","userDelete","toggleFollow","activity","Videos","deleted_video","forEach","baseCtor","getOwnPropertyNames","name","defineProperty","getOwnPropertyDescriptor"],"mappings":"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"}