@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
TypeScript
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