UNPKG

@wwdrew/expo-spotify-sdk

Version:

Expo module wrapping the native Spotify iOS (v5) and Android (v4) SDKs for OAuth authentication and App Remote playback control

124 lines 4.79 kB
import type { EventSubscription } from "expo-modules-core"; import { type AuthErrorCode } from "./error"; export type { AuthErrorCode } from "./error"; export { AuthError } from "./error"; export interface SpotifySession { /** OAuth access token. */ accessToken: string; /** * OAuth refresh token. `null` on Android when no `tokenSwapURL` is provided * (the Spotify Android SDK does not expose a refresh token for implicit * grants). */ refreshToken: string | null; /** Expiration timestamp as Unix epoch milliseconds. */ expirationDate: number; /** Scopes the access token was granted (or requested, on Android implicit). */ scopes: SpotifyScope[]; } export type SpotifyScope = "ugc-image-upload" | "user-read-playback-state" | "user-modify-playback-state" | "user-read-currently-playing" | "app-remote-control" | "streaming" | "playlist-read-private" | "playlist-read-collaborative" | "playlist-modify-private" | "playlist-modify-public" | "user-follow-modify" | "user-follow-read" | "user-top-read" | "user-read-recently-played" | "user-library-modify" | "user-library-read" | "user-read-email" | "user-read-private"; export interface AuthenticateConfig { /** OAuth scopes to request. Must contain at least one entry. */ scopes: SpotifyScope[]; /** * If supplied, requests an authorization code rather than an implicit * token, then POSTs the code to this URL to exchange it for tokens. * **Required on Android** to receive a usable `refreshToken`. */ tokenSwapURL?: string; /** * Used by the iOS SDK to refresh access tokens automatically, and by * `Auth.refresh()` on both platforms. */ tokenRefreshURL?: string; /** * If `true`, forces Spotify to show the authorization dialog even when the * user already has an active session. Defaults to `false`. */ showDialog?: boolean; } export interface RefreshConfig { /** The refresh token from a previous `Auth.authenticate()` call. */ refreshToken: string; /** URL of your token refresh server endpoint. */ tokenRefreshURL: string; /** * Scopes that were granted by the previous session. Used as a fallback when * the refresh response omits the `scope` field. */ scopes?: SpotifyScope[]; } /** * Payload delivered to `Auth.addListener("sessionChange", ...)` subscribers. */ export type SessionChangeEvent = { type: "didInitiate"; session: SpotifySession; } | { type: "didRenew"; session: SpotifySession; } | { type: "didFail"; error: { code: AuthErrorCode; message: string; }; }; /** * Spotify Auth namespace. Handles OAuth authentication and session lifecycle. * * @example * ```ts * import { Auth } from "@wwdrew/expo-spotify-sdk"; * * const session = await Auth.authenticate({ scopes: ["streaming"] }); * ``` */ export declare const Auth: { /** * Returns `true` if the Spotify app is installed on the device. */ readonly isAvailable: () => boolean; /** * Starts a Spotify OAuth flow. Resolves with a {@link SpotifySession}; * rejects with an {@link AuthError} carrying a `code`. */ readonly authenticate: (config: AuthenticateConfig) => Promise<SpotifySession>; /** * Exchanges a refresh token for a new access token via your token refresh * server. Resolves with a fresh {@link SpotifySession}; rejects with an * {@link AuthError}. */ readonly refresh: (config: RefreshConfig) => Promise<SpotifySession>; /** * Forcibly cancel any in-flight `Auth.authenticate()` call. No-op on * Android (the Android coordinator self-cleans via structured concurrency). * * Use before `Auth.authenticate()` to defensively clear any leaked iOS * coordinator state (the `SPTSessionManager` delegate callbacks are not * guaranteed to fire). */ readonly cancelPending: () => Promise<void>; /** * Subscribes to session lifecycle events. * * Events fire for every `Auth.authenticate()` and `Auth.refresh()` call, * regardless of whether the call was awaited. Useful for persisting tokens * in a central store without coupling the store to the call sites. * * Returns a `Subscription` — call `.remove()` to unsubscribe. * * @example * ```ts * const sub = Auth.addListener("sessionChange", (event) => { * if (event.type === "didInitiate" || event.type === "didRenew") { * store.setSession(event.session); * } * }); * // later: * sub.remove(); * ``` */ readonly addListener: (event: "sessionChange", listener: (event: SessionChangeEvent) => void) => EventSubscription; }; //# sourceMappingURL=index.d.ts.map