@wwdrew/expo-spotify-sdk 0.8.0 → 2.0.0
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.
- package/README.md +404 -140
- package/android/build.gradle +12 -2
- package/android/consumer-rules.pro +5 -0
- package/android/libs/SETUP.md +29 -0
- package/android/src/main/java/expo/modules/spotifysdk/ExpoSpotifySDKModule.kt +146 -9
- package/android/src/main/java/expo/modules/spotifysdk/SpotifyAppRemoteCoordinator.kt +556 -0
- package/android/src/main/java/expo/modules/spotifysdk/SpotifyErrors.kt +112 -0
- package/app.plugin.js +1 -1
- package/build/ExpoSpotifySDKModule.web.d.ts +23 -0
- package/build/ExpoSpotifySDKModule.web.d.ts.map +1 -1
- package/build/ExpoSpotifySDKModule.web.js +74 -5
- package/build/ExpoSpotifySDKModule.web.js.map +1 -1
- package/build/app-remote/error.d.ts +8 -0
- package/build/app-remote/error.d.ts.map +1 -0
- package/build/app-remote/error.js +10 -0
- package/build/app-remote/error.js.map +1 -0
- package/build/app-remote/index.d.ts +79 -0
- package/build/app-remote/index.d.ts.map +1 -0
- package/build/app-remote/index.js +110 -0
- package/build/app-remote/index.js.map +1 -0
- package/build/auth/error.d.ts +8 -0
- package/build/auth/error.d.ts.map +1 -0
- package/build/auth/error.js +10 -0
- package/build/auth/error.js.map +1 -0
- package/build/auth/index.d.ts +124 -0
- package/build/auth/index.d.ts.map +1 -0
- package/build/auth/index.js +162 -0
- package/build/auth/index.js.map +1 -0
- package/build/content/error.d.ts +8 -0
- package/build/content/error.d.ts.map +1 -0
- package/build/content/error.js +10 -0
- package/build/content/error.js.map +1 -0
- package/build/content/index.d.ts +38 -0
- package/build/content/index.d.ts.map +1 -0
- package/build/content/index.js +56 -0
- package/build/content/index.js.map +1 -0
- package/build/error.d.ts +24 -0
- package/build/error.d.ts.map +1 -0
- package/build/error.js +25 -0
- package/build/error.js.map +1 -0
- package/build/hooks/index.d.ts +90 -0
- package/build/hooks/index.d.ts.map +1 -0
- package/build/hooks/index.js +326 -0
- package/build/hooks/index.js.map +1 -0
- package/build/images/error.d.ts +8 -0
- package/build/images/error.d.ts.map +1 -0
- package/build/images/error.js +10 -0
- package/build/images/error.js.map +1 -0
- package/build/images/index.d.ts +36 -0
- package/build/images/index.d.ts.map +1 -0
- package/build/images/index.js +59 -0
- package/build/images/index.js.map +1 -0
- package/build/index.d.ts +44 -56
- package/build/index.d.ts.map +1 -1
- package/build/index.js +49 -141
- package/build/index.js.map +1 -1
- package/build/player/error.d.ts +8 -0
- package/build/player/error.d.ts.map +1 -0
- package/build/player/error.js +10 -0
- package/build/player/error.js.map +1 -0
- package/build/player/index.d.ts +140 -0
- package/build/player/index.d.ts.map +1 -0
- package/build/player/index.js +137 -0
- package/build/player/index.js.map +1 -0
- package/build/uri/index.d.ts +55 -0
- package/build/uri/index.d.ts.map +1 -0
- package/build/uri/index.js +57 -0
- package/build/uri/index.js.map +1 -0
- package/build/user/error.d.ts +8 -0
- package/build/user/error.d.ts.map +1 -0
- package/build/user/error.js +10 -0
- package/build/user/error.js.map +1 -0
- package/build/user/index.d.ts +44 -0
- package/build/user/index.d.ts.map +1 -0
- package/build/user/index.js +97 -0
- package/build/user/index.js.map +1 -0
- package/ios/ExpoSpotifySDK.podspec +1 -1
- package/ios/ExpoSpotifySDKModule.swift +227 -5
- package/ios/SpotifyAppRemoteCoordinator.swift +939 -0
- package/ios/SpotifyAuthCoordinator.swift +53 -13
- package/ios/SpotifyTokenRefreshClient.swift +28 -0
- package/package.json +29 -16
- package/plugin/build/index.d.ts +20 -3
- package/plugin/build/index.js +22 -25
- package/plugin/build/types.d.ts +17 -1
- package/plugin/build/withSpotifySdkConfig.d.ts +4 -0
- package/plugin/build/withSpotifySdkConfig.js +27 -0
|
@@ -2,6 +2,29 @@ declare const _default: {
|
|
|
2
2
|
isAvailable(): boolean;
|
|
3
3
|
authenticateAsync(): Promise<never>;
|
|
4
4
|
refreshSessionAsync(): Promise<never>;
|
|
5
|
+
appRemoteConnect(): Promise<never>;
|
|
6
|
+
appRemoteDisconnect(): Promise<never>;
|
|
7
|
+
appRemoteIsConnected(): boolean;
|
|
8
|
+
appRemoteGetConnectionState(): Promise<"disconnected">;
|
|
9
|
+
playerPlay(): Promise<never>;
|
|
10
|
+
playerPause(): Promise<never>;
|
|
11
|
+
playerResume(): Promise<never>;
|
|
12
|
+
playerSkipNext(): Promise<never>;
|
|
13
|
+
playerSkipPrevious(): Promise<never>;
|
|
14
|
+
playerSeekTo(): Promise<never>;
|
|
15
|
+
playerSetShuffle(): Promise<never>;
|
|
16
|
+
playerSetRepeatMode(): Promise<never>;
|
|
17
|
+
playerSetPodcastPlaybackSpeed(): Promise<never>;
|
|
18
|
+
playerQueue(): Promise<never>;
|
|
19
|
+
playerGetPlayerState(): Promise<never>;
|
|
20
|
+
playerGetCrossfadeState(): Promise<never>;
|
|
21
|
+
userGetCapabilities(): Promise<never>;
|
|
22
|
+
userGetLibraryState(): Promise<never>;
|
|
23
|
+
userAddToLibrary(): Promise<never>;
|
|
24
|
+
userRemoveFromLibrary(): Promise<never>;
|
|
25
|
+
contentGetRecommendedContentItems(): Promise<never>;
|
|
26
|
+
contentGetChildren(): Promise<never>;
|
|
27
|
+
imagesLoad(): Promise<never>;
|
|
5
28
|
addListener(): {
|
|
6
29
|
remove(): void;
|
|
7
30
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ExpoSpotifySDKModule.web.d.ts","sourceRoot":"","sources":["../src/ExpoSpotifySDKModule.web.ts"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"ExpoSpotifySDKModule.web.d.ts","sourceRoot":"","sources":["../src/ExpoSpotifySDKModule.web.ts"],"names":[],"mappings":";mBAQiB,OAAO;yBAGD,OAAO,CAAC,KAAK,CAAC;2BAGZ,OAAO,CAAC,KAAK,CAAC;wBAGjB,OAAO,CAAC,KAAK,CAAC;2BAGX,OAAO,CAAC,KAAK,CAAC;4BAGb,OAAO;mCAGA,OAAO,CAAC,cAAc,CAAC;kBAGxC,OAAO,CAAC,KAAK,CAAC;mBAGb,OAAO,CAAC,KAAK,CAAC;oBAGb,OAAO,CAAC,KAAK,CAAC;sBAGZ,OAAO,CAAC,KAAK,CAAC;0BAGV,OAAO,CAAC,KAAK,CAAC;oBAGpB,OAAO,CAAC,KAAK,CAAC;wBAGV,OAAO,CAAC,KAAK,CAAC;2BAGX,OAAO,CAAC,KAAK,CAAC;qCAGJ,OAAO,CAAC,KAAK,CAAC;mBAGhC,OAAO,CAAC,KAAK,CAAC;4BAGL,OAAO,CAAC,KAAK,CAAC;+BAGX,OAAO,CAAC,KAAK,CAAC;2BAGlB,OAAO,CAAC,KAAK,CAAC;2BAGd,OAAO,CAAC,KAAK,CAAC;wBAGjB,OAAO,CAAC,KAAK,CAAC;6BAGT,OAAO,CAAC,KAAK,CAAC;yCAGF,OAAO,CAAC,KAAK,CAAC;0BAG7B,OAAO,CAAC,KAAK,CAAC;kBAGtB,OAAO,CAAC,KAAK,CAAC;mBAGb;QAAE,MAAM,IAAI,IAAI,CAAA;KAAE;uBAGd,IAAI;;AAlFzB,wBAqFE"}
|
|
@@ -1,16 +1,85 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
function unsupported(method) {
|
|
2
|
+
return new Error(`[expo-spotify-sdk] ${method} is not supported on web. ` +
|
|
3
|
+
"This library targets iOS and Android only.");
|
|
4
4
|
}
|
|
5
5
|
export default {
|
|
6
6
|
isAvailable() {
|
|
7
7
|
return false;
|
|
8
8
|
},
|
|
9
9
|
authenticateAsync() {
|
|
10
|
-
return Promise.reject(
|
|
10
|
+
return Promise.reject(unsupported("authenticateAsync"));
|
|
11
11
|
},
|
|
12
12
|
refreshSessionAsync() {
|
|
13
|
-
return Promise.reject(
|
|
13
|
+
return Promise.reject(unsupported("refreshSessionAsync"));
|
|
14
|
+
},
|
|
15
|
+
appRemoteConnect() {
|
|
16
|
+
return Promise.reject(unsupported("appRemoteConnect"));
|
|
17
|
+
},
|
|
18
|
+
appRemoteDisconnect() {
|
|
19
|
+
return Promise.reject(unsupported("appRemoteDisconnect"));
|
|
20
|
+
},
|
|
21
|
+
appRemoteIsConnected() {
|
|
22
|
+
return false;
|
|
23
|
+
},
|
|
24
|
+
appRemoteGetConnectionState() {
|
|
25
|
+
return Promise.resolve("disconnected");
|
|
26
|
+
},
|
|
27
|
+
playerPlay() {
|
|
28
|
+
return Promise.reject(unsupported("playerPlay"));
|
|
29
|
+
},
|
|
30
|
+
playerPause() {
|
|
31
|
+
return Promise.reject(unsupported("playerPause"));
|
|
32
|
+
},
|
|
33
|
+
playerResume() {
|
|
34
|
+
return Promise.reject(unsupported("playerResume"));
|
|
35
|
+
},
|
|
36
|
+
playerSkipNext() {
|
|
37
|
+
return Promise.reject(unsupported("playerSkipNext"));
|
|
38
|
+
},
|
|
39
|
+
playerSkipPrevious() {
|
|
40
|
+
return Promise.reject(unsupported("playerSkipPrevious"));
|
|
41
|
+
},
|
|
42
|
+
playerSeekTo() {
|
|
43
|
+
return Promise.reject(unsupported("playerSeekTo"));
|
|
44
|
+
},
|
|
45
|
+
playerSetShuffle() {
|
|
46
|
+
return Promise.reject(unsupported("playerSetShuffle"));
|
|
47
|
+
},
|
|
48
|
+
playerSetRepeatMode() {
|
|
49
|
+
return Promise.reject(unsupported("playerSetRepeatMode"));
|
|
50
|
+
},
|
|
51
|
+
playerSetPodcastPlaybackSpeed() {
|
|
52
|
+
return Promise.reject(unsupported("playerSetPodcastPlaybackSpeed"));
|
|
53
|
+
},
|
|
54
|
+
playerQueue() {
|
|
55
|
+
return Promise.reject(unsupported("playerQueue"));
|
|
56
|
+
},
|
|
57
|
+
playerGetPlayerState() {
|
|
58
|
+
return Promise.reject(unsupported("playerGetPlayerState"));
|
|
59
|
+
},
|
|
60
|
+
playerGetCrossfadeState() {
|
|
61
|
+
return Promise.reject(unsupported("playerGetCrossfadeState"));
|
|
62
|
+
},
|
|
63
|
+
userGetCapabilities() {
|
|
64
|
+
return Promise.reject(unsupported("userGetCapabilities"));
|
|
65
|
+
},
|
|
66
|
+
userGetLibraryState() {
|
|
67
|
+
return Promise.reject(unsupported("userGetLibraryState"));
|
|
68
|
+
},
|
|
69
|
+
userAddToLibrary() {
|
|
70
|
+
return Promise.reject(unsupported("userAddToLibrary"));
|
|
71
|
+
},
|
|
72
|
+
userRemoveFromLibrary() {
|
|
73
|
+
return Promise.reject(unsupported("userRemoveFromLibrary"));
|
|
74
|
+
},
|
|
75
|
+
contentGetRecommendedContentItems() {
|
|
76
|
+
return Promise.reject(unsupported("contentGetRecommendedContentItems"));
|
|
77
|
+
},
|
|
78
|
+
contentGetChildren() {
|
|
79
|
+
return Promise.reject(unsupported("contentGetChildren"));
|
|
80
|
+
},
|
|
81
|
+
imagesLoad() {
|
|
82
|
+
return Promise.reject(unsupported("imagesLoad"));
|
|
14
83
|
},
|
|
15
84
|
addListener() {
|
|
16
85
|
return { remove() { } };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ExpoSpotifySDKModule.web.js","sourceRoot":"","sources":["../src/ExpoSpotifySDKModule.web.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"ExpoSpotifySDKModule.web.js","sourceRoot":"","sources":["../src/ExpoSpotifySDKModule.web.ts"],"names":[],"mappings":"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","sourcesContent":["function unsupported(method: string): Error {\n return new Error(\n `[expo-spotify-sdk] ${method} is not supported on web. ` +\n \"This library targets iOS and Android only.\",\n );\n}\n\nexport default {\n isAvailable(): boolean {\n return false;\n },\n authenticateAsync(): Promise<never> {\n return Promise.reject(unsupported(\"authenticateAsync\"));\n },\n refreshSessionAsync(): Promise<never> {\n return Promise.reject(unsupported(\"refreshSessionAsync\"));\n },\n appRemoteConnect(): Promise<never> {\n return Promise.reject(unsupported(\"appRemoteConnect\"));\n },\n appRemoteDisconnect(): Promise<never> {\n return Promise.reject(unsupported(\"appRemoteDisconnect\"));\n },\n appRemoteIsConnected(): boolean {\n return false;\n },\n appRemoteGetConnectionState(): Promise<\"disconnected\"> {\n return Promise.resolve(\"disconnected\");\n },\n playerPlay(): Promise<never> {\n return Promise.reject(unsupported(\"playerPlay\"));\n },\n playerPause(): Promise<never> {\n return Promise.reject(unsupported(\"playerPause\"));\n },\n playerResume(): Promise<never> {\n return Promise.reject(unsupported(\"playerResume\"));\n },\n playerSkipNext(): Promise<never> {\n return Promise.reject(unsupported(\"playerSkipNext\"));\n },\n playerSkipPrevious(): Promise<never> {\n return Promise.reject(unsupported(\"playerSkipPrevious\"));\n },\n playerSeekTo(): Promise<never> {\n return Promise.reject(unsupported(\"playerSeekTo\"));\n },\n playerSetShuffle(): Promise<never> {\n return Promise.reject(unsupported(\"playerSetShuffle\"));\n },\n playerSetRepeatMode(): Promise<never> {\n return Promise.reject(unsupported(\"playerSetRepeatMode\"));\n },\n playerSetPodcastPlaybackSpeed(): Promise<never> {\n return Promise.reject(unsupported(\"playerSetPodcastPlaybackSpeed\"));\n },\n playerQueue(): Promise<never> {\n return Promise.reject(unsupported(\"playerQueue\"));\n },\n playerGetPlayerState(): Promise<never> {\n return Promise.reject(unsupported(\"playerGetPlayerState\"));\n },\n playerGetCrossfadeState(): Promise<never> {\n return Promise.reject(unsupported(\"playerGetCrossfadeState\"));\n },\n userGetCapabilities(): Promise<never> {\n return Promise.reject(unsupported(\"userGetCapabilities\"));\n },\n userGetLibraryState(): Promise<never> {\n return Promise.reject(unsupported(\"userGetLibraryState\"));\n },\n userAddToLibrary(): Promise<never> {\n return Promise.reject(unsupported(\"userAddToLibrary\"));\n },\n userRemoveFromLibrary(): Promise<never> {\n return Promise.reject(unsupported(\"userRemoveFromLibrary\"));\n },\n contentGetRecommendedContentItems(): Promise<never> {\n return Promise.reject(unsupported(\"contentGetRecommendedContentItems\"));\n },\n contentGetChildren(): Promise<never> {\n return Promise.reject(unsupported(\"contentGetChildren\"));\n },\n imagesLoad(): Promise<never> {\n return Promise.reject(unsupported(\"imagesLoad\"));\n },\n addListener(): { remove(): void } {\n return { remove() {} };\n },\n removeListeners(): void {\n /* no-op */\n },\n};\n"]}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { SpotifyError } from "../error";
|
|
2
|
+
export type AppRemoteErrorCode = "CONNECTION_FAILED" | "CONNECTION_LOST" | "NOT_CONNECTED" | "UNKNOWN";
|
|
3
|
+
export declare class AppRemoteError extends SpotifyError {
|
|
4
|
+
readonly namespace: "AppRemote";
|
|
5
|
+
readonly code: AppRemoteErrorCode;
|
|
6
|
+
constructor(code: AppRemoteErrorCode, message: string);
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=error.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error.d.ts","sourceRoot":"","sources":["../../src/app-remote/error.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAExC,MAAM,MAAM,kBAAkB,GAC1B,mBAAmB,GACnB,iBAAiB,GACjB,eAAe,GACf,SAAS,CAAC;AAEd,qBAAa,cAAe,SAAQ,YAAY;IAC9C,QAAQ,CAAC,SAAS,EAAG,WAAW,CAAU;IAC1C,QAAQ,CAAC,IAAI,EAAE,kBAAkB,CAAC;gBAEtB,IAAI,EAAE,kBAAkB,EAAE,OAAO,EAAE,MAAM;CAItD"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error.js","sourceRoot":"","sources":["../../src/app-remote/error.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAQxC,MAAM,OAAO,cAAe,SAAQ,YAAY;IACrC,SAAS,GAAG,WAAoB,CAAC;IACjC,IAAI,CAAqB;IAElC,YAAY,IAAwB,EAAE,OAAe;QACnD,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;CACF","sourcesContent":["import { SpotifyError } from \"../error\";\n\nexport type AppRemoteErrorCode =\n | \"CONNECTION_FAILED\"\n | \"CONNECTION_LOST\"\n | \"NOT_CONNECTED\"\n | \"UNKNOWN\";\n\nexport class AppRemoteError extends SpotifyError {\n readonly namespace = \"AppRemote\" as const;\n readonly code: AppRemoteErrorCode;\n\n constructor(code: AppRemoteErrorCode, message: string) {\n super(message);\n this.code = code;\n }\n}\n"]}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import type { EventSubscription } from "expo-modules-core";
|
|
2
|
+
import { type AppRemoteErrorCode } from "./error";
|
|
3
|
+
export type { AppRemoteErrorCode } from "./error";
|
|
4
|
+
export { AppRemoteError } from "./error";
|
|
5
|
+
/** Current state of the IPC connection to the Spotify app. */
|
|
6
|
+
export type ConnectionState = "disconnected" | "connecting" | "connected";
|
|
7
|
+
/** Payload of the `connectionStateChange` event. */
|
|
8
|
+
export interface ConnectionStateChangeEvent {
|
|
9
|
+
state: ConnectionState;
|
|
10
|
+
}
|
|
11
|
+
/** Payload of the `connectionError` event. */
|
|
12
|
+
export interface ConnectionErrorEvent {
|
|
13
|
+
code: AppRemoteErrorCode;
|
|
14
|
+
message: string;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Spotify App Remote namespace. Manages the IPC connection to the running
|
|
18
|
+
* Spotify app. All `Player`, `User`, `Content`, and `Images` calls require an
|
|
19
|
+
* active connection established via `AppRemote.connect()`.
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```ts
|
|
23
|
+
* import { AppRemote } from "@wwdrew/expo-spotify-sdk";
|
|
24
|
+
*
|
|
25
|
+
* // Connect using the access token from Auth.authenticate()
|
|
26
|
+
* await AppRemote.connect(session.accessToken);
|
|
27
|
+
*
|
|
28
|
+
* const sub = AppRemote.addListener("connectionStateChange", ({ state }) => {
|
|
29
|
+
* console.log("connection state:", state);
|
|
30
|
+
* });
|
|
31
|
+
*
|
|
32
|
+
* // later:
|
|
33
|
+
* await AppRemote.disconnect();
|
|
34
|
+
* sub.remove();
|
|
35
|
+
* ```
|
|
36
|
+
*/
|
|
37
|
+
export declare const AppRemote: {
|
|
38
|
+
/**
|
|
39
|
+
* Opens a connection to the running Spotify app using the provided access
|
|
40
|
+
* token. Resolves when the connection is established; rejects with an
|
|
41
|
+
* {@link AppRemoteError} if the connection fails.
|
|
42
|
+
*
|
|
43
|
+
* **Android note:** The access token is accepted for API parity with iOS but
|
|
44
|
+
* the Android App Remote SDK does not accept it directly — it uses the
|
|
45
|
+
* session cached in the Spotify app from your earlier `Auth.authenticate()`
|
|
46
|
+
* call. Ensure `Auth.authenticate()` has succeeded before calling `connect()`.
|
|
47
|
+
*
|
|
48
|
+
* Calling `connect()` while already connected is a no-op.
|
|
49
|
+
*/
|
|
50
|
+
readonly connect: (accessToken: string) => Promise<void>;
|
|
51
|
+
/**
|
|
52
|
+
* Disconnects from the Spotify app. Safe to call when already disconnected.
|
|
53
|
+
* Resolves once the disconnection is complete.
|
|
54
|
+
*/
|
|
55
|
+
readonly disconnect: () => Promise<void>;
|
|
56
|
+
/**
|
|
57
|
+
* Returns `true` if currently connected to the Spotify app.
|
|
58
|
+
* This is a synchronous snapshot — subscribe to `"connectionStateChange"`
|
|
59
|
+
* for reactive updates.
|
|
60
|
+
*/
|
|
61
|
+
readonly isConnected: () => boolean;
|
|
62
|
+
/**
|
|
63
|
+
* Returns the current {@link ConnectionState} synchronously.
|
|
64
|
+
* Subscribe to `"connectionStateChange"` for reactive updates.
|
|
65
|
+
*/
|
|
66
|
+
readonly getConnectionState: () => Promise<ConnectionState>;
|
|
67
|
+
/**
|
|
68
|
+
* Subscribes to connection lifecycle events.
|
|
69
|
+
*
|
|
70
|
+
* | Event | Payload | When |
|
|
71
|
+
* |---|---|---|
|
|
72
|
+
* | `"connectionStateChange"` | `{ state: ConnectionState }` | State transitions |
|
|
73
|
+
* | `"connectionError"` | `{ code, message }` | Connection failures and drops |
|
|
74
|
+
*
|
|
75
|
+
* Returns a `Subscription` — call `.remove()` to unsubscribe.
|
|
76
|
+
*/
|
|
77
|
+
readonly addListener: <E extends "connectionStateChange" | "connectionError">(event: E, listener: E extends "connectionStateChange" ? (event: ConnectionStateChangeEvent) => void : (event: ConnectionErrorEvent) => void) => EventSubscription;
|
|
78
|
+
};
|
|
79
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/app-remote/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAG3D,OAAO,EAAkB,KAAK,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAElE,YAAY,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAClD,OAAO,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAMzC,8DAA8D;AAC9D,MAAM,MAAM,eAAe,GAAG,cAAc,GAAG,YAAY,GAAG,WAAW,CAAC;AAE1E,oDAAoD;AACpD,MAAM,WAAW,0BAA0B;IACzC,KAAK,EAAE,eAAe,CAAC;CACxB;AAED,8CAA8C;AAC9C,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,kBAAkB,CAAC;IACzB,OAAO,EAAE,MAAM,CAAC;CACjB;AAqCD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,SAAS;IACpB;;;;;;;;;;;OAWG;oCACkB,MAAM,KAAG,OAAO,CAAC,IAAI,CAAC;IAM3C;;;OAGG;+BACW,OAAO,CAAC,IAAI,CAAC;IAI3B;;;;OAIG;gCACY,OAAO;IAItB;;;OAGG;uCACmB,OAAO,CAAC,eAAe,CAAC;IAI9C;;;;;;;;;OASG;2BACS,CAAC,SAAS,uBAAuB,GAAG,iBAAiB,SACxD,CAAC,YACE,CAAC,SAAS,uBAAuB,GACvC,CAAC,KAAK,EAAE,0BAA0B,KAAK,IAAI,GAC3C,CAAC,KAAK,EAAE,oBAAoB,KAAK,IAAI,KACxC,iBAAiB;CAUZ,CAAC"}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import ExpoSpotifySDKModule from "../ExpoSpotifySDKModule";
|
|
2
|
+
import { AppRemoteError } from "./error";
|
|
3
|
+
export { AppRemoteError } from "./error";
|
|
4
|
+
// ---------------------------------------------------------------------------
|
|
5
|
+
// Internal helpers
|
|
6
|
+
// ---------------------------------------------------------------------------
|
|
7
|
+
const VALID_APPREMOTE_CODES = new Set([
|
|
8
|
+
"CONNECTION_FAILED",
|
|
9
|
+
"CONNECTION_LOST",
|
|
10
|
+
"NOT_CONNECTED",
|
|
11
|
+
"UNKNOWN",
|
|
12
|
+
]);
|
|
13
|
+
const CAUSE_SEPARATOR = "→ Caused by: ";
|
|
14
|
+
function unwrapReason(message) {
|
|
15
|
+
const idx = message.lastIndexOf(CAUSE_SEPARATOR);
|
|
16
|
+
return idx === -1 ? message : message.slice(idx + CAUSE_SEPARATOR.length);
|
|
17
|
+
}
|
|
18
|
+
function rethrowAsAppRemoteError(err) {
|
|
19
|
+
if (err instanceof AppRemoteError)
|
|
20
|
+
throw err;
|
|
21
|
+
if (err instanceof Error) {
|
|
22
|
+
const reason = unwrapReason(err.message);
|
|
23
|
+
const maybeCode = err.code;
|
|
24
|
+
if (maybeCode && VALID_APPREMOTE_CODES.has(maybeCode)) {
|
|
25
|
+
throw new AppRemoteError(maybeCode, reason);
|
|
26
|
+
}
|
|
27
|
+
throw new AppRemoteError("UNKNOWN", reason);
|
|
28
|
+
}
|
|
29
|
+
throw new AppRemoteError("UNKNOWN", String(err));
|
|
30
|
+
}
|
|
31
|
+
// ---------------------------------------------------------------------------
|
|
32
|
+
// AppRemote namespace
|
|
33
|
+
// ---------------------------------------------------------------------------
|
|
34
|
+
/**
|
|
35
|
+
* Spotify App Remote namespace. Manages the IPC connection to the running
|
|
36
|
+
* Spotify app. All `Player`, `User`, `Content`, and `Images` calls require an
|
|
37
|
+
* active connection established via `AppRemote.connect()`.
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* ```ts
|
|
41
|
+
* import { AppRemote } from "@wwdrew/expo-spotify-sdk";
|
|
42
|
+
*
|
|
43
|
+
* // Connect using the access token from Auth.authenticate()
|
|
44
|
+
* await AppRemote.connect(session.accessToken);
|
|
45
|
+
*
|
|
46
|
+
* const sub = AppRemote.addListener("connectionStateChange", ({ state }) => {
|
|
47
|
+
* console.log("connection state:", state);
|
|
48
|
+
* });
|
|
49
|
+
*
|
|
50
|
+
* // later:
|
|
51
|
+
* await AppRemote.disconnect();
|
|
52
|
+
* sub.remove();
|
|
53
|
+
* ```
|
|
54
|
+
*/
|
|
55
|
+
export const AppRemote = {
|
|
56
|
+
/**
|
|
57
|
+
* Opens a connection to the running Spotify app using the provided access
|
|
58
|
+
* token. Resolves when the connection is established; rejects with an
|
|
59
|
+
* {@link AppRemoteError} if the connection fails.
|
|
60
|
+
*
|
|
61
|
+
* **Android note:** The access token is accepted for API parity with iOS but
|
|
62
|
+
* the Android App Remote SDK does not accept it directly — it uses the
|
|
63
|
+
* session cached in the Spotify app from your earlier `Auth.authenticate()`
|
|
64
|
+
* call. Ensure `Auth.authenticate()` has succeeded before calling `connect()`.
|
|
65
|
+
*
|
|
66
|
+
* Calling `connect()` while already connected is a no-op.
|
|
67
|
+
*/
|
|
68
|
+
connect(accessToken) {
|
|
69
|
+
return ExpoSpotifySDKModule.appRemoteConnect(accessToken).catch(rethrowAsAppRemoteError);
|
|
70
|
+
},
|
|
71
|
+
/**
|
|
72
|
+
* Disconnects from the Spotify app. Safe to call when already disconnected.
|
|
73
|
+
* Resolves once the disconnection is complete.
|
|
74
|
+
*/
|
|
75
|
+
disconnect() {
|
|
76
|
+
return ExpoSpotifySDKModule.appRemoteDisconnect();
|
|
77
|
+
},
|
|
78
|
+
/**
|
|
79
|
+
* Returns `true` if currently connected to the Spotify app.
|
|
80
|
+
* This is a synchronous snapshot — subscribe to `"connectionStateChange"`
|
|
81
|
+
* for reactive updates.
|
|
82
|
+
*/
|
|
83
|
+
isConnected() {
|
|
84
|
+
return ExpoSpotifySDKModule.appRemoteIsConnected();
|
|
85
|
+
},
|
|
86
|
+
/**
|
|
87
|
+
* Returns the current {@link ConnectionState} synchronously.
|
|
88
|
+
* Subscribe to `"connectionStateChange"` for reactive updates.
|
|
89
|
+
*/
|
|
90
|
+
getConnectionState() {
|
|
91
|
+
return ExpoSpotifySDKModule.appRemoteGetConnectionState();
|
|
92
|
+
},
|
|
93
|
+
/**
|
|
94
|
+
* Subscribes to connection lifecycle events.
|
|
95
|
+
*
|
|
96
|
+
* | Event | Payload | When |
|
|
97
|
+
* |---|---|---|
|
|
98
|
+
* | `"connectionStateChange"` | `{ state: ConnectionState }` | State transitions |
|
|
99
|
+
* | `"connectionError"` | `{ code, message }` | Connection failures and drops |
|
|
100
|
+
*
|
|
101
|
+
* Returns a `Subscription` — call `.remove()` to unsubscribe.
|
|
102
|
+
*/
|
|
103
|
+
addListener(event, listener) {
|
|
104
|
+
const nativeEvent = event === "connectionStateChange"
|
|
105
|
+
? "onConnectionStateChange"
|
|
106
|
+
: "onConnectionError";
|
|
107
|
+
return ExpoSpotifySDKModule.addListener(nativeEvent, listener);
|
|
108
|
+
},
|
|
109
|
+
};
|
|
110
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/app-remote/index.ts"],"names":[],"mappings":"AAEA,OAAO,oBAAoB,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,cAAc,EAA2B,MAAM,SAAS,CAAC;AAGlE,OAAO,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAoBzC,8EAA8E;AAC9E,mBAAmB;AACnB,8EAA8E;AAE9E,MAAM,qBAAqB,GAAG,IAAI,GAAG,CAAqB;IACxD,mBAAmB;IACnB,iBAAiB;IACjB,eAAe;IACf,SAAS;CACV,CAAC,CAAC;AAEH,MAAM,eAAe,GAAG,eAAe,CAAC;AAExC,SAAS,YAAY,CAAC,OAAe;IACnC,MAAM,GAAG,GAAG,OAAO,CAAC,WAAW,CAAC,eAAe,CAAC,CAAC;IACjD,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,GAAG,eAAe,CAAC,MAAM,CAAC,CAAC;AAC5E,CAAC;AAED,SAAS,uBAAuB,CAAC,GAAY;IAC3C,IAAI,GAAG,YAAY,cAAc;QAAE,MAAM,GAAG,CAAC;IAC7C,IAAI,GAAG,YAAY,KAAK,EAAE,CAAC;QACzB,MAAM,MAAM,GAAG,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACzC,MAAM,SAAS,GAAI,GAAiC,CAAC,IAAI,CAAC;QAC1D,IAAI,SAAS,IAAI,qBAAqB,CAAC,GAAG,CAAC,SAA+B,CAAC,EAAE,CAAC;YAC5E,MAAM,IAAI,cAAc,CAAC,SAA+B,EAAE,MAAM,CAAC,CAAC;QACpE,CAAC;QACD,MAAM,IAAI,cAAc,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;IAC9C,CAAC;IACD,MAAM,IAAI,cAAc,CAAC,SAAS,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;AACnD,CAAC;AAED,8EAA8E;AAC9E,sBAAsB;AACtB,8EAA8E;AAE9E;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG;IACvB;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,WAAmB;QACzB,OAAO,oBAAoB,CAAC,gBAAgB,CAAC,WAAW,CAAC,CAAC,KAAK,CAC7D,uBAAuB,CACxB,CAAC;IACJ,CAAC;IAED;;;OAGG;IACH,UAAU;QACR,OAAO,oBAAoB,CAAC,mBAAmB,EAAE,CAAC;IACpD,CAAC;IAED;;;;OAIG;IACH,WAAW;QACT,OAAO,oBAAoB,CAAC,oBAAoB,EAAE,CAAC;IACrD,CAAC;IAED;;;OAGG;IACH,kBAAkB;QAChB,OAAO,oBAAoB,CAAC,2BAA2B,EAAE,CAAC;IAC5D,CAAC;IAED;;;;;;;;;OASG;IACH,WAAW,CACT,KAAQ,EACR,QAEyC;QAEzC,MAAM,WAAW,GACf,KAAK,KAAK,uBAAuB;YAC/B,CAAC,CAAC,yBAAyB;YAC3B,CAAC,CAAC,mBAAmB,CAAC;QAC1B,OAAO,oBAAoB,CAAC,WAAW,CACrC,WAAW,EACX,QAAoC,CAChB,CAAC;IACzB,CAAC;CACO,CAAC","sourcesContent":["import type { EventSubscription } from \"expo-modules-core\";\n\nimport ExpoSpotifySDKModule from \"../ExpoSpotifySDKModule\";\nimport { AppRemoteError, type AppRemoteErrorCode } from \"./error\";\n\nexport type { AppRemoteErrorCode } from \"./error\";\nexport { AppRemoteError } from \"./error\";\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/** Current state of the IPC connection to the Spotify app. */\nexport type ConnectionState = \"disconnected\" | \"connecting\" | \"connected\";\n\n/** Payload of the `connectionStateChange` event. */\nexport interface ConnectionStateChangeEvent {\n state: ConnectionState;\n}\n\n/** Payload of the `connectionError` event. */\nexport interface ConnectionErrorEvent {\n code: AppRemoteErrorCode;\n message: string;\n}\n\n// ---------------------------------------------------------------------------\n// Internal helpers\n// ---------------------------------------------------------------------------\n\nconst VALID_APPREMOTE_CODES = new Set<AppRemoteErrorCode>([\n \"CONNECTION_FAILED\",\n \"CONNECTION_LOST\",\n \"NOT_CONNECTED\",\n \"UNKNOWN\",\n]);\n\nconst CAUSE_SEPARATOR = \"→ Caused by: \";\n\nfunction unwrapReason(message: string): string {\n const idx = message.lastIndexOf(CAUSE_SEPARATOR);\n return idx === -1 ? message : message.slice(idx + CAUSE_SEPARATOR.length);\n}\n\nfunction rethrowAsAppRemoteError(err: unknown): never {\n if (err instanceof AppRemoteError) throw err;\n if (err instanceof Error) {\n const reason = unwrapReason(err.message);\n const maybeCode = (err as Error & { code?: string }).code;\n if (maybeCode && VALID_APPREMOTE_CODES.has(maybeCode as AppRemoteErrorCode)) {\n throw new AppRemoteError(maybeCode as AppRemoteErrorCode, reason);\n }\n throw new AppRemoteError(\"UNKNOWN\", reason);\n }\n throw new AppRemoteError(\"UNKNOWN\", String(err));\n}\n\n// ---------------------------------------------------------------------------\n// AppRemote namespace\n// ---------------------------------------------------------------------------\n\n/**\n * Spotify App Remote namespace. Manages the IPC connection to the running\n * Spotify app. All `Player`, `User`, `Content`, and `Images` calls require an\n * active connection established via `AppRemote.connect()`.\n *\n * @example\n * ```ts\n * import { AppRemote } from \"@wwdrew/expo-spotify-sdk\";\n *\n * // Connect using the access token from Auth.authenticate()\n * await AppRemote.connect(session.accessToken);\n *\n * const sub = AppRemote.addListener(\"connectionStateChange\", ({ state }) => {\n * console.log(\"connection state:\", state);\n * });\n *\n * // later:\n * await AppRemote.disconnect();\n * sub.remove();\n * ```\n */\nexport const AppRemote = {\n /**\n * Opens a connection to the running Spotify app using the provided access\n * token. Resolves when the connection is established; rejects with an\n * {@link AppRemoteError} if the connection fails.\n *\n * **Android note:** The access token is accepted for API parity with iOS but\n * the Android App Remote SDK does not accept it directly — it uses the\n * session cached in the Spotify app from your earlier `Auth.authenticate()`\n * call. Ensure `Auth.authenticate()` has succeeded before calling `connect()`.\n *\n * Calling `connect()` while already connected is a no-op.\n */\n connect(accessToken: string): Promise<void> {\n return ExpoSpotifySDKModule.appRemoteConnect(accessToken).catch(\n rethrowAsAppRemoteError,\n );\n },\n\n /**\n * Disconnects from the Spotify app. Safe to call when already disconnected.\n * Resolves once the disconnection is complete.\n */\n disconnect(): Promise<void> {\n return ExpoSpotifySDKModule.appRemoteDisconnect();\n },\n\n /**\n * Returns `true` if currently connected to the Spotify app.\n * This is a synchronous snapshot — subscribe to `\"connectionStateChange\"`\n * for reactive updates.\n */\n isConnected(): boolean {\n return ExpoSpotifySDKModule.appRemoteIsConnected();\n },\n\n /**\n * Returns the current {@link ConnectionState} synchronously.\n * Subscribe to `\"connectionStateChange\"` for reactive updates.\n */\n getConnectionState(): Promise<ConnectionState> {\n return ExpoSpotifySDKModule.appRemoteGetConnectionState();\n },\n\n /**\n * Subscribes to connection lifecycle events.\n *\n * | Event | Payload | When |\n * |---|---|---|\n * | `\"connectionStateChange\"` | `{ state: ConnectionState }` | State transitions |\n * | `\"connectionError\"` | `{ code, message }` | Connection failures and drops |\n *\n * Returns a `Subscription` — call `.remove()` to unsubscribe.\n */\n addListener<E extends \"connectionStateChange\" | \"connectionError\">(\n event: E,\n listener: E extends \"connectionStateChange\"\n ? (event: ConnectionStateChangeEvent) => void\n : (event: ConnectionErrorEvent) => void,\n ): EventSubscription {\n const nativeEvent =\n event === \"connectionStateChange\"\n ? \"onConnectionStateChange\"\n : \"onConnectionError\";\n return ExpoSpotifySDKModule.addListener(\n nativeEvent,\n listener as (event: unknown) => void,\n ) as EventSubscription;\n },\n} as const;\n"]}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { SpotifyError } from "../error";
|
|
2
|
+
export type AuthErrorCode = "USER_CANCELLED" | "AUTH_IN_PROGRESS" | "INVALID_CONFIG" | "NETWORK_ERROR" | "TOKEN_SWAP_FAILED" | "TOKEN_SWAP_PARSE_ERROR" | "SPOTIFY_NOT_INSTALLED" | "AUTH_ERROR" | "UNKNOWN";
|
|
3
|
+
export declare class AuthError extends SpotifyError {
|
|
4
|
+
readonly namespace: "Auth";
|
|
5
|
+
readonly code: AuthErrorCode;
|
|
6
|
+
constructor(code: AuthErrorCode, message: string);
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=error.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error.d.ts","sourceRoot":"","sources":["../../src/auth/error.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAExC,MAAM,MAAM,aAAa,GACrB,gBAAgB,GAChB,kBAAkB,GAClB,gBAAgB,GAChB,eAAe,GACf,mBAAmB,GACnB,wBAAwB,GACxB,uBAAuB,GACvB,YAAY,GACZ,SAAS,CAAC;AAEd,qBAAa,SAAU,SAAQ,YAAY;IACzC,QAAQ,CAAC,SAAS,EAAG,MAAM,CAAU;IACrC,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;gBAEjB,IAAI,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM;CAIjD"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error.js","sourceRoot":"","sources":["../../src/auth/error.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAaxC,MAAM,OAAO,SAAU,SAAQ,YAAY;IAChC,SAAS,GAAG,MAAe,CAAC;IAC5B,IAAI,CAAgB;IAE7B,YAAY,IAAmB,EAAE,OAAe;QAC9C,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;CACF","sourcesContent":["import { SpotifyError } from \"../error\";\n\nexport type AuthErrorCode =\n | \"USER_CANCELLED\"\n | \"AUTH_IN_PROGRESS\"\n | \"INVALID_CONFIG\"\n | \"NETWORK_ERROR\"\n | \"TOKEN_SWAP_FAILED\"\n | \"TOKEN_SWAP_PARSE_ERROR\"\n | \"SPOTIFY_NOT_INSTALLED\"\n | \"AUTH_ERROR\"\n | \"UNKNOWN\";\n\nexport class AuthError extends SpotifyError {\n readonly namespace = \"Auth\" as const;\n readonly code: AuthErrorCode;\n\n constructor(code: AuthErrorCode, message: string) {\n super(message);\n this.code = code;\n }\n}\n"]}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import type { EventSubscription } from "expo-modules-core";
|
|
2
|
+
import { type AuthErrorCode } from "./error";
|
|
3
|
+
export type { AuthErrorCode } from "./error";
|
|
4
|
+
export { AuthError } from "./error";
|
|
5
|
+
export interface SpotifySession {
|
|
6
|
+
/** OAuth access token. */
|
|
7
|
+
accessToken: string;
|
|
8
|
+
/**
|
|
9
|
+
* OAuth refresh token. `null` on Android when no `tokenSwapURL` is provided
|
|
10
|
+
* (the Spotify Android SDK does not expose a refresh token for implicit
|
|
11
|
+
* grants).
|
|
12
|
+
*/
|
|
13
|
+
refreshToken: string | null;
|
|
14
|
+
/** Expiration timestamp as Unix epoch milliseconds. */
|
|
15
|
+
expirationDate: number;
|
|
16
|
+
/** Scopes the access token was granted (or requested, on Android implicit). */
|
|
17
|
+
scopes: SpotifyScope[];
|
|
18
|
+
}
|
|
19
|
+
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";
|
|
20
|
+
export interface AuthenticateConfig {
|
|
21
|
+
/** OAuth scopes to request. Must contain at least one entry. */
|
|
22
|
+
scopes: SpotifyScope[];
|
|
23
|
+
/**
|
|
24
|
+
* If supplied, requests an authorization code rather than an implicit
|
|
25
|
+
* token, then POSTs the code to this URL to exchange it for tokens.
|
|
26
|
+
* **Required on Android** to receive a usable `refreshToken`.
|
|
27
|
+
*/
|
|
28
|
+
tokenSwapURL?: string;
|
|
29
|
+
/**
|
|
30
|
+
* Used by the iOS SDK to refresh access tokens automatically, and by
|
|
31
|
+
* `Auth.refresh()` on both platforms.
|
|
32
|
+
*/
|
|
33
|
+
tokenRefreshURL?: string;
|
|
34
|
+
/**
|
|
35
|
+
* If `true`, forces Spotify to show the authorization dialog even when the
|
|
36
|
+
* user already has an active session. Defaults to `false`.
|
|
37
|
+
*/
|
|
38
|
+
showDialog?: boolean;
|
|
39
|
+
}
|
|
40
|
+
export interface RefreshConfig {
|
|
41
|
+
/** The refresh token from a previous `Auth.authenticate()` call. */
|
|
42
|
+
refreshToken: string;
|
|
43
|
+
/** URL of your token refresh server endpoint. */
|
|
44
|
+
tokenRefreshURL: string;
|
|
45
|
+
/**
|
|
46
|
+
* Scopes that were granted by the previous session. Used as a fallback when
|
|
47
|
+
* the refresh response omits the `scope` field.
|
|
48
|
+
*/
|
|
49
|
+
scopes?: SpotifyScope[];
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Payload delivered to `Auth.addListener("sessionChange", ...)` subscribers.
|
|
53
|
+
*/
|
|
54
|
+
export type SessionChangeEvent = {
|
|
55
|
+
type: "didInitiate";
|
|
56
|
+
session: SpotifySession;
|
|
57
|
+
} | {
|
|
58
|
+
type: "didRenew";
|
|
59
|
+
session: SpotifySession;
|
|
60
|
+
} | {
|
|
61
|
+
type: "didFail";
|
|
62
|
+
error: {
|
|
63
|
+
code: AuthErrorCode;
|
|
64
|
+
message: string;
|
|
65
|
+
};
|
|
66
|
+
};
|
|
67
|
+
/**
|
|
68
|
+
* Spotify Auth namespace. Handles OAuth authentication and session lifecycle.
|
|
69
|
+
*
|
|
70
|
+
* @example
|
|
71
|
+
* ```ts
|
|
72
|
+
* import { Auth } from "@wwdrew/expo-spotify-sdk";
|
|
73
|
+
*
|
|
74
|
+
* const session = await Auth.authenticate({ scopes: ["streaming"] });
|
|
75
|
+
* ```
|
|
76
|
+
*/
|
|
77
|
+
export declare const Auth: {
|
|
78
|
+
/**
|
|
79
|
+
* Returns `true` if the Spotify app is installed on the device.
|
|
80
|
+
*/
|
|
81
|
+
readonly isAvailable: () => boolean;
|
|
82
|
+
/**
|
|
83
|
+
* Starts a Spotify OAuth flow. Resolves with a {@link SpotifySession};
|
|
84
|
+
* rejects with an {@link AuthError} carrying a `code`.
|
|
85
|
+
*/
|
|
86
|
+
readonly authenticate: (config: AuthenticateConfig) => Promise<SpotifySession>;
|
|
87
|
+
/**
|
|
88
|
+
* Exchanges a refresh token for a new access token via your token refresh
|
|
89
|
+
* server. Resolves with a fresh {@link SpotifySession}; rejects with an
|
|
90
|
+
* {@link AuthError}.
|
|
91
|
+
*/
|
|
92
|
+
readonly refresh: (config: RefreshConfig) => Promise<SpotifySession>;
|
|
93
|
+
/**
|
|
94
|
+
* Forcibly cancel any in-flight `Auth.authenticate()` call. No-op on
|
|
95
|
+
* Android (the Android coordinator self-cleans via structured concurrency).
|
|
96
|
+
*
|
|
97
|
+
* Use before `Auth.authenticate()` to defensively clear any leaked iOS
|
|
98
|
+
* coordinator state (the `SPTSessionManager` delegate callbacks are not
|
|
99
|
+
* guaranteed to fire).
|
|
100
|
+
*/
|
|
101
|
+
readonly cancelPending: () => Promise<void>;
|
|
102
|
+
/**
|
|
103
|
+
* Subscribes to session lifecycle events.
|
|
104
|
+
*
|
|
105
|
+
* Events fire for every `Auth.authenticate()` and `Auth.refresh()` call,
|
|
106
|
+
* regardless of whether the call was awaited. Useful for persisting tokens
|
|
107
|
+
* in a central store without coupling the store to the call sites.
|
|
108
|
+
*
|
|
109
|
+
* Returns a `Subscription` — call `.remove()` to unsubscribe.
|
|
110
|
+
*
|
|
111
|
+
* @example
|
|
112
|
+
* ```ts
|
|
113
|
+
* const sub = Auth.addListener("sessionChange", (event) => {
|
|
114
|
+
* if (event.type === "didInitiate" || event.type === "didRenew") {
|
|
115
|
+
* store.setSession(event.session);
|
|
116
|
+
* }
|
|
117
|
+
* });
|
|
118
|
+
* // later:
|
|
119
|
+
* sub.remove();
|
|
120
|
+
* ```
|
|
121
|
+
*/
|
|
122
|
+
readonly addListener: (event: "sessionChange", listener: (event: SessionChangeEvent) => void) => EventSubscription;
|
|
123
|
+
};
|
|
124
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/auth/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAI3D,OAAO,EAAa,KAAK,aAAa,EAAE,MAAM,SAAS,CAAC;AAExD,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC7C,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAMpC,MAAM,WAAW,cAAc;IAC7B,0BAA0B;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB;;;;OAIG;IACH,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,uDAAuD;IACvD,cAAc,EAAE,MAAM,CAAC;IACvB,+EAA+E;IAC/E,MAAM,EAAE,YAAY,EAAE,CAAC;CACxB;AAED,MAAM,MAAM,YAAY,GACpB,kBAAkB,GAClB,0BAA0B,GAC1B,4BAA4B,GAC5B,6BAA6B,GAC7B,oBAAoB,GACpB,WAAW,GACX,uBAAuB,GACvB,6BAA6B,GAC7B,yBAAyB,GACzB,wBAAwB,GACxB,oBAAoB,GACpB,kBAAkB,GAClB,eAAe,GACf,2BAA2B,GAC3B,qBAAqB,GACrB,mBAAmB,GACnB,iBAAiB,GACjB,mBAAmB,CAAC;AAExB,MAAM,WAAW,kBAAkB;IACjC,gEAAgE;IAChE,MAAM,EAAE,YAAY,EAAE,CAAC;IACvB;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;OAGG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,aAAa;IAC5B,oEAAoE;IACpE,YAAY,EAAE,MAAM,CAAC;IACrB,iDAAiD;IACjD,eAAe,EAAE,MAAM,CAAC;IACxB;;;OAGG;IACH,MAAM,CAAC,EAAE,YAAY,EAAE,CAAC;CACzB;AAED;;GAEG;AACH,MAAM,MAAM,kBAAkB,GAC1B;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,OAAO,EAAE,cAAc,CAAA;CAAE,GAChD;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,OAAO,EAAE,cAAc,CAAA;CAAE,GAC7C;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,KAAK,EAAE;QAAE,IAAI,EAAE,aAAa,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,CAAC;AAgFzE;;;;;;;;;GASG;AACH,eAAO,MAAM,IAAI;IACf;;OAEG;gCACY,OAAO;IAItB;;;OAGG;oCACkB,kBAAkB,KAAG,OAAO,CAAC,cAAc,CAAC;IAmBjE;;;;OAIG;+BACa,aAAa,KAAG,OAAO,CAAC,cAAc,CAAC;IAgBvD;;;;;;;OAOG;kCACc,OAAO,CAAC,IAAI,CAAC;IAO9B;;;;;;;;;;;;;;;;;;;OAmBG;kCAEM,eAAe,YACZ,CAAC,KAAK,EAAE,kBAAkB,KAAK,IAAI,KAC5C,iBAAiB;CAMZ,CAAC"}
|