Skip to content

Instantly share code, notes, and snippets.

@bundle-js
Created March 22, 2023 06:02
Show Gist options
  • Save bundle-js/ef27deef1c9bc1a62d5d287198e963c0 to your computer and use it in GitHub Desktop.
Save bundle-js/ef27deef1c9bc1a62d5d287198e963c0 to your computer and use it in GitHub Desktop.
var x=Object.defineProperty;var p=(r,e)=>{for(var t in e)x(r,t,{get:e[t],enumerable:!0})};import{Buffer as k}from"buffer";import{createHash as I,randomBytes as O}from"crypto";var u=r=>k.from(r).toString("base64"),E=O,f=async r=>I("sha256").update(r).digest("base64url");var m="https://accounts.spotify.com",c=`${m}/authorize`,n=`${m}/api/token`,i="application/x-www-form-urlencoded;charset=UTF-8",o=class extends Error{status;constructor(e,t,a){super(e,a),this.status=t,this.name="SpotifyAuthError"+t}},_=r=>{let e=Object.fromEntries(r);if("code"in e||"error"in e)return e;throw new Error("Invalid params.")},h=(r,e)=>"Basic "+u(r+":"+e),P={UGC_IMAGE_UPLOAD:"ugc-image-upload",USER_READ_PLAYBACK_STATE:"user-read-playback-state",USER_MODIFY_PLAYBACK_STATE:"user-modify-playback-state",USER_READ_CURRENTLY_PLAYING:"user-read-currently-playing",STREAMING:"streaming",PLAYLIST_READ_PRIVATE:"playlist-read-private",PLAYLIST_READ_COLLABORATIVE:"playlist-read-collaborative",PLAYLIST_MODIFY_PRIVATE:"playlist-modify-private",PLAYLIST_MODIFY_PUBLIC:"playlist-modify-public",USER_FOLLOW_MODIFY:"user-follow-modify",USER_FOLLOW_READ:"user-follow-read",USER_READ_PLAYBACK_POSITION:"user-read-playback-position",USER_TOP_READ:"user-top-read",USER_READ_RECENTLY_PLAYED:"user-read-recently-played",USER_LIBRARY_MODIFY:"user-library-modify",USER_LIBRARY_READ:"user-library-read",USER_READ_EMAIL:"user-read-email",USER_READ_PRIVATE:"user-read-private"};var A={};p(A,{AuthProvider:()=>l,getGrantData:()=>b,getRedirectURL:()=>D,parseCallbackData:()=>_,refresh:()=>y});var s=r=>{let e=new URLSearchParams;return Object.keys(r).forEach(t=>{let a=r[t];typeof a>"u"||e.set(t,a.toString())}),e};var D=({scopes:r,...e})=>{let t=new URL(c);return t.search=s({response_type:"code",scope:r?.join(" "),...e}).toString(),t},b=async r=>{let e=await fetch(n,{method:"POST",headers:{Authorization:h(r.client_id,r.client_secret),"Content-Type":i},body:s({code:r.code,redirect_uri:r.redirect_uri,grant_type:"authorization_code"})});if(!e.ok)throw new o(await e.text(),e.status);return await e.json()},y=async r=>{let e=await fetch(n,{method:"POST",headers:{Authorization:h(r.client_id,r.client_secret),"Content-Type":i},body:s({refresh_token:r.refresh_token,grant_type:"refresh_token"})});if(!e.ok)throw new o(await e.text(),e.status);return await e.json()},l=class{config;opts;constructor(e,t={}){this.config=e,this.opts=t}async getAccessToken(e=!1){if(e||!this.config.access_token)try{let t=await y(this.config);this.config.access_token=t.access_token,this.opts.onRefresh&&await this.opts.onRefresh(t)}catch(t){throw this.opts.onRefreshFailure&&await this.opts.onRefreshFailure(t),t}return this.config.access_token}};var L={};p(L,{AuthProvider:()=>d,generateCodeVerifier:()=>w,generateCodes:()=>F,getCodeChallenge:()=>f,getGrantData:()=>Y,getRedirectURL:()=>B,parseCallbackData:()=>_,refresh:()=>T});var B=({scopes:r,...e})=>{let t=new URL(c);return t.search=s({response_type:"code",scope:r?.join(" "),code_challenge_method:"S256",...e}).toString(),t},Y=async r=>{let e=await fetch(n,{headers:{"Content-Type":i},method:"POST",body:s({grant_type:"authorization_code",...r})});if(!e.ok)throw new o(await e.text(),e.status);return await e.json()},g="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~",w=(r=64)=>{let e=E(r),t="";for(let a=0;a<r;a++)t+=g[e[a]%g.length];return t},F=async r=>{let e=w(r),t=await f(e);return{code_verifier:e,code_challenge:t}},T=async r=>{let e=await fetch(n,{headers:{"Content-Type":i},method:"POST",body:s({grant_type:"refresh_token",client_id:r.client_id,refresh_token:r.refresh_token})});if(!e.ok)throw new o(await e.text(),e.status);return await e.json()},d=class{config;opts;constructor(e,t={}){this.config=e,this.opts=t}async getAccessToken(e=!1){if(e||!this.config.access_token)try{let t=await T(this.config);this.config.refresh_token=t.refresh_token,this.config.access_token=t.access_token,this.opts.onRefresh&&await this.opts.onRefresh(t)}catch(t){throw this.opts.onRefreshFailure&&await this.opts.onRefreshFailure(t),t}return this.config.access_token}};var C={};p(C,{AuthProvider:()=>R,getAccessToken:()=>S});var S=async r=>{let e=await fetch(n,{method:"POST",headers:{Authorization:h(r.client_id,r.client_secret),"Content-Type":i},body:new URLSearchParams({grant_type:"client_credentials"})});if(!e.ok)throw new o(await e.text(),e.status);return await e.json()},R=class{config;opts;#e=null;constructor(e,t={}){this.config=e,this.opts=t}async getAccessToken(e=!1){if(e||!this.#e)try{let t=await S(this.config);this.#e=t.access_token,this.opts.onRefresh&&await this.opts.onRefresh(t)}catch(t){throw this.opts.onRefreshFailure&&this.opts.onRefreshFailure(t),t}return this.#e}};var U={};p(U,{getRedirectURL:()=>j,parseCallbackData:()=>N});var j=({scopes:r,...e})=>{let t=new URL(c);return t.search=s({response_type:"token",scope:r?.join(" "),...e}).toString(),t},N=r=>{let e=Object.fromEntries(new URLSearchParams(r.substring(1)));if("error"in e||"access_token"in e&&"expires_in"in e&&"token_type"in e)return e;throw new Error("Invalid params")};export{A as AuthCode,C as ClientCredentials,U as ImplicitGrant,L as PKCEAuthCode,P as SCOPES,o as SpotifyAuthError};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment