@wwdrew/expo-apple-music 1.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/ATTRIBUTION.md +24 -0
- package/LICENSE +190 -0
- package/NOTICE +7 -0
- package/README.md +81 -0
- package/android/build.gradle +26 -0
- package/android/libs/mediaplayback-release-1.1.1.aar +0 -0
- package/android/libs/musickitauth-release-1.1.2.aar +0 -0
- package/android/src/main/AndroidManifest.xml +16 -0
- package/android/src/main/java/expo/modules/applemusic/AndroidCatalogService.kt +86 -0
- package/android/src/main/java/expo/modules/applemusic/AndroidDeveloperToken.kt +39 -0
- package/android/src/main/java/expo/modules/applemusic/AndroidHistoryService.kt +24 -0
- package/android/src/main/java/expo/modules/applemusic/AndroidLibraryMutationsService.kt +30 -0
- package/android/src/main/java/expo/modules/applemusic/AndroidLibraryService.kt +61 -0
- package/android/src/main/java/expo/modules/applemusic/AndroidPlaybackController.kt +484 -0
- package/android/src/main/java/expo/modules/applemusic/AndroidPlaybackObserver.kt +173 -0
- package/android/src/main/java/expo/modules/applemusic/AndroidQueueService.kt +78 -0
- package/android/src/main/java/expo/modules/applemusic/AndroidRatingsService.kt +27 -0
- package/android/src/main/java/expo/modules/applemusic/AndroidRecommendationsService.kt +15 -0
- package/android/src/main/java/expo/modules/applemusic/AndroidSubscriptionService.kt +24 -0
- package/android/src/main/java/expo/modules/applemusic/AppleMusicErrorCodes.kt +13 -0
- package/android/src/main/java/expo/modules/applemusic/AppleMusicErrors.kt +46 -0
- package/android/src/main/java/expo/modules/applemusic/AppleMusicHttpMethod.kt +8 -0
- package/android/src/main/java/expo/modules/applemusic/AppleMusicJsonMapper.kt +258 -0
- package/android/src/main/java/expo/modules/applemusic/AppleMusicNativeLoader.kt +32 -0
- package/android/src/main/java/expo/modules/applemusic/AppleMusicRestJson.kt +40 -0
- package/android/src/main/java/expo/modules/applemusic/AppleMusicRestQuery.kt +12 -0
- package/android/src/main/java/expo/modules/applemusic/AppleMusicRestStack.kt +19 -0
- package/android/src/main/java/expo/modules/applemusic/AppleMusicRestTransport.kt +118 -0
- package/android/src/main/java/expo/modules/applemusic/AuthenticatedSession.kt +57 -0
- package/android/src/main/java/expo/modules/applemusic/BridgeResponses.kt +55 -0
- package/android/src/main/java/expo/modules/applemusic/CatalogRestClient.kt +306 -0
- package/android/src/main/java/expo/modules/applemusic/ExpoAppleMusicModule.kt +152 -0
- package/android/src/main/java/expo/modules/applemusic/HistoryRestClient.kt +60 -0
- package/android/src/main/java/expo/modules/applemusic/LibraryIds.kt +6 -0
- package/android/src/main/java/expo/modules/applemusic/LibraryMutationsRestClient.kt +95 -0
- package/android/src/main/java/expo/modules/applemusic/LibraryRestClient.kt +195 -0
- package/android/src/main/java/expo/modules/applemusic/MusicKitAuthContract.kt +78 -0
- package/android/src/main/java/expo/modules/applemusic/MusicKitAuthStorage.kt +76 -0
- package/android/src/main/java/expo/modules/applemusic/MusicKitTokenProvider.kt +13 -0
- package/android/src/main/java/expo/modules/applemusic/PaginationOptions.kt +14 -0
- package/android/src/main/java/expo/modules/applemusic/RatingsRestClient.kt +72 -0
- package/android/src/main/java/expo/modules/applemusic/RecommendationsRestClient.kt +37 -0
- package/android/src/main/java/expo/modules/applemusic/StorefrontRestClient.kt +44 -0
- package/android/src/main/java/expo/modules/applemusic/bridge/ExpoBridgeAuth.kt +69 -0
- package/android/src/main/java/expo/modules/applemusic/bridge/ExpoBridgeCatalog.kt +76 -0
- package/android/src/main/java/expo/modules/applemusic/bridge/ExpoBridgeHistory.kt +35 -0
- package/android/src/main/java/expo/modules/applemusic/bridge/ExpoBridgeLibrary.kt +54 -0
- package/android/src/main/java/expo/modules/applemusic/bridge/ExpoBridgeLibraryMutations.kt +30 -0
- package/android/src/main/java/expo/modules/applemusic/bridge/ExpoBridgePlayer.kt +89 -0
- package/android/src/main/java/expo/modules/applemusic/bridge/ExpoBridgeRatings.kt +29 -0
- package/android/src/main/java/expo/modules/applemusic/bridge/ExpoBridgeRecommendations.kt +18 -0
- package/app.plugin.js +1 -0
- package/build/ExpoAppleMusicModule.web.d.ts +15 -0
- package/build/ExpoAppleMusicModule.web.d.ts.map +1 -0
- package/build/ExpoAppleMusicModule.web.js +33 -0
- package/build/ExpoAppleMusicModule.web.js.map +1 -0
- package/build/api/call-native.d.ts +6 -0
- package/build/api/call-native.d.ts.map +1 -0
- package/build/api/call-native.js +35 -0
- package/build/api/call-native.js.map +1 -0
- package/build/api/decode-jwt-exp.d.ts +5 -0
- package/build/api/decode-jwt-exp.d.ts.map +1 -0
- package/build/api/decode-jwt-exp.js +28 -0
- package/build/api/decode-jwt-exp.js.map +1 -0
- package/build/api/library-ids.d.ts +4 -0
- package/build/api/library-ids.d.ts.map +1 -0
- package/build/api/library-ids.js +11 -0
- package/build/api/library-ids.js.map +1 -0
- package/build/api/pagination.d.ts +12 -0
- package/build/api/pagination.d.ts.map +1 -0
- package/build/api/pagination.js +13 -0
- package/build/api/pagination.js.map +1 -0
- package/build/api/parse-authorize-result.d.ts +3 -0
- package/build/api/parse-authorize-result.d.ts.map +1 -0
- package/build/api/parse-authorize-result.js +27 -0
- package/build/api/parse-authorize-result.js.map +1 -0
- package/build/api/require-music-user-token.d.ts +2 -0
- package/build/api/require-music-user-token.d.ts.map +1 -0
- package/build/api/require-music-user-token.js +14 -0
- package/build/api/require-music-user-token.js.map +1 -0
- package/build/api/sync-developer-token.d.ts +4 -0
- package/build/api/sync-developer-token.d.ts.map +1 -0
- package/build/api/sync-developer-token.js +27 -0
- package/build/api/sync-developer-token.js.map +1 -0
- package/build/bridge/bridge-methods.d.ts +17 -0
- package/build/bridge/bridge-methods.d.ts.map +1 -0
- package/build/bridge/bridge-methods.js +71 -0
- package/build/bridge/bridge-methods.js.map +1 -0
- package/build/bridge/bridge-responses.d.ts +64 -0
- package/build/bridge/bridge-responses.d.ts.map +1 -0
- package/build/bridge/bridge-responses.js +67 -0
- package/build/bridge/bridge-responses.js.map +1 -0
- package/build/bridge/handlers/auth-bridge.d.ts +11 -0
- package/build/bridge/handlers/auth-bridge.d.ts.map +1 -0
- package/build/bridge/handlers/auth-bridge.js +49 -0
- package/build/bridge/handlers/auth-bridge.js.map +1 -0
- package/build/bridge/handlers/catalog-bridge.d.ts +34 -0
- package/build/bridge/handlers/catalog-bridge.d.ts.map +1 -0
- package/build/bridge/handlers/catalog-bridge.js +58 -0
- package/build/bridge/handlers/catalog-bridge.js.map +1 -0
- package/build/bridge/handlers/history-bridge.d.ts +19 -0
- package/build/bridge/handlers/history-bridge.d.ts.map +1 -0
- package/build/bridge/handlers/history-bridge.js +31 -0
- package/build/bridge/handlers/history-bridge.js.map +1 -0
- package/build/bridge/handlers/index.d.ts +124 -0
- package/build/bridge/handlers/index.d.ts.map +1 -0
- package/build/bridge/handlers/index.js +21 -0
- package/build/bridge/handlers/index.js.map +1 -0
- package/build/bridge/handlers/library-bridge.d.ts +23 -0
- package/build/bridge/handlers/library-bridge.d.ts.map +1 -0
- package/build/bridge/handlers/library-bridge.js +41 -0
- package/build/bridge/handlers/library-bridge.js.map +1 -0
- package/build/bridge/handlers/library-mutations-bridge.d.ts +16 -0
- package/build/bridge/handlers/library-mutations-bridge.d.ts.map +1 -0
- package/build/bridge/handlers/library-mutations-bridge.js +20 -0
- package/build/bridge/handlers/library-mutations-bridge.js.map +1 -0
- package/build/bridge/handlers/player-bridge.d.ts +18 -0
- package/build/bridge/handlers/player-bridge.d.ts.map +1 -0
- package/build/bridge/handlers/player-bridge.js +42 -0
- package/build/bridge/handlers/player-bridge.js.map +1 -0
- package/build/bridge/handlers/ratings-bridge.d.ts +15 -0
- package/build/bridge/handlers/ratings-bridge.d.ts.map +1 -0
- package/build/bridge/handlers/ratings-bridge.js +16 -0
- package/build/bridge/handlers/ratings-bridge.js.map +1 -0
- package/build/bridge/handlers/recommendations-bridge.d.ts +10 -0
- package/build/bridge/handlers/recommendations-bridge.d.ts.map +1 -0
- package/build/bridge/handlers/recommendations-bridge.js +14 -0
- package/build/bridge/handlers/recommendations-bridge.js.map +1 -0
- package/build/constants/apple-music-error-codes.d.ts +22 -0
- package/build/constants/apple-music-error-codes.d.ts.map +1 -0
- package/build/constants/apple-music-error-codes.js +21 -0
- package/build/constants/apple-music-error-codes.js.map +1 -0
- package/build/hooks/use-current-song.d.ts +10 -0
- package/build/hooks/use-current-song.d.ts.map +1 -0
- package/build/hooks/use-current-song.js +35 -0
- package/build/hooks/use-current-song.js.map +1 -0
- package/build/hooks/use-is-playing.d.ts +6 -0
- package/build/hooks/use-is-playing.d.ts.map +1 -0
- package/build/hooks/use-is-playing.js +21 -0
- package/build/hooks/use-is-playing.js.map +1 -0
- package/build/hooks/use-playback-state.d.ts +12 -0
- package/build/hooks/use-playback-state.d.ts.map +1 -0
- package/build/hooks/use-playback-state.js +41 -0
- package/build/hooks/use-playback-state.js.map +1 -0
- package/build/index.d.ts +52 -0
- package/build/index.d.ts.map +1 -0
- package/build/index.js +44 -0
- package/build/index.js.map +1 -0
- package/build/mappers/apple-music-json-mapper.d.ts +94 -0
- package/build/mappers/apple-music-json-mapper.d.ts.map +1 -0
- package/build/mappers/apple-music-json-mapper.js +212 -0
- package/build/mappers/apple-music-json-mapper.js.map +1 -0
- package/build/modules/auth.d.ts +32 -0
- package/build/modules/auth.d.ts.map +1 -0
- package/build/modules/auth.js +60 -0
- package/build/modules/auth.js.map +1 -0
- package/build/modules/catalog.d.ts +46 -0
- package/build/modules/catalog.d.ts.map +1 -0
- package/build/modules/catalog.js +47 -0
- package/build/modules/catalog.js.map +1 -0
- package/build/modules/history.d.ts +17 -0
- package/build/modules/history.d.ts.map +1 -0
- package/build/modules/history.js +28 -0
- package/build/modules/history.js.map +1 -0
- package/build/modules/library-mutations.d.ts +9 -0
- package/build/modules/library-mutations.d.ts.map +1 -0
- package/build/modules/library-mutations.js +41 -0
- package/build/modules/library-mutations.js.map +1 -0
- package/build/modules/library.d.ts +21 -0
- package/build/modules/library.d.ts.map +1 -0
- package/build/modules/library.js +38 -0
- package/build/modules/library.js.map +1 -0
- package/build/modules/player.d.ts +53 -0
- package/build/modules/player.d.ts.map +1 -0
- package/build/modules/player.js +68 -0
- package/build/modules/player.js.map +1 -0
- package/build/modules/ratings.d.ts +10 -0
- package/build/modules/ratings.d.ts.map +1 -0
- package/build/modules/ratings.js +37 -0
- package/build/modules/ratings.js.map +1 -0
- package/build/modules/recommendations.d.ts +7 -0
- package/build/modules/recommendations.d.ts.map +1 -0
- package/build/modules/recommendations.js +15 -0
- package/build/modules/recommendations.js.map +1 -0
- package/build/native-module.d.ts +5 -0
- package/build/native-module.d.ts.map +1 -0
- package/build/native-module.js +5 -0
- package/build/native-module.js.map +1 -0
- package/build/native-module.web.d.ts +11 -0
- package/build/native-module.web.d.ts.map +1 -0
- package/build/native-module.web.js +11 -0
- package/build/native-module.web.js.map +1 -0
- package/build/rest/apple-music-rest-stack.d.ts +21 -0
- package/build/rest/apple-music-rest-stack.d.ts.map +1 -0
- package/build/rest/apple-music-rest-stack.js +21 -0
- package/build/rest/apple-music-rest-stack.js.map +1 -0
- package/build/rest/apple-music-rest-transport.d.ts +8 -0
- package/build/rest/apple-music-rest-transport.d.ts.map +1 -0
- package/build/rest/apple-music-rest-transport.js +2 -0
- package/build/rest/apple-music-rest-transport.js.map +1 -0
- package/build/rest/catalog-rest-client.d.ts +38 -0
- package/build/rest/catalog-rest-client.d.ts.map +1 -0
- package/build/rest/catalog-rest-client.js +189 -0
- package/build/rest/catalog-rest-client.js.map +1 -0
- package/build/rest/history-rest-client.d.ts +37 -0
- package/build/rest/history-rest-client.d.ts.map +1 -0
- package/build/rest/history-rest-client.js +30 -0
- package/build/rest/history-rest-client.js.map +1 -0
- package/build/rest/library-ids.d.ts +2 -0
- package/build/rest/library-ids.d.ts.map +1 -0
- package/build/rest/library-ids.js +2 -0
- package/build/rest/library-ids.js.map +1 -0
- package/build/rest/library-mutations-rest-client.d.ts +22 -0
- package/build/rest/library-mutations-rest-client.d.ts.map +1 -0
- package/build/rest/library-mutations-rest-client.js +37 -0
- package/build/rest/library-mutations-rest-client.js.map +1 -0
- package/build/rest/library-rest-client.d.ts +59 -0
- package/build/rest/library-rest-client.d.ts.map +1 -0
- package/build/rest/library-rest-client.js +141 -0
- package/build/rest/library-rest-client.js.map +1 -0
- package/build/rest/ratings-rest-client.d.ts +18 -0
- package/build/rest/ratings-rest-client.d.ts.map +1 -0
- package/build/rest/ratings-rest-client.js +37 -0
- package/build/rest/ratings-rest-client.js.map +1 -0
- package/build/rest/recommendations-rest-client.d.ts +32 -0
- package/build/rest/recommendations-rest-client.d.ts.map +1 -0
- package/build/rest/recommendations-rest-client.js +26 -0
- package/build/rest/recommendations-rest-client.js.map +1 -0
- package/build/rest/resource-ids-query.d.ts +2 -0
- package/build/rest/resource-ids-query.d.ts.map +1 -0
- package/build/rest/resource-ids-query.js +10 -0
- package/build/rest/resource-ids-query.js.map +1 -0
- package/build/rest/rest-json.d.ts +11 -0
- package/build/rest/rest-json.d.ts.map +1 -0
- package/build/rest/rest-json.js +29 -0
- package/build/rest/rest-json.js.map +1 -0
- package/build/rest/storefront-rest-client.d.ts +14 -0
- package/build/rest/storefront-rest-client.d.ts.map +1 -0
- package/build/rest/storefront-rest-client.js +36 -0
- package/build/rest/storefront-rest-client.js.map +1 -0
- package/build/types/album.d.ts +8 -0
- package/build/types/album.d.ts.map +1 -0
- package/build/types/album.js +2 -0
- package/build/types/album.js.map +1 -0
- package/build/types/albums-response.d.ts +5 -0
- package/build/types/albums-response.d.ts.map +1 -0
- package/build/types/albums-response.js +2 -0
- package/build/types/albums-response.js.map +1 -0
- package/build/types/android-authorize-options.d.ts +18 -0
- package/build/types/android-authorize-options.d.ts.map +1 -0
- package/build/types/android-authorize-options.js +2 -0
- package/build/types/android-authorize-options.js.map +1 -0
- package/build/types/artist.d.ts +9 -0
- package/build/types/artist.d.ts.map +1 -0
- package/build/types/artist.js +2 -0
- package/build/types/artist.js.map +1 -0
- package/build/types/auth-status.d.ts +19 -0
- package/build/types/auth-status.d.ts.map +1 -0
- package/build/types/auth-status.js +18 -0
- package/build/types/auth-status.js.map +1 -0
- package/build/types/authorize-result.d.ts +8 -0
- package/build/types/authorize-result.d.ts.map +1 -0
- package/build/types/authorize-result.js +2 -0
- package/build/types/authorize-result.js.map +1 -0
- package/build/types/catalog-album-tracks.d.ts +5 -0
- package/build/types/catalog-album-tracks.d.ts.map +1 -0
- package/build/types/catalog-album-tracks.js +2 -0
- package/build/types/catalog-album-tracks.js.map +1 -0
- package/build/types/catalog-charts.d.ts +25 -0
- package/build/types/catalog-charts.d.ts.map +1 -0
- package/build/types/catalog-charts.js +7 -0
- package/build/types/catalog-charts.js.map +1 -0
- package/build/types/catalog-resource-type.d.ts +11 -0
- package/build/types/catalog-resource-type.d.ts.map +1 -0
- package/build/types/catalog-resource-type.js +10 -0
- package/build/types/catalog-resource-type.js.map +1 -0
- package/build/types/catalog-search.d.ts +24 -0
- package/build/types/catalog-search.d.ts.map +1 -0
- package/build/types/catalog-search.js +9 -0
- package/build/types/catalog-search.js.map +1 -0
- package/build/types/check-subscription.d.ts +31 -0
- package/build/types/check-subscription.d.ts.map +1 -0
- package/build/types/check-subscription.js +5 -0
- package/build/types/check-subscription.js.map +1 -0
- package/build/types/library-music-videos.d.ts +5 -0
- package/build/types/library-music-videos.d.ts.map +1 -0
- package/build/types/library-music-videos.js +2 -0
- package/build/types/library-music-videos.js.map +1 -0
- package/build/types/library-mutations.d.ts +21 -0
- package/build/types/library-mutations.d.ts.map +1 -0
- package/build/types/library-mutations.js +8 -0
- package/build/types/library-mutations.js.map +1 -0
- package/build/types/library-search.d.ts +22 -0
- package/build/types/library-search.d.ts.map +1 -0
- package/build/types/library-search.js +9 -0
- package/build/types/library-search.js.map +1 -0
- package/build/types/music-item.d.ts +8 -0
- package/build/types/music-item.d.ts.map +1 -0
- package/build/types/music-item.js +7 -0
- package/build/types/music-item.js.map +1 -0
- package/build/types/music-video.d.ts +8 -0
- package/build/types/music-video.d.ts.map +1 -0
- package/build/types/music-video.js +2 -0
- package/build/types/music-video.js.map +1 -0
- package/build/types/pagination.d.ts +11 -0
- package/build/types/pagination.d.ts.map +1 -0
- package/build/types/pagination.js +2 -0
- package/build/types/pagination.js.map +1 -0
- package/build/types/playback-state.d.ts +9 -0
- package/build/types/playback-state.d.ts.map +1 -0
- package/build/types/playback-state.js +2 -0
- package/build/types/playback-state.js.map +1 -0
- package/build/types/playback-status.d.ts +10 -0
- package/build/types/playback-status.d.ts.map +1 -0
- package/build/types/playback-status.js +9 -0
- package/build/types/playback-status.js.map +1 -0
- package/build/types/playlist.d.ts +15 -0
- package/build/types/playlist.d.ts.map +1 -0
- package/build/types/playlist.js +2 -0
- package/build/types/playlist.js.map +1 -0
- package/build/types/rating.d.ts +34 -0
- package/build/types/rating.d.ts.map +1 -0
- package/build/types/rating.js +26 -0
- package/build/types/rating.js.map +1 -0
- package/build/types/recent-resource.d.ts +11 -0
- package/build/types/recent-resource.d.ts.map +1 -0
- package/build/types/recent-resource.js +2 -0
- package/build/types/recent-resource.js.map +1 -0
- package/build/types/recommendation.d.ts +37 -0
- package/build/types/recommendation.d.ts.map +1 -0
- package/build/types/recommendation.js +2 -0
- package/build/types/recommendation.js.map +1 -0
- package/build/types/song.d.ts +8 -0
- package/build/types/song.d.ts.map +1 -0
- package/build/types/song.js +2 -0
- package/build/types/song.js.map +1 -0
- package/build/types/station.d.ts +9 -0
- package/build/types/station.d.ts.map +1 -0
- package/build/types/station.js +2 -0
- package/build/types/station.js.map +1 -0
- package/build/types/storefront.d.ts +4 -0
- package/build/types/storefront.d.ts.map +1 -0
- package/build/types/storefront.js +2 -0
- package/build/types/storefront.js.map +1 -0
- package/build/types/tracks-from-library.d.ts +11 -0
- package/build/types/tracks-from-library.d.ts.map +1 -0
- package/build/types/tracks-from-library.js +2 -0
- package/build/types/tracks-from-library.js.map +1 -0
- package/build/utils/apple-music-error.d.ts +10 -0
- package/build/utils/apple-music-error.d.ts.map +1 -0
- package/build/utils/apple-music-error.js +13 -0
- package/build/utils/apple-music-error.js.map +1 -0
- package/build/utils/get-error-message.d.ts +2 -0
- package/build/utils/get-error-message.d.ts.map +1 -0
- package/build/utils/get-error-message.js +21 -0
- package/build/utils/get-error-message.js.map +1 -0
- package/build/utils/is-library-item.d.ts +2 -0
- package/build/utils/is-library-item.d.ts.map +1 -0
- package/build/utils/is-library-item.js +4 -0
- package/build/utils/is-library-item.js.map +1 -0
- package/build/utils/normalize-resource-ids.d.ts +4 -0
- package/build/utils/normalize-resource-ids.d.ts.map +1 -0
- package/build/utils/normalize-resource-ids.js +12 -0
- package/build/utils/normalize-resource-ids.js.map +1 -0
- package/build/web/MusicKitLoader.d.ts +11 -0
- package/build/web/MusicKitLoader.d.ts.map +1 -0
- package/build/web/MusicKitLoader.js +135 -0
- package/build/web/MusicKitLoader.js.map +1 -0
- package/build/web/WebAppleMusicApiClient.d.ts +151 -0
- package/build/web/WebAppleMusicApiClient.d.ts.map +1 -0
- package/build/web/WebAppleMusicApiClient.js +139 -0
- package/build/web/WebAppleMusicApiClient.js.map +1 -0
- package/build/web/WebAppleMusicRestTransport.d.ts +9 -0
- package/build/web/WebAppleMusicRestTransport.d.ts.map +1 -0
- package/build/web/WebAppleMusicRestTransport.js +31 -0
- package/build/web/WebAppleMusicRestTransport.js.map +1 -0
- package/build/web/WebPlaybackController.d.ts +12 -0
- package/build/web/WebPlaybackController.d.ts.map +1 -0
- package/build/web/WebPlaybackController.js +90 -0
- package/build/web/WebPlaybackController.js.map +1 -0
- package/build/web/WebPlaybackObserver.d.ts +22 -0
- package/build/web/WebPlaybackObserver.d.ts.map +1 -0
- package/build/web/WebPlaybackObserver.js +106 -0
- package/build/web/WebPlaybackObserver.js.map +1 -0
- package/build/web/WebQueueService.d.ts +10 -0
- package/build/web/WebQueueService.d.ts.map +1 -0
- package/build/web/WebQueueService.js +53 -0
- package/build/web/WebQueueService.js.map +1 -0
- package/build/web/WebSubscriptionService.d.ts +7 -0
- package/build/web/WebSubscriptionService.d.ts.map +1 -0
- package/build/web/WebSubscriptionService.js +24 -0
- package/build/web/WebSubscriptionService.js.map +1 -0
- package/build/web/apple-music-errors.d.ts +11 -0
- package/build/web/apple-music-errors.d.ts.map +1 -0
- package/build/web/apple-music-errors.js +31 -0
- package/build/web/apple-music-errors.js.map +1 -0
- package/build/web/extract-music-user-token.d.ts +4 -0
- package/build/web/extract-music-user-token.d.ts.map +1 -0
- package/build/web/extract-music-user-token.js +15 -0
- package/build/web/extract-music-user-token.js.map +1 -0
- package/build/web/map-auth-status.d.ts +17 -0
- package/build/web/map-auth-status.d.ts.map +1 -0
- package/build/web/map-auth-status.js +85 -0
- package/build/web/map-auth-status.js.map +1 -0
- package/build/web/music-kit-api.d.ts +18 -0
- package/build/web/music-kit-api.d.ts.map +1 -0
- package/build/web/music-kit-api.js +120 -0
- package/build/web/music-kit-api.js.map +1 -0
- package/build/web/musickit-types.d.ts +70 -0
- package/build/web/musickit-types.d.ts.map +1 -0
- package/build/web/musickit-types.js +3 -0
- package/build/web/musickit-types.js.map +1 -0
- package/build/web/pagination.d.ts +2 -0
- package/build/web/pagination.d.ts.map +1 -0
- package/build/web/pagination.js +2 -0
- package/build/web/pagination.js.map +1 -0
- package/expo-module.config.json +19 -0
- package/ios/AppleMusicBridgeError.swift +60 -0
- package/ios/AppleMusicErrorCodes.swift +11 -0
- package/ios/AppleMusicRestClient.swift +213 -0
- package/ios/AuthenticatedSession.swift +64 -0
- package/ios/BridgePagination.swift +17 -0
- package/ios/BridgeResponses.swift +82 -0
- package/ios/CatalogSearchStore.swift +13 -0
- package/ios/CatalogSearchStoreFactory.swift +31 -0
- package/ios/CatalogService.swift +307 -0
- package/ios/ExpoAppleMusic.podspec +29 -0
- package/ios/ExpoAppleMusicModule.swift +505 -0
- package/ios/HistoryService.swift +53 -0
- package/ios/LibraryMutationsService.swift +63 -0
- package/ios/LibraryService.swift +313 -0
- package/ios/MusicItemMapper.swift +171 -0
- package/ios/MusicKitAuthStorage.swift +38 -0
- package/ios/MusicKitCatalogSearchStore.swift +62 -0
- package/ios/PlaybackController.swift +201 -0
- package/ios/PlaybackObserver.swift +225 -0
- package/ios/QueueService.swift +166 -0
- package/ios/RatingsService.swift +66 -0
- package/ios/RecommendationsService.swift +34 -0
- package/ios/RestCatalogSearchStore.swift +62 -0
- package/ios/RestJsonMapper.swift +268 -0
- package/ios/StorefrontService.swift +55 -0
- package/ios/SubscriptionService.swift +119 -0
- package/ios/bridge/ExpoBridgeCatalog.swift +98 -0
- package/ios/bridge/ExpoBridgeHistory.swift +71 -0
- package/ios/bridge/ExpoBridgeLibrary.swift +93 -0
- package/ios/bridge/ExpoBridgeRecommendations.swift +28 -0
- package/package.json +89 -0
- package/plugin/build/index.d.ts +5 -0
- package/plugin/build/index.js +10 -0
- package/plugin/build/with-expo-apple-music.d.ts +10 -0
- package/plugin/build/with-expo-apple-music.js +50 -0
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { mapPlaylist } from '../mappers/apple-music-json-mapper';
|
|
2
|
+
import * as errors from '../web/apple-music-errors';
|
|
3
|
+
import { buildIdsQuery } from './resource-ids-query';
|
|
4
|
+
/** Library write/mutation Apple Music REST. */
|
|
5
|
+
export class LibraryMutationsRestClient {
|
|
6
|
+
transport;
|
|
7
|
+
constructor(transport) {
|
|
8
|
+
this.transport = transport;
|
|
9
|
+
}
|
|
10
|
+
async addToLibrary(musicUserToken, resourceIds) {
|
|
11
|
+
await this.transport.request('POST', '/v1/me/library', buildIdsQuery(resourceIds), undefined, musicUserToken);
|
|
12
|
+
}
|
|
13
|
+
async createLibraryPlaylist(musicUserToken, name, description, isPublic, tracks) {
|
|
14
|
+
const attributes = { name, isPublic };
|
|
15
|
+
if (description?.trim()) {
|
|
16
|
+
attributes.description = { standard: description };
|
|
17
|
+
}
|
|
18
|
+
const payload = { attributes };
|
|
19
|
+
if (tracks?.length) {
|
|
20
|
+
payload.relationships = {
|
|
21
|
+
tracks: {
|
|
22
|
+
data: tracks.map((track) => ({ id: track.id, type: track.type })),
|
|
23
|
+
},
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
const json = await this.transport.request('POST', '/v1/me/library/playlists', {}, payload, musicUserToken);
|
|
27
|
+
const data = Array.isArray(json.data) ? json.data[0] : null;
|
|
28
|
+
if (!data) {
|
|
29
|
+
throw errors.apiError('Create playlist returned no data');
|
|
30
|
+
}
|
|
31
|
+
return mapPlaylist(data);
|
|
32
|
+
}
|
|
33
|
+
async addTracksToLibraryPlaylist(musicUserToken, playlistId, tracks) {
|
|
34
|
+
await this.transport.request('POST', `/v1/me/library/playlists/${playlistId}/tracks`, {}, { data: tracks.map((track) => ({ id: track.id, type: track.type })) }, musicUserToken);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=library-mutations-rest-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"library-mutations-rest-client.js","sourceRoot":"","sources":["../../src/rest/library-mutations-rest-client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAA8B,MAAM,oCAAoC,CAAC;AAC7F,OAAO,KAAK,MAAM,MAAM,2BAA2B,CAAC;AAEpD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAErD,+CAA+C;AAC/C,MAAM,OAAO,0BAA0B;IACR;IAA7B,YAA6B,SAAkC;QAAlC,cAAS,GAAT,SAAS,CAAyB;IAAG,CAAC;IAEnE,KAAK,CAAC,YAAY,CAAC,cAAsB,EAAE,WAAqC;QAC9E,MAAM,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,MAAM,EAAE,gBAAgB,EAAE,aAAa,CAAC,WAAW,CAAC,EAAE,SAAS,EAAE,cAAc,CAAC,CAAC;IAChH,CAAC;IAED,KAAK,CAAC,qBAAqB,CACzB,cAAsB,EACtB,IAAY,EACZ,WAA0B,EAC1B,QAAiB,EACjB,MAA6C;QAE7C,MAAM,UAAU,GAA4B,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;QAC/D,IAAI,WAAW,EAAE,IAAI,EAAE,EAAE,CAAC;YACxB,UAAU,CAAC,WAAW,GAAG,EAAE,QAAQ,EAAE,WAAW,EAAE,CAAC;QACrD,CAAC;QACD,MAAM,OAAO,GAA4B,EAAE,UAAU,EAAE,CAAC;QACxD,IAAI,MAAM,EAAE,MAAM,EAAE,CAAC;YACnB,OAAO,CAAC,aAAa,GAAG;gBACtB,MAAM,EAAE;oBACN,IAAI,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,KAAK,CAAC,EAAE,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;iBAClE;aACF,CAAC;QACJ,CAAC;QACD,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,OAAO,CACvC,MAAM,EACN,0BAA0B,EAC1B,EAAE,EACF,OAAO,EACP,cAAc,CACf,CAAC;QACF,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QAC5D,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,MAAM,MAAM,CAAC,QAAQ,CAAC,kCAAkC,CAAC,CAAC;QAC5D,CAAC;QACD,OAAO,WAAW,CAAC,IAA6B,CAAC,CAAC;IACpD,CAAC;IAED,KAAK,CAAC,0BAA0B,CAC9B,cAAsB,EACtB,UAAkB,EAClB,MAAsC;QAEtC,MAAM,IAAI,CAAC,SAAS,CAAC,OAAO,CAC1B,MAAM,EACN,4BAA4B,UAAU,SAAS,EAC/C,EAAE,EACF,EAAE,IAAI,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,KAAK,CAAC,EAAE,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,EAAE,EACrE,cAAc,CACf,CAAC;IACJ,CAAC;CACF","sourcesContent":["import { mapPlaylist, type AppleMusicApiResource } from '../mappers/apple-music-json-mapper';\nimport * as errors from '../web/apple-music-errors';\nimport type { AppleMusicRestTransport } from './apple-music-rest-transport';\nimport { buildIdsQuery } from './resource-ids-query';\n\n/** Library write/mutation Apple Music REST. */\nexport class LibraryMutationsRestClient {\n constructor(private readonly transport: AppleMusicRestTransport) {}\n\n async addToLibrary(musicUserToken: string, resourceIds: Record<string, string[]>) {\n await this.transport.request('POST', '/v1/me/library', buildIdsQuery(resourceIds), undefined, musicUserToken);\n }\n\n async createLibraryPlaylist(\n musicUserToken: string,\n name: string,\n description: string | null,\n isPublic: boolean,\n tracks: { id: string; type: string }[] | null,\n ) {\n const attributes: Record<string, unknown> = { name, isPublic };\n if (description?.trim()) {\n attributes.description = { standard: description };\n }\n const payload: Record<string, unknown> = { attributes };\n if (tracks?.length) {\n payload.relationships = {\n tracks: {\n data: tracks.map((track) => ({ id: track.id, type: track.type })),\n },\n };\n }\n const json = await this.transport.request(\n 'POST',\n '/v1/me/library/playlists',\n {},\n payload,\n musicUserToken,\n );\n const data = Array.isArray(json.data) ? json.data[0] : null;\n if (!data) {\n throw errors.apiError('Create playlist returned no data');\n }\n return mapPlaylist(data as AppleMusicApiResource);\n }\n\n async addTracksToLibraryPlaylist(\n musicUserToken: string,\n playlistId: string,\n tracks: { id: string; type: string }[],\n ) {\n await this.transport.request(\n 'POST',\n `/v1/me/library/playlists/${playlistId}/tracks`,\n {},\n { data: tracks.map((track) => ({ id: track.id, type: track.type })) },\n musicUserToken,\n );\n }\n}\n"]}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import type { LibrarySearchType } from '../types/library-search';
|
|
2
|
+
import type { AppleMusicRestTransport } from './apple-music-rest-transport';
|
|
3
|
+
export type LibrarySearchResult = {
|
|
4
|
+
songs: Record<string, unknown>[];
|
|
5
|
+
albums: Record<string, unknown>[];
|
|
6
|
+
artists: Record<string, unknown>[];
|
|
7
|
+
playlists: Record<string, unknown>[];
|
|
8
|
+
musicVideos: Record<string, unknown>[];
|
|
9
|
+
};
|
|
10
|
+
/** Library-domain Apple Music REST (user collection reads + playback id resolution). */
|
|
11
|
+
export declare class LibraryRestClient {
|
|
12
|
+
private readonly transport;
|
|
13
|
+
constructor(transport: AppleMusicRestTransport);
|
|
14
|
+
getLibraryPlaylists(musicUserToken: string, limit: number, offset: number): Promise<{
|
|
15
|
+
id: string;
|
|
16
|
+
name: string;
|
|
17
|
+
description: string;
|
|
18
|
+
artworkUrl: string;
|
|
19
|
+
trackCount: number;
|
|
20
|
+
}[]>;
|
|
21
|
+
getLibrarySongs(musicUserToken: string, limit: number, offset: number): Promise<{
|
|
22
|
+
id: string;
|
|
23
|
+
title: string;
|
|
24
|
+
artistName: string;
|
|
25
|
+
artworkUrl: string;
|
|
26
|
+
duration: number;
|
|
27
|
+
}[]>;
|
|
28
|
+
getPlaylistTracks(musicUserToken: string, playlistId: string): Promise<{
|
|
29
|
+
id: string;
|
|
30
|
+
title: string;
|
|
31
|
+
artistName: string;
|
|
32
|
+
artworkUrl: string;
|
|
33
|
+
duration: number;
|
|
34
|
+
}[]>;
|
|
35
|
+
getLibraryArtists(musicUserToken: string, limit: number, offset: number): Promise<{
|
|
36
|
+
id: string;
|
|
37
|
+
name: string;
|
|
38
|
+
artworkUrl: string;
|
|
39
|
+
}[]>;
|
|
40
|
+
getLibraryAlbums(musicUserToken: string, limit: number, offset: number): Promise<{
|
|
41
|
+
id: string;
|
|
42
|
+
title: string;
|
|
43
|
+
artistName: string;
|
|
44
|
+
artworkUrl: string;
|
|
45
|
+
trackCount: number;
|
|
46
|
+
}[]>;
|
|
47
|
+
getLibraryMusicVideos(musicUserToken: string, limit: number, offset: number): Promise<{
|
|
48
|
+
id: string;
|
|
49
|
+
title: string;
|
|
50
|
+
artistName: string;
|
|
51
|
+
artworkUrl: string;
|
|
52
|
+
duration: number;
|
|
53
|
+
}[]>;
|
|
54
|
+
searchLibrary(musicUserToken: string, term: string, types: LibrarySearchType[], limit: number, offset: number): Promise<LibrarySearchResult>;
|
|
55
|
+
probeLibraryAccess(musicUserToken: string): Promise<boolean>;
|
|
56
|
+
resolveCatalogPlaybackId(musicUserToken: string, libraryId: string, mediaType: string): Promise<string>;
|
|
57
|
+
resolveLibrarySongCatalogIds(musicUserToken: string, playlistId: string): Promise<string[]>;
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=library-rest-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"library-rest-client.d.ts","sourceRoot":"","sources":["../../src/rest/library-rest-client.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAEjE,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AAG5E,MAAM,MAAM,mBAAmB,GAAG;IAChC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC;IACjC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC;IAClC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC;IACnC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC;IACrC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC;CACxC,CAAC;AAyBF,wFAAwF;AACxF,qBAAa,iBAAiB;IAChB,OAAO,CAAC,QAAQ,CAAC,SAAS;gBAAT,SAAS,EAAE,uBAAuB;IAEzD,mBAAmB,CAAC,cAAc,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;;;;;;;IAQzE,eAAe,CAAC,cAAc,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;;;;;;;IAQrE,iBAAiB,CAAC,cAAc,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM;;;;;;;IAY5D,iBAAiB,CAAC,cAAc,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;;;;;IAQvE,gBAAgB,CAAC,cAAc,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;;;;;;;IAQtE,qBAAqB,CAAC,cAAc,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;;;;;;;IAQ3E,aAAa,CACjB,cAAc,EAAE,MAAM,EACtB,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,iBAAiB,EAAE,EAC1B,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,mBAAmB,CAAC;IAuBzB,kBAAkB,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAS5D,wBAAwB,CAAC,cAAc,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAyBvG,4BAA4B,CAAC,cAAc,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;CAoBlG"}
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import { catalogPlaybackId, mapAlbum, mapArtist, mapMusicVideo, mapPlaylist, mapSong, } from '../mappers/apple-music-json-mapper';
|
|
2
|
+
import * as errors from '../web/apple-music-errors';
|
|
3
|
+
import { mapResourceArray, mapTopLevelResourceArray, parseDataArray } from './rest-json';
|
|
4
|
+
function librarySearchTypeParam(type) {
|
|
5
|
+
switch (type) {
|
|
6
|
+
case 'library-songs':
|
|
7
|
+
case 'songs':
|
|
8
|
+
return 'library-songs';
|
|
9
|
+
case 'library-albums':
|
|
10
|
+
case 'albums':
|
|
11
|
+
return 'library-albums';
|
|
12
|
+
case 'library-artists':
|
|
13
|
+
case 'artists':
|
|
14
|
+
return 'library-artists';
|
|
15
|
+
case 'library-playlists':
|
|
16
|
+
case 'playlists':
|
|
17
|
+
return 'library-playlists';
|
|
18
|
+
case 'library-music-videos':
|
|
19
|
+
case 'music-videos':
|
|
20
|
+
case 'musicVideos':
|
|
21
|
+
return 'library-music-videos';
|
|
22
|
+
default:
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
/** Library-domain Apple Music REST (user collection reads + playback id resolution). */
|
|
27
|
+
export class LibraryRestClient {
|
|
28
|
+
transport;
|
|
29
|
+
constructor(transport) {
|
|
30
|
+
this.transport = transport;
|
|
31
|
+
}
|
|
32
|
+
async getLibraryPlaylists(musicUserToken, limit, offset) {
|
|
33
|
+
const json = await this.transport.getJson('/v1/me/library/playlists', {
|
|
34
|
+
limit: String(limit),
|
|
35
|
+
offset: String(offset),
|
|
36
|
+
}, musicUserToken);
|
|
37
|
+
return mapTopLevelResourceArray(json.data, mapPlaylist);
|
|
38
|
+
}
|
|
39
|
+
async getLibrarySongs(musicUserToken, limit, offset) {
|
|
40
|
+
const json = await this.transport.getJson('/v1/me/library/songs', {
|
|
41
|
+
limit: String(limit),
|
|
42
|
+
offset: String(offset),
|
|
43
|
+
}, musicUserToken);
|
|
44
|
+
return mapTopLevelResourceArray(json.data, mapSong);
|
|
45
|
+
}
|
|
46
|
+
async getPlaylistTracks(musicUserToken, playlistId) {
|
|
47
|
+
const json = await this.transport.getJson(`/v1/me/library/playlists/${playlistId}/tracks`, {}, musicUserToken);
|
|
48
|
+
const data = parseDataArray(json.data);
|
|
49
|
+
return data
|
|
50
|
+
.filter((item) => String(item.type ?? '').includes('song'))
|
|
51
|
+
.map((item) => mapSong(item));
|
|
52
|
+
}
|
|
53
|
+
async getLibraryArtists(musicUserToken, limit, offset) {
|
|
54
|
+
const json = await this.transport.getJson('/v1/me/library/artists', {
|
|
55
|
+
limit: String(limit),
|
|
56
|
+
offset: String(offset),
|
|
57
|
+
}, musicUserToken);
|
|
58
|
+
return mapTopLevelResourceArray(json.data, mapArtist);
|
|
59
|
+
}
|
|
60
|
+
async getLibraryAlbums(musicUserToken, limit, offset) {
|
|
61
|
+
const json = await this.transport.getJson('/v1/me/library/albums', {
|
|
62
|
+
limit: String(limit),
|
|
63
|
+
offset: String(offset),
|
|
64
|
+
}, musicUserToken);
|
|
65
|
+
return mapTopLevelResourceArray(json.data, mapAlbum);
|
|
66
|
+
}
|
|
67
|
+
async getLibraryMusicVideos(musicUserToken, limit, offset) {
|
|
68
|
+
const json = await this.transport.getJson('/v1/me/library/music-videos', {
|
|
69
|
+
limit: String(limit),
|
|
70
|
+
offset: String(offset),
|
|
71
|
+
}, musicUserToken);
|
|
72
|
+
return mapTopLevelResourceArray(json.data, mapMusicVideo);
|
|
73
|
+
}
|
|
74
|
+
async searchLibrary(musicUserToken, term, types, limit, offset) {
|
|
75
|
+
const typeParam = [...new Set(types.map(librarySearchTypeParam).filter(Boolean))].sort().join(',');
|
|
76
|
+
const typesQuery = typeParam || 'library-songs,library-albums';
|
|
77
|
+
const json = await this.transport.getJson('/v1/me/library/search', {
|
|
78
|
+
term,
|
|
79
|
+
types: typesQuery,
|
|
80
|
+
limit: String(limit),
|
|
81
|
+
offset: String(offset),
|
|
82
|
+
}, musicUserToken);
|
|
83
|
+
const results = (json.results ?? {});
|
|
84
|
+
return {
|
|
85
|
+
songs: mapResourceArray(results['library-songs']?.data, mapSong),
|
|
86
|
+
albums: mapResourceArray(results['library-albums']?.data, mapAlbum),
|
|
87
|
+
artists: mapResourceArray(results['library-artists']?.data, mapArtist),
|
|
88
|
+
playlists: mapResourceArray(results['library-playlists']?.data, mapPlaylist),
|
|
89
|
+
musicVideos: mapResourceArray(results['library-music-videos']?.data, mapMusicVideo),
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
async probeLibraryAccess(musicUserToken) {
|
|
93
|
+
try {
|
|
94
|
+
await this.transport.getJson('/v1/me/library/songs', { limit: '1' }, musicUserToken);
|
|
95
|
+
return true;
|
|
96
|
+
}
|
|
97
|
+
catch {
|
|
98
|
+
return false;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
async resolveCatalogPlaybackId(musicUserToken, libraryId, mediaType) {
|
|
102
|
+
const path = mediaType === 'song'
|
|
103
|
+
? `/v1/me/library/songs/${libraryId}`
|
|
104
|
+
: mediaType === 'album'
|
|
105
|
+
? `/v1/me/library/albums/${libraryId}`
|
|
106
|
+
: mediaType === 'playlist'
|
|
107
|
+
? `/v1/me/library/playlists/${libraryId}`
|
|
108
|
+
: null;
|
|
109
|
+
if (!path) {
|
|
110
|
+
throw errors.unknownMediaType(mediaType);
|
|
111
|
+
}
|
|
112
|
+
const json = await this.transport.getJson(path, {}, musicUserToken);
|
|
113
|
+
const rows = parseDataArray(json.data);
|
|
114
|
+
const data = rows[0];
|
|
115
|
+
if (!data) {
|
|
116
|
+
throw errors.itemNotFound(mediaType, true);
|
|
117
|
+
}
|
|
118
|
+
const catalogId = catalogPlaybackId(data);
|
|
119
|
+
if (!catalogId) {
|
|
120
|
+
throw errors.itemNotFound(mediaType, true);
|
|
121
|
+
}
|
|
122
|
+
return catalogId;
|
|
123
|
+
}
|
|
124
|
+
async resolveLibrarySongCatalogIds(musicUserToken, playlistId) {
|
|
125
|
+
const json = await this.transport.getJson(`/v1/me/library/playlists/${playlistId}/tracks`, {}, musicUserToken);
|
|
126
|
+
const data = parseDataArray(json.data);
|
|
127
|
+
const ids = [];
|
|
128
|
+
for (const item of data) {
|
|
129
|
+
const resource = item;
|
|
130
|
+
if (!String(resource.type ?? '').includes('song')) {
|
|
131
|
+
continue;
|
|
132
|
+
}
|
|
133
|
+
const catalogId = catalogPlaybackId(resource);
|
|
134
|
+
if (catalogId) {
|
|
135
|
+
ids.push(catalogId);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
return ids;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
//# sourceMappingURL=library-rest-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"library-rest-client.js","sourceRoot":"","sources":["../../src/rest/library-rest-client.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n catalogPlaybackId,\n mapAlbum,\n mapArtist,\n mapMusicVideo,\n mapPlaylist,\n mapSong,\n type AppleMusicApiResource,\n} from '../mappers/apple-music-json-mapper';\nimport type { LibrarySearchType } from '../types/library-search';\nimport * as errors from '../web/apple-music-errors';\nimport type { AppleMusicRestTransport } from './apple-music-rest-transport';\nimport { mapResourceArray, mapTopLevelResourceArray, parseDataArray } from './rest-json';\n\nexport type LibrarySearchResult = {\n songs: Record<string, unknown>[];\n albums: Record<string, unknown>[];\n artists: Record<string, unknown>[];\n playlists: Record<string, unknown>[];\n musicVideos: Record<string, unknown>[];\n};\n\nfunction librarySearchTypeParam(type: string): string | null {\n switch (type) {\n case 'library-songs':\n case 'songs':\n return 'library-songs';\n case 'library-albums':\n case 'albums':\n return 'library-albums';\n case 'library-artists':\n case 'artists':\n return 'library-artists';\n case 'library-playlists':\n case 'playlists':\n return 'library-playlists';\n case 'library-music-videos':\n case 'music-videos':\n case 'musicVideos':\n return 'library-music-videos';\n default:\n return null;\n }\n}\n\n/** Library-domain Apple Music REST (user collection reads + playback id resolution). */\nexport class LibraryRestClient {\n constructor(private readonly transport: AppleMusicRestTransport) {}\n\n async getLibraryPlaylists(musicUserToken: string, limit: number, offset: number) {\n const json = await this.transport.getJson('/v1/me/library/playlists', {\n limit: String(limit),\n offset: String(offset),\n }, musicUserToken);\n return mapTopLevelResourceArray(json.data, mapPlaylist);\n }\n\n async getLibrarySongs(musicUserToken: string, limit: number, offset: number) {\n const json = await this.transport.getJson('/v1/me/library/songs', {\n limit: String(limit),\n offset: String(offset),\n }, musicUserToken);\n return mapTopLevelResourceArray(json.data, mapSong);\n }\n\n async getPlaylistTracks(musicUserToken: string, playlistId: string) {\n const json = await this.transport.getJson(\n `/v1/me/library/playlists/${playlistId}/tracks`,\n {},\n musicUserToken,\n );\n const data = parseDataArray(json.data);\n return data\n .filter((item) => String((item as AppleMusicApiResource).type ?? '').includes('song'))\n .map((item) => mapSong(item as AppleMusicApiResource));\n }\n\n async getLibraryArtists(musicUserToken: string, limit: number, offset: number) {\n const json = await this.transport.getJson('/v1/me/library/artists', {\n limit: String(limit),\n offset: String(offset),\n }, musicUserToken);\n return mapTopLevelResourceArray(json.data, mapArtist);\n }\n\n async getLibraryAlbums(musicUserToken: string, limit: number, offset: number) {\n const json = await this.transport.getJson('/v1/me/library/albums', {\n limit: String(limit),\n offset: String(offset),\n }, musicUserToken);\n return mapTopLevelResourceArray(json.data, mapAlbum);\n }\n\n async getLibraryMusicVideos(musicUserToken: string, limit: number, offset: number) {\n const json = await this.transport.getJson('/v1/me/library/music-videos', {\n limit: String(limit),\n offset: String(offset),\n }, musicUserToken);\n return mapTopLevelResourceArray(json.data, mapMusicVideo);\n }\n\n async searchLibrary(\n musicUserToken: string,\n term: string,\n types: LibrarySearchType[],\n limit: number,\n offset: number,\n ): Promise<LibrarySearchResult> {\n const typeParam = [...new Set(types.map(librarySearchTypeParam).filter(Boolean))].sort().join(\n ',',\n );\n const typesQuery = typeParam || 'library-songs,library-albums';\n\n const json = await this.transport.getJson('/v1/me/library/search', {\n term,\n types: typesQuery,\n limit: String(limit),\n offset: String(offset),\n }, musicUserToken);\n\n const results = (json.results ?? {}) as Record<string, { data?: AppleMusicApiResource[] }>;\n return {\n songs: mapResourceArray(results['library-songs']?.data, mapSong),\n albums: mapResourceArray(results['library-albums']?.data, mapAlbum),\n artists: mapResourceArray(results['library-artists']?.data, mapArtist),\n playlists: mapResourceArray(results['library-playlists']?.data, mapPlaylist),\n musicVideos: mapResourceArray(results['library-music-videos']?.data, mapMusicVideo),\n };\n }\n\n async probeLibraryAccess(musicUserToken: string): Promise<boolean> {\n try {\n await this.transport.getJson('/v1/me/library/songs', { limit: '1' }, musicUserToken);\n return true;\n } catch {\n return false;\n }\n }\n\n async resolveCatalogPlaybackId(musicUserToken: string, libraryId: string, mediaType: string): Promise<string> {\n const path =\n mediaType === 'song'\n ? `/v1/me/library/songs/${libraryId}`\n : mediaType === 'album'\n ? `/v1/me/library/albums/${libraryId}`\n : mediaType === 'playlist'\n ? `/v1/me/library/playlists/${libraryId}`\n : null;\n if (!path) {\n throw errors.unknownMediaType(mediaType);\n }\n const json = await this.transport.getJson(path, {}, musicUserToken);\n const rows = parseDataArray(json.data);\n const data = rows[0];\n if (!data) {\n throw errors.itemNotFound(mediaType, true);\n }\n const catalogId = catalogPlaybackId(data as AppleMusicApiResource);\n if (!catalogId) {\n throw errors.itemNotFound(mediaType, true);\n }\n return catalogId;\n }\n\n async resolveLibrarySongCatalogIds(musicUserToken: string, playlistId: string): Promise<string[]> {\n const json = await this.transport.getJson(\n `/v1/me/library/playlists/${playlistId}/tracks`,\n {},\n musicUserToken,\n );\n const data = parseDataArray(json.data);\n const ids: string[] = [];\n for (const item of data) {\n const resource = item as AppleMusicApiResource;\n if (!String(resource.type ?? '').includes('song')) {\n continue;\n }\n const catalogId = catalogPlaybackId(resource);\n if (catalogId) {\n ids.push(catalogId);\n }\n }\n return ids;\n }\n}\n"]}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { AppleMusicRestTransport } from './apple-music-rest-transport';
|
|
2
|
+
/** Ratings and favorites Apple Music REST. */
|
|
3
|
+
export declare class RatingsRestClient {
|
|
4
|
+
private readonly transport;
|
|
5
|
+
constructor(transport: AppleMusicRestTransport);
|
|
6
|
+
getRating(musicUserToken: string, resourceType: string, id: string): Promise<{
|
|
7
|
+
id: string;
|
|
8
|
+
value: number;
|
|
9
|
+
} | null>;
|
|
10
|
+
setRating(musicUserToken: string, resourceType: string, id: string, value: number): Promise<{
|
|
11
|
+
id: string;
|
|
12
|
+
value: number;
|
|
13
|
+
} | null>;
|
|
14
|
+
clearRating(musicUserToken: string, resourceType: string, id: string): Promise<void>;
|
|
15
|
+
addToFavorites(musicUserToken: string, resourceIds: Record<string, string[]>): Promise<void>;
|
|
16
|
+
removeFromFavorites(musicUserToken: string, resourceIds: Record<string, string[]>): Promise<void>;
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=ratings-rest-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ratings-rest-client.d.ts","sourceRoot":"","sources":["../../src/rest/ratings-rest-client.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AAG5E,8CAA8C;AAC9C,qBAAa,iBAAiB;IAChB,OAAO,CAAC,QAAQ,CAAC,SAAS;gBAAT,SAAS,EAAE,uBAAuB;IAEzD,SAAS,CAAC,cAAc,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM;;;;IAiBlE,SAAS,CAAC,cAAc,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM;;;;IAWjF,WAAW,CAAC,cAAc,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM;IAIpE,cAAc,CAAC,cAAc,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC;IAI5E,mBAAmB,CAAC,cAAc,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC;CAGxF"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { mapRating } from '../mappers/apple-music-json-mapper';
|
|
2
|
+
import { getErrorMessage } from '../utils/get-error-message';
|
|
3
|
+
import { buildIdsQuery } from './resource-ids-query';
|
|
4
|
+
/** Ratings and favorites Apple Music REST. */
|
|
5
|
+
export class RatingsRestClient {
|
|
6
|
+
transport;
|
|
7
|
+
constructor(transport) {
|
|
8
|
+
this.transport = transport;
|
|
9
|
+
}
|
|
10
|
+
async getRating(musicUserToken, resourceType, id) {
|
|
11
|
+
try {
|
|
12
|
+
const json = await this.transport.getJson(`/v1/me/ratings/${resourceType}/${id}`, {}, musicUserToken);
|
|
13
|
+
return mapRating(json);
|
|
14
|
+
}
|
|
15
|
+
catch (error) {
|
|
16
|
+
const message = getErrorMessage(error);
|
|
17
|
+
if (message.includes('404')) {
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
throw error;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
async setRating(musicUserToken, resourceType, id, value) {
|
|
24
|
+
const json = await this.transport.request('PUT', `/v1/me/ratings/${resourceType}/${id}`, {}, { type: 'rating', attributes: { value } }, musicUserToken);
|
|
25
|
+
return mapRating(json);
|
|
26
|
+
}
|
|
27
|
+
async clearRating(musicUserToken, resourceType, id) {
|
|
28
|
+
await this.transport.request('DELETE', `/v1/me/ratings/${resourceType}/${id}`, {}, undefined, musicUserToken);
|
|
29
|
+
}
|
|
30
|
+
async addToFavorites(musicUserToken, resourceIds) {
|
|
31
|
+
await this.transport.request('POST', '/v1/me/favorites', buildIdsQuery(resourceIds), undefined, musicUserToken);
|
|
32
|
+
}
|
|
33
|
+
async removeFromFavorites(musicUserToken, resourceIds) {
|
|
34
|
+
await this.transport.request('DELETE', '/v1/me/favorites', buildIdsQuery(resourceIds), undefined, musicUserToken);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=ratings-rest-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ratings-rest-client.js","sourceRoot":"","sources":["../../src/rest/ratings-rest-client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,oCAAoC,CAAC;AAC/D,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAE7D,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAErD,8CAA8C;AAC9C,MAAM,OAAO,iBAAiB;IACC;IAA7B,YAA6B,SAAkC;QAAlC,cAAS,GAAT,SAAS,CAAyB;IAAG,CAAC;IAEnE,KAAK,CAAC,SAAS,CAAC,cAAsB,EAAE,YAAoB,EAAE,EAAU;QACtE,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,OAAO,CACvC,kBAAkB,YAAY,IAAI,EAAE,EAAE,EACtC,EAAE,EACF,cAAc,CACf,CAAC;YACF,OAAO,SAAS,CAAC,IAAuC,CAAC,CAAC;QAC5D,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,OAAO,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC;YACvC,IAAI,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;gBAC5B,OAAO,IAAI,CAAC;YACd,CAAC;YACD,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;IAED,KAAK,CAAC,SAAS,CAAC,cAAsB,EAAE,YAAoB,EAAE,EAAU,EAAE,KAAa;QACrF,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,OAAO,CACvC,KAAK,EACL,kBAAkB,YAAY,IAAI,EAAE,EAAE,EACtC,EAAE,EACF,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,EAAE,KAAK,EAAE,EAAE,EACzC,cAAc,CACf,CAAC;QACF,OAAO,SAAS,CAAC,IAAuC,CAAC,CAAC;IAC5D,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,cAAsB,EAAE,YAAoB,EAAE,EAAU;QACxE,MAAM,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,QAAQ,EAAE,kBAAkB,YAAY,IAAI,EAAE,EAAE,EAAE,EAAE,EAAE,SAAS,EAAE,cAAc,CAAC,CAAC;IAChH,CAAC;IAED,KAAK,CAAC,cAAc,CAAC,cAAsB,EAAE,WAAqC;QAChF,MAAM,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,MAAM,EAAE,kBAAkB,EAAE,aAAa,CAAC,WAAW,CAAC,EAAE,SAAS,EAAE,cAAc,CAAC,CAAC;IAClH,CAAC;IAED,KAAK,CAAC,mBAAmB,CAAC,cAAsB,EAAE,WAAqC;QACrF,MAAM,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,QAAQ,EAAE,kBAAkB,EAAE,aAAa,CAAC,WAAW,CAAC,EAAE,SAAS,EAAE,cAAc,CAAC,CAAC;IACpH,CAAC;CACF","sourcesContent":["import { mapRating } from '../mappers/apple-music-json-mapper';\nimport { getErrorMessage } from '../utils/get-error-message';\nimport type { AppleMusicRestTransport } from './apple-music-rest-transport';\nimport { buildIdsQuery } from './resource-ids-query';\n\n/** Ratings and favorites Apple Music REST. */\nexport class RatingsRestClient {\n constructor(private readonly transport: AppleMusicRestTransport) {}\n\n async getRating(musicUserToken: string, resourceType: string, id: string) {\n try {\n const json = await this.transport.getJson(\n `/v1/me/ratings/${resourceType}/${id}`,\n {},\n musicUserToken,\n );\n return mapRating(json as Parameters<typeof mapRating>[0]);\n } catch (error) {\n const message = getErrorMessage(error);\n if (message.includes('404')) {\n return null;\n }\n throw error;\n }\n }\n\n async setRating(musicUserToken: string, resourceType: string, id: string, value: number) {\n const json = await this.transport.request(\n 'PUT',\n `/v1/me/ratings/${resourceType}/${id}`,\n {},\n { type: 'rating', attributes: { value } },\n musicUserToken,\n );\n return mapRating(json as Parameters<typeof mapRating>[0]);\n }\n\n async clearRating(musicUserToken: string, resourceType: string, id: string) {\n await this.transport.request('DELETE', `/v1/me/ratings/${resourceType}/${id}`, {}, undefined, musicUserToken);\n }\n\n async addToFavorites(musicUserToken: string, resourceIds: Record<string, string[]>) {\n await this.transport.request('POST', '/v1/me/favorites', buildIdsQuery(resourceIds), undefined, musicUserToken);\n }\n\n async removeFromFavorites(musicUserToken: string, resourceIds: Record<string, string[]>) {\n await this.transport.request('DELETE', '/v1/me/favorites', buildIdsQuery(resourceIds), undefined, musicUserToken);\n }\n}\n"]}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { AppleMusicRestTransport } from './apple-music-rest-transport';
|
|
2
|
+
/** Recommendations and Replay Apple Music REST. */
|
|
3
|
+
export declare class RecommendationsRestClient {
|
|
4
|
+
private readonly transport;
|
|
5
|
+
constructor(transport: AppleMusicRestTransport);
|
|
6
|
+
getRecommendations(musicUserToken: string, ids: string[] | null): Promise<{
|
|
7
|
+
id: string;
|
|
8
|
+
title: string;
|
|
9
|
+
resourceTypes: string[];
|
|
10
|
+
playlists: {
|
|
11
|
+
id: string;
|
|
12
|
+
name: string;
|
|
13
|
+
description: string;
|
|
14
|
+
artworkUrl: string;
|
|
15
|
+
trackCount: number;
|
|
16
|
+
}[];
|
|
17
|
+
albums: {
|
|
18
|
+
id: string;
|
|
19
|
+
title: string;
|
|
20
|
+
artistName: string;
|
|
21
|
+
artworkUrl: string;
|
|
22
|
+
trackCount: number;
|
|
23
|
+
}[];
|
|
24
|
+
stations: {
|
|
25
|
+
id: string;
|
|
26
|
+
name: string;
|
|
27
|
+
artworkUrl: string;
|
|
28
|
+
}[];
|
|
29
|
+
}[]>;
|
|
30
|
+
getReplay(musicUserToken: string, year: number | null): Promise<Record<string, unknown>[]>;
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=recommendations-rest-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recommendations-rest-client.d.ts","sourceRoot":"","sources":["../../src/rest/recommendations-rest-client.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AAG5E,mDAAmD;AACnD,qBAAa,yBAAyB;IACxB,OAAO,CAAC,QAAQ,CAAC,SAAS;gBAAT,SAAS,EAAE,uBAAuB;IAEzD,kBAAkB,CAAC,cAAc,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,IAAI;;;;;;;;;;;;;;;;;;;;;;;;IAS/D,SAAS,CAAC,cAAc,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI;CAQ5D"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { mapRecommendation, mapReplaySummary } from '../mappers/apple-music-json-mapper';
|
|
2
|
+
import { mapTopLevelResourceArray } from './rest-json';
|
|
3
|
+
/** Recommendations and Replay Apple Music REST. */
|
|
4
|
+
export class RecommendationsRestClient {
|
|
5
|
+
transport;
|
|
6
|
+
constructor(transport) {
|
|
7
|
+
this.transport = transport;
|
|
8
|
+
}
|
|
9
|
+
async getRecommendations(musicUserToken, ids) {
|
|
10
|
+
const query = {};
|
|
11
|
+
if (ids?.length) {
|
|
12
|
+
query.ids = ids.join(',');
|
|
13
|
+
}
|
|
14
|
+
const json = await this.transport.getJson('/v1/me/recommendations', query, musicUserToken);
|
|
15
|
+
return mapTopLevelResourceArray(json.data, mapRecommendation);
|
|
16
|
+
}
|
|
17
|
+
async getReplay(musicUserToken, year) {
|
|
18
|
+
const query = {};
|
|
19
|
+
if (year != null) {
|
|
20
|
+
query['filter[year]'] = String(year);
|
|
21
|
+
}
|
|
22
|
+
const json = await this.transport.getJson('/v1/me/music-summaries', query, musicUserToken);
|
|
23
|
+
return mapTopLevelResourceArray(json.data, mapReplaySummary);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=recommendations-rest-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recommendations-rest-client.js","sourceRoot":"","sources":["../../src/rest/recommendations-rest-client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AAEzF,OAAO,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAC;AAEvD,mDAAmD;AACnD,MAAM,OAAO,yBAAyB;IACP;IAA7B,YAA6B,SAAkC;QAAlC,cAAS,GAAT,SAAS,CAAyB;IAAG,CAAC;IAEnE,KAAK,CAAC,kBAAkB,CAAC,cAAsB,EAAE,GAAoB;QACnE,MAAM,KAAK,GAA2B,EAAE,CAAC;QACzC,IAAI,GAAG,EAAE,MAAM,EAAE,CAAC;YAChB,KAAK,CAAC,GAAG,GAAG,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC5B,CAAC;QACD,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,wBAAwB,EAAE,KAAK,EAAE,cAAc,CAAC,CAAC;QAC3F,OAAO,wBAAwB,CAAC,IAAI,CAAC,IAAI,EAAE,iBAAiB,CAAC,CAAC;IAChE,CAAC;IAED,KAAK,CAAC,SAAS,CAAC,cAAsB,EAAE,IAAmB;QACzD,MAAM,KAAK,GAA2B,EAAE,CAAC;QACzC,IAAI,IAAI,IAAI,IAAI,EAAE,CAAC;YACjB,KAAK,CAAC,cAAc,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;QACvC,CAAC;QACD,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,wBAAwB,EAAE,KAAK,EAAE,cAAc,CAAC,CAAC;QAC3F,OAAO,wBAAwB,CAAC,IAAI,CAAC,IAAI,EAAE,gBAAgB,CAAC,CAAC;IAC/D,CAAC;CACF","sourcesContent":["import { mapRecommendation, mapReplaySummary } from '../mappers/apple-music-json-mapper';\nimport type { AppleMusicRestTransport } from './apple-music-rest-transport';\nimport { mapTopLevelResourceArray } from './rest-json';\n\n/** Recommendations and Replay Apple Music REST. */\nexport class RecommendationsRestClient {\n constructor(private readonly transport: AppleMusicRestTransport) {}\n\n async getRecommendations(musicUserToken: string, ids: string[] | null) {\n const query: Record<string, string> = {};\n if (ids?.length) {\n query.ids = ids.join(',');\n }\n const json = await this.transport.getJson('/v1/me/recommendations', query, musicUserToken);\n return mapTopLevelResourceArray(json.data, mapRecommendation);\n }\n\n async getReplay(musicUserToken: string, year: number | null) {\n const query: Record<string, string> = {};\n if (year != null) {\n query['filter[year]'] = String(year);\n }\n const json = await this.transport.getJson('/v1/me/music-summaries', query, musicUserToken);\n return mapTopLevelResourceArray(json.data, mapReplaySummary);\n }\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resource-ids-query.d.ts","sourceRoot":"","sources":["../../src/rest/resource-ids-query.ts"],"names":[],"mappings":"AAAA,wBAAgB,aAAa,CAAC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAQ3F"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export function buildIdsQuery(resourceIds) {
|
|
2
|
+
const query = {};
|
|
3
|
+
for (const [type, ids] of Object.entries(resourceIds)) {
|
|
4
|
+
if (ids.length > 0) {
|
|
5
|
+
query[`ids[${type}]`] = ids.join(',');
|
|
6
|
+
}
|
|
7
|
+
}
|
|
8
|
+
return query;
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=resource-ids-query.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resource-ids-query.js","sourceRoot":"","sources":["../../src/rest/resource-ids-query.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,aAAa,CAAC,WAAqC;IACjE,MAAM,KAAK,GAA2B,EAAE,CAAC;IACzC,KAAK,MAAM,CAAC,IAAI,EAAE,GAAG,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE,CAAC;QACtD,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACnB,KAAK,CAAC,OAAO,IAAI,GAAG,CAAC,GAAG,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACxC,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC","sourcesContent":["export function buildIdsQuery(resourceIds: Record<string, string[]>): Record<string, string> {\n const query: Record<string, string> = {};\n for (const [type, ids] of Object.entries(resourceIds)) {\n if (ids.length > 0) {\n query[`ids[${type}]`] = ids.join(',');\n }\n }\n return query;\n}\n"]}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { AppleMusicApiResource } from '../mappers/apple-music-json-mapper';
|
|
2
|
+
/** Top-level list responses must include a `data` array (may be empty). */
|
|
3
|
+
export declare function parseDataArray(data: unknown): AppleMusicApiResource[];
|
|
4
|
+
/**
|
|
5
|
+
* Map a `data` array (or optional nested search bucket).
|
|
6
|
+
* `undefined` / `null` → empty (type omitted from search). Non-array → reject.
|
|
7
|
+
*/
|
|
8
|
+
export declare function mapResourceArray<T>(data: unknown, mapper: (resource: AppleMusicApiResource) => T): T[];
|
|
9
|
+
/** Parse required top-level `data`, then map resources. */
|
|
10
|
+
export declare function mapTopLevelResourceArray<T>(data: unknown, mapper: (resource: AppleMusicApiResource) => T): T[];
|
|
11
|
+
//# sourceMappingURL=rest-json.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rest-json.d.ts","sourceRoot":"","sources":["../../src/rest/rest-json.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,oCAAoC,CAAC;AAGhF,2EAA2E;AAC3E,wBAAgB,cAAc,CAAC,IAAI,EAAE,OAAO,GAAG,qBAAqB,EAAE,CAQrE;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,EAChC,IAAI,EAAE,OAAO,EACb,MAAM,EAAE,CAAC,QAAQ,EAAE,qBAAqB,KAAK,CAAC,GAC7C,CAAC,EAAE,CAQL;AAED,2DAA2D;AAC3D,wBAAgB,wBAAwB,CAAC,CAAC,EACxC,IAAI,EAAE,OAAO,EACb,MAAM,EAAE,CAAC,QAAQ,EAAE,qBAAqB,KAAK,CAAC,GAC7C,CAAC,EAAE,CAEL"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import * as errors from '../web/apple-music-errors';
|
|
2
|
+
/** Top-level list responses must include a `data` array (may be empty). */
|
|
3
|
+
export function parseDataArray(data) {
|
|
4
|
+
if (data === undefined || data === null) {
|
|
5
|
+
throw errors.apiError('Apple Music API response missing "data"');
|
|
6
|
+
}
|
|
7
|
+
if (!Array.isArray(data)) {
|
|
8
|
+
throw errors.apiError('Apple Music API response "data" is not an array');
|
|
9
|
+
}
|
|
10
|
+
return data;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Map a `data` array (or optional nested search bucket).
|
|
14
|
+
* `undefined` / `null` → empty (type omitted from search). Non-array → reject.
|
|
15
|
+
*/
|
|
16
|
+
export function mapResourceArray(data, mapper) {
|
|
17
|
+
if (data === undefined || data === null) {
|
|
18
|
+
return [];
|
|
19
|
+
}
|
|
20
|
+
if (!Array.isArray(data)) {
|
|
21
|
+
throw errors.apiError('Apple Music API response "data" is not an array');
|
|
22
|
+
}
|
|
23
|
+
return data.map((item) => mapper(item));
|
|
24
|
+
}
|
|
25
|
+
/** Parse required top-level `data`, then map resources. */
|
|
26
|
+
export function mapTopLevelResourceArray(data, mapper) {
|
|
27
|
+
return mapResourceArray(parseDataArray(data), mapper);
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=rest-json.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rest-json.js","sourceRoot":"","sources":["../../src/rest/rest-json.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,MAAM,2BAA2B,CAAC;AAEpD,2EAA2E;AAC3E,MAAM,UAAU,cAAc,CAAC,IAAa;IAC1C,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;QACxC,MAAM,MAAM,CAAC,QAAQ,CAAC,yCAAyC,CAAC,CAAC;IACnE,CAAC;IACD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;QACzB,MAAM,MAAM,CAAC,QAAQ,CAAC,iDAAiD,CAAC,CAAC;IAC3E,CAAC;IACD,OAAO,IAA+B,CAAC;AACzC,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAC9B,IAAa,EACb,MAA8C;IAE9C,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;QACxC,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;QACzB,MAAM,MAAM,CAAC,QAAQ,CAAC,iDAAiD,CAAC,CAAC;IAC3E,CAAC;IACD,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,MAAM,CAAC,IAA6B,CAAC,CAAC,CAAC;AACnE,CAAC;AAED,2DAA2D;AAC3D,MAAM,UAAU,wBAAwB,CACtC,IAAa,EACb,MAA8C;IAE9C,OAAO,gBAAgB,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC,CAAC;AACxD,CAAC","sourcesContent":["import type { AppleMusicApiResource } from '../mappers/apple-music-json-mapper';\nimport * as errors from '../web/apple-music-errors';\n\n/** Top-level list responses must include a `data` array (may be empty). */\nexport function parseDataArray(data: unknown): AppleMusicApiResource[] {\n if (data === undefined || data === null) {\n throw errors.apiError('Apple Music API response missing \"data\"');\n }\n if (!Array.isArray(data)) {\n throw errors.apiError('Apple Music API response \"data\" is not an array');\n }\n return data as AppleMusicApiResource[];\n}\n\n/**\n * Map a `data` array (or optional nested search bucket).\n * `undefined` / `null` → empty (type omitted from search). Non-array → reject.\n */\nexport function mapResourceArray<T>(\n data: unknown,\n mapper: (resource: AppleMusicApiResource) => T,\n): T[] {\n if (data === undefined || data === null) {\n return [];\n }\n if (!Array.isArray(data)) {\n throw errors.apiError('Apple Music API response \"data\" is not an array');\n }\n return data.map((item) => mapper(item as AppleMusicApiResource));\n}\n\n/** Parse required top-level `data`, then map resources. */\nexport function mapTopLevelResourceArray<T>(\n data: unknown,\n mapper: (resource: AppleMusicApiResource) => T,\n): T[] {\n return mapResourceArray(parseDataArray(data), mapper);\n}\n"]}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { AppleMusicRestTransport } from './apple-music-rest-transport';
|
|
2
|
+
export type StorefrontResolver = () => Promise<string | null | undefined>;
|
|
3
|
+
/** Resolves and caches the user's Apple Music storefront id for catalog paths. */
|
|
4
|
+
export declare class StorefrontRestClient {
|
|
5
|
+
private readonly transport;
|
|
6
|
+
private readonly resolveFromMusicKit?;
|
|
7
|
+
private cachedStorefront;
|
|
8
|
+
constructor(transport: AppleMusicRestTransport, resolveFromMusicKit?: StorefrontResolver | undefined);
|
|
9
|
+
/** Catalog storefront — MusicKit instance or locale fallback (no music user token). */
|
|
10
|
+
getStorefront(): Promise<string>;
|
|
11
|
+
/** User storefront from `/v1/me/storefront` (requires music user token). */
|
|
12
|
+
getUserStorefront(musicUserToken: string): Promise<string>;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=storefront-rest-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storefront-rest-client.d.ts","sourceRoot":"","sources":["../../src/rest/storefront-rest-client.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AAE5E,MAAM,MAAM,kBAAkB,GAAG,MAAM,OAAO,CAAC,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,CAAC;AAE1E,kFAAkF;AAClF,qBAAa,oBAAoB;IAI7B,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAC;IAJvC,OAAO,CAAC,gBAAgB,CAAuB;gBAG5B,SAAS,EAAE,uBAAuB,EAClC,mBAAmB,CAAC,EAAE,kBAAkB,YAAA;IAG3D,uFAAuF;IACjF,aAAa,IAAI,OAAO,CAAC,MAAM,CAAC;IAetC,4EAA4E;IACtE,iBAAiB,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CASjE"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { parseStorefrontId } from '../web/music-kit-api';
|
|
2
|
+
import * as errors from '../web/apple-music-errors';
|
|
3
|
+
/** Resolves and caches the user's Apple Music storefront id for catalog paths. */
|
|
4
|
+
export class StorefrontRestClient {
|
|
5
|
+
transport;
|
|
6
|
+
resolveFromMusicKit;
|
|
7
|
+
cachedStorefront = null;
|
|
8
|
+
constructor(transport, resolveFromMusicKit) {
|
|
9
|
+
this.transport = transport;
|
|
10
|
+
this.resolveFromMusicKit = resolveFromMusicKit;
|
|
11
|
+
}
|
|
12
|
+
/** Catalog storefront — MusicKit instance or locale fallback (no music user token). */
|
|
13
|
+
async getStorefront() {
|
|
14
|
+
if (this.cachedStorefront) {
|
|
15
|
+
return this.cachedStorefront;
|
|
16
|
+
}
|
|
17
|
+
const fromMusicKit = this.resolveFromMusicKit ? await this.resolveFromMusicKit() : null;
|
|
18
|
+
if (fromMusicKit) {
|
|
19
|
+
this.cachedStorefront = fromMusicKit;
|
|
20
|
+
return fromMusicKit;
|
|
21
|
+
}
|
|
22
|
+
this.cachedStorefront = 'us';
|
|
23
|
+
return 'us';
|
|
24
|
+
}
|
|
25
|
+
/** User storefront from `/v1/me/storefront` (requires music user token). */
|
|
26
|
+
async getUserStorefront(musicUserToken) {
|
|
27
|
+
const json = await this.transport.getJson('/v1/me/storefront', {}, musicUserToken);
|
|
28
|
+
const id = parseStorefrontId(json);
|
|
29
|
+
if (!id) {
|
|
30
|
+
throw errors.apiError('Storefront response missing id');
|
|
31
|
+
}
|
|
32
|
+
this.cachedStorefront = id;
|
|
33
|
+
return id;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=storefront-rest-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storefront-rest-client.js","sourceRoot":"","sources":["../../src/rest/storefront-rest-client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,KAAK,MAAM,MAAM,2BAA2B,CAAC;AAKpD,kFAAkF;AAClF,MAAM,OAAO,oBAAoB;IAIZ;IACA;IAJX,gBAAgB,GAAkB,IAAI,CAAC;IAE/C,YACmB,SAAkC,EAClC,mBAAwC;QADxC,cAAS,GAAT,SAAS,CAAyB;QAClC,wBAAmB,GAAnB,mBAAmB,CAAqB;IACxD,CAAC;IAEJ,uFAAuF;IACvF,KAAK,CAAC,aAAa;QACjB,IAAI,IAAI,CAAC,gBAAgB,EAAE,CAAC;YAC1B,OAAO,IAAI,CAAC,gBAAgB,CAAC;QAC/B,CAAC;QAED,MAAM,YAAY,GAAG,IAAI,CAAC,mBAAmB,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,mBAAmB,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;QACxF,IAAI,YAAY,EAAE,CAAC;YACjB,IAAI,CAAC,gBAAgB,GAAG,YAAY,CAAC;YACrC,OAAO,YAAY,CAAC;QACtB,CAAC;QAED,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC;QAC7B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,4EAA4E;IAC5E,KAAK,CAAC,iBAAiB,CAAC,cAAsB;QAC5C,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,mBAAmB,EAAE,EAAE,EAAE,cAAc,CAAC,CAAC;QACnF,MAAM,EAAE,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC;QACnC,IAAI,CAAC,EAAE,EAAE,CAAC;YACR,MAAM,MAAM,CAAC,QAAQ,CAAC,gCAAgC,CAAC,CAAC;QAC1D,CAAC;QACD,IAAI,CAAC,gBAAgB,GAAG,EAAE,CAAC;QAC3B,OAAO,EAAE,CAAC;IACZ,CAAC;CACF","sourcesContent":["import { parseStorefrontId } from '../web/music-kit-api';\nimport * as errors from '../web/apple-music-errors';\nimport type { AppleMusicRestTransport } from './apple-music-rest-transport';\n\nexport type StorefrontResolver = () => Promise<string | null | undefined>;\n\n/** Resolves and caches the user's Apple Music storefront id for catalog paths. */\nexport class StorefrontRestClient {\n private cachedStorefront: string | null = null;\n\n constructor(\n private readonly transport: AppleMusicRestTransport,\n private readonly resolveFromMusicKit?: StorefrontResolver,\n ) {}\n\n /** Catalog storefront — MusicKit instance or locale fallback (no music user token). */\n async getStorefront(): Promise<string> {\n if (this.cachedStorefront) {\n return this.cachedStorefront;\n }\n\n const fromMusicKit = this.resolveFromMusicKit ? await this.resolveFromMusicKit() : null;\n if (fromMusicKit) {\n this.cachedStorefront = fromMusicKit;\n return fromMusicKit;\n }\n\n this.cachedStorefront = 'us';\n return 'us';\n }\n\n /** User storefront from `/v1/me/storefront` (requires music user token). */\n async getUserStorefront(musicUserToken: string): Promise<string> {\n const json = await this.transport.getJson('/v1/me/storefront', {}, musicUserToken);\n const id = parseStorefrontId(json);\n if (!id) {\n throw errors.apiError('Storefront response missing id');\n }\n this.cachedStorefront = id;\n return id;\n }\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"album.d.ts","sourceRoot":"","sources":["../../src/types/album.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,KAAK;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;CACpB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"album.js","sourceRoot":"","sources":["../../src/types/album.ts"],"names":[],"mappings":"","sourcesContent":["export interface Album {\n artistName: string;\n title: string;\n artworkUrl: string;\n id: string;\n trackCount: number;\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"albums-response.d.ts","sourceRoot":"","sources":["../../src/types/albums-response.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAErC,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,KAAK,EAAE,CAAC;CACjB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"albums-response.js","sourceRoot":"","sources":["../../src/types/albums-response.ts"],"names":[],"mappings":"","sourcesContent":["import type { Album } from './album';\n\nexport interface AlbumsResponse {\n albums: Album[];\n}\n"]}
|