← Public packages
@kentcdodds/spotify
Spotify playback, playlist, search, library, and device helpers.
src/lib/accounts.ts
82 lines · 2.7 KB · TypeScriptexport type SpotifyAccountAlias = 'personal' | 'family'
export type SpotifyAccountInfo = {
account: SpotifyAccountAlias
integrationName: string
label: string
userIdHint: string | null
displayNameHint: string | null
/** Default Spotify Connect device id used when nothing is playing, or null. */
fallbackDeviceId: string | null
/** Context started when play is requested and nothing is playing, or null. */
defaultCollectionUri: string | null
useWhen: string
}
export const SPOTIFY_ACCOUNTS: Record<SpotifyAccountAlias, SpotifyAccountInfo> = {
personal: {
account: 'personal',
integrationName: 'spotify',
label: 'Personal Spotify',
userIdHint: 'ajxrmwjv1y6so642k7b6qad0t',
displayNameHint: 'Kent C. Dodds',
fallbackDeviceId: '2084292936',
defaultCollectionUri: 'spotify:user:kentcdodds:collection',
useWhen:
'Default account. Use for Kent\u2019s personal playback, playlists, library, and listening history unless the user asks for the family account.',
},
family: {
account: 'family',
integrationName: 'spotify-family',
label: 'Family Spotify',
userIdHint: '1mgpsy0fwzzsvuczyh4upar42',
displayNameHint: 'Dodds Kids',
fallbackDeviceId: null,
defaultCollectionUri: null,
useWhen:
'Use when the user asks for the family / kids / household Spotify account, such as playlists meant for whole-home Sonos playback.',
},
}
export const SPOTIFY_ACCOUNT_ALIASES = ['personal', 'family'] as const
const DEFAULT_ACCOUNT: SpotifyAccountAlias = 'personal'
function cloneAccount(account: SpotifyAccountInfo): SpotifyAccountInfo {
return { ...account }
}
export function listSpotifyAccounts(): SpotifyAccountInfo[] {
return SPOTIFY_ACCOUNT_ALIASES.map((alias) => cloneAccount(SPOTIFY_ACCOUNTS[alias]))
}
/**
* Resolve an account alias or integration name to account info.
* Unlike google-products, the account is optional and defaults to `personal`.
*/
export function resolveSpotifyAccount(
input: { account?: string } | string = {},
): SpotifyAccountInfo {
const account = (typeof input === 'string' ? input : input.account) ?? DEFAULT_ACCOUNT
const fromAlias = SPOTIFY_ACCOUNTS[account as SpotifyAccountAlias]
if (fromAlias) return cloneAccount(fromAlias)
const fromIntegration = SPOTIFY_ACCOUNT_ALIASES.map((alias) => SPOTIFY_ACCOUNTS[alias]).find(
(candidate) => candidate.integrationName === account,
)
if (fromIntegration) return cloneAccount(fromIntegration)
throw new Error(
'Unknown Spotify account "' +
account +
'". Pass one of: ' +
SPOTIFY_ACCOUNT_ALIASES.join(', ') +
' (defaults to personal when omitted).',
)
}
export default function accounts() {
return {
accounts: listSpotifyAccounts(),
aliases: [...SPOTIFY_ACCOUNT_ALIASES],
defaultAccount: DEFAULT_ACCOUNT,
}
}