musora-content-services 1.3.18 → 2.0.2

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.
Files changed (46) hide show
  1. package/.editorconfig +16 -0
  2. package/CHANGELOG.md +1 -1
  3. package/docs/config.js.html +14 -5
  4. package/docs/content.js.html +425 -0
  5. package/docs/global.html +3026 -0
  6. package/docs/index.html +2 -2
  7. package/docs/module-Config.html +60 -7
  8. package/docs/module-Content-Services-V2.html +2433 -0
  9. package/docs/module-Railcontent-Services.html +522 -2
  10. package/docs/module-Sanity-Services.html +57 -43
  11. package/docs/module-Session-Management.html +575 -0
  12. package/docs/module-User-Permissions.html +406 -0
  13. package/docs/railcontent.js.html +42 -5
  14. package/docs/sanity.js.html +290 -103
  15. package/docs/user_permissions.js.html +110 -0
  16. package/docs/user_sessions.js.html +139 -0
  17. package/docs/user_types.js.html +188 -0
  18. package/jsdoc.json +2 -0
  19. package/package.json +1 -1
  20. package/publish.sh +2 -2
  21. package/src/contentMetaData.js +307 -1088
  22. package/src/contentTypeConfig.js +108 -4
  23. package/src/filterBuilder.js +6 -6
  24. package/src/index.d.ts +41 -6
  25. package/src/index.js +41 -6
  26. package/src/{services → lib}/lastUpdated.js +17 -1
  27. package/src/services/config.js +0 -0
  28. package/src/services/content.js +371 -0
  29. package/src/services/dataContext.js +0 -0
  30. package/src/services/forum.js +57 -0
  31. package/src/services/railcontent.js +3 -3
  32. package/src/services/recommendations.js +19 -0
  33. package/src/services/sanity.js +278 -104
  34. package/src/services/{userPermissions.js → user/permissions.js} +16 -2
  35. package/src/services/user/sessions.js +67 -0
  36. package/src/services/user/types.js +116 -0
  37. package/src/services/userActivity.js +32 -0
  38. package/test/content.test.js +116 -0
  39. package/test/contentLikes.test.js +0 -0
  40. package/test/contentProgress.test.js +83 -5
  41. package/test/forum.test.js +18 -0
  42. package/test/initializeTests.js +6 -1
  43. package/test/{lastUpdated.test.js → lib/lastUpdated.test.js} +2 -5
  44. package/test/sanityQueryService.test.js +66 -18
  45. package/test/{userPermissions.test.js → user/permissions.test.js} +3 -3
  46. package/tools/generate-index.cjs +16 -3
package/.editorconfig ADDED
@@ -0,0 +1,16 @@
1
+ root = true
2
+
3
+ [*]
4
+ charset = utf-8
5
+ end_of_line = lf
6
+ insert_final_newline = true
7
+ indent_style = space
8
+ indent_size = 2
9
+ trim_trailing_whitespace = true
10
+
11
+ [*.md]
12
+ trim_trailing_whitespace = false
13
+
14
+ [*.{yml,yaml}]
15
+ indent_size = 2
16
+
package/CHANGELOG.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
4
4
 
5
- ### [1.3.18](https://github.com/railroadmedia/musora-content-services/compare/v1.3.17...v1.3.18) (2025-03-18)
5
+ ### [2.0.2](https://github.com/railroadmedia/musora-content-services/compare/v1.3.17...v2.0.2) (2025-03-17)
6
6
 
7
7
  ### [1.3.17](https://github.com/railroadmedia/musora-content-services/compare/v1.3.16...v1.3.17) (2025-03-17)
8
8
 
@@ -29,7 +29,7 @@
29
29
  <nav >
30
30
 
31
31
 
32
- <h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-Config.html">Config</a><ul class='methods'><li data-type='method'><a href="module-Config.html#.initializeService">initializeService</a></li></ul></li><li><a href="module-Railcontent-Services.html">Railcontent-Services</a><ul class='methods'><li data-type='method'><a href="module-Railcontent-Services.html#.addItemToPlaylist">addItemToPlaylist</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.countAssignmentsAndLessons">countAssignmentsAndLessons</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.createPlaylist">createPlaylist</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.deletePlaylist">deletePlaylist</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.deletePlaylistItem">deletePlaylistItem</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.deletePlaylistLike">deletePlaylistLike</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.duplicatePlaylist">duplicatePlaylist</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchAllCompletedStates">fetchAllCompletedStates</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchCarouselCardData">fetchCarouselCardData</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchChallengeIndexMetadata">fetchChallengeIndexMetadata</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchChallengeLessonData">fetchChallengeLessonData</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchChallengeMetadata">fetchChallengeMetadata</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchChallengeUserActiveChallenges">fetchChallengeUserActiveChallenges</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchCompletedChallenges">fetchCompletedChallenges</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchCompletedContent">fetchCompletedContent</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchCompletedState">fetchCompletedState</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchContentInProgress">fetchContentInProgress</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchContentPageUserData">fetchContentPageUserData</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchNextContentDataForParent">fetchNextContentDataForParent</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchOwnedChallenges">fetchOwnedChallenges</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchPinnedPlaylists">fetchPinnedPlaylists</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchPlaylist">fetchPlaylist</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchPlaylistItem">fetchPlaylistItem</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchPlaylistItems">fetchPlaylistItems</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchSongsInProgress">fetchSongsInProgress</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchUserAward">fetchUserAward</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchUserBadges">fetchUserBadges</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchUserChallengeProgress">fetchUserChallengeProgress</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchUserPlaylists">fetchUserPlaylists</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.likePlaylist">likePlaylist</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.pinPlaylist">pinPlaylist</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.postChallengesCommunityNotification">postChallengesCommunityNotification</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.postChallengesCompleteLesson">postChallengesCompleteLesson</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.postChallengesEnroll">postChallengesEnroll</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.postChallengesEnrollmentNotification">postChallengesEnrollmentNotification</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.postChallengesHideCompletedBanner">postChallengesHideCompletedBanner</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.postChallengesLeave">postChallengesLeave</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.postChallengesSetStartDate">postChallengesSetStartDate</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.postChallengesSoloNotification">postChallengesSoloNotification</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.postChallengesUnlock">postChallengesUnlock</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.reportPlaylist">reportPlaylist</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.setStudentViewForUser">setStudentViewForUser</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.unpinPlaylist">unpinPlaylist</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.updatePlaylist">updatePlaylist</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.updatePlaylistItem">updatePlaylistItem</a></li></ul></li><li><a href="module-Sanity-Services.html">Sanity-Services</a><ul class='methods'><li data-type='method'><a href="module-Sanity-Services.html#.fetchAll">fetchAll</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchAllFilterOptions">fetchAllFilterOptions</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchAllPacks">fetchAllPacks</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchArtistLessons">fetchArtistLessons</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchArtists">fetchArtists</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchByRailContentId">fetchByRailContentId</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchByRailContentIds">fetchByRailContentIds</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchByReference">fetchByReference</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchCoachLessons">fetchCoachLessons</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchComingSoon">fetchComingSoon</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchCommentModContentData">fetchCommentModContentData</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchFoundation">fetchFoundation</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchGenreLessons">fetchGenreLessons</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchLeaving">fetchLeaving</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchLessonContent">fetchLessonContent</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchMetadata">fetchMetadata</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchMethod">fetchMethod</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchMethodChildren">fetchMethodChildren</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchMethodChildrenIds">fetchMethodChildrenIds</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchMethodPreviousNextLesson">fetchMethodPreviousNextLesson</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchNewReleases">fetchNewReleases</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchNextPreviousLesson">fetchNextPreviousLesson</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchPackAll">fetchPackAll</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchPackData">fetchPackData</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchParentForDownload">fetchParentForDownload</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchRelatedLessons">fetchRelatedLessons</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchRelatedSongs">fetchRelatedSongs</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchReturning">fetchReturning</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchSanity">fetchSanity</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchScheduledReleases">fetchScheduledReleases</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchShowsData">fetchShowsData</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchSongArtistCount">fetchSongArtistCount</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchSongById">fetchSongById</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchUpcomingEvents">fetchUpcomingEvents</a></li><li data-type='method'><a href="module-Sanity-Services.html#.jumpToContinueContent">jumpToContinueContent</a></li><li data-type='method'><a href="module-Sanity-Services.html#~getNextAndPreviousQuarterDates">getNextAndPreviousQuarterDates</a></li><li data-type='method'><a href="module-Sanity-Services.html#~getQueryFromPage">getQueryFromPage</a></li><li data-type='method'><a href="module-Sanity-Services.html#~handleCustomFetchAll">handleCustomFetchAll</a></li></ul></li></ul>
32
+ <h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-Config.html">Config</a><ul class='methods'><li data-type='method'><a href="module-Config.html#.initializeService">initializeService</a></li></ul></li><li><a href="module-Content-Services-V2.html">Content-Services-V2</a><ul class='methods'><li data-type='method'><a href="module-Content-Services-V2.html#.getContentRows">getContentRows</a></li><li data-type='method'><a href="module-Content-Services-V2.html#.getNewAndUpcoming">getNewAndUpcoming</a></li><li data-type='method'><a href="module-Content-Services-V2.html#.getRecent">getRecent</a></li><li data-type='method'><a href="module-Content-Services-V2.html#.getRecommendedForYou">getRecommendedForYou</a></li><li data-type='method'><a href="module-Content-Services-V2.html#.getScheduleContentRows">getScheduleContentRows</a></li><li data-type='method'><a href="module-Content-Services-V2.html#.getTabResults">getTabResults</a></li></ul></li><li><a href="module-Railcontent-Services.html">Railcontent-Services</a><ul class='methods'><li data-type='method'><a href="module-Railcontent-Services.html#.addItemToPlaylist">addItemToPlaylist</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.countAssignmentsAndLessons">countAssignmentsAndLessons</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.createPlaylist">createPlaylist</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.deletePlaylist">deletePlaylist</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.deletePlaylistItem">deletePlaylistItem</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.deletePlaylistLike">deletePlaylistLike</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.duplicatePlaylist">duplicatePlaylist</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchAllCompletedStates">fetchAllCompletedStates</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchCarouselCardData">fetchCarouselCardData</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchChallengeIndexMetadata">fetchChallengeIndexMetadata</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchChallengeLessonData">fetchChallengeLessonData</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchChallengeMetadata">fetchChallengeMetadata</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchChallengeUserActiveChallenges">fetchChallengeUserActiveChallenges</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchCommentRelies">fetchCommentRelies</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchComments">fetchComments</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchCompletedChallenges">fetchCompletedChallenges</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchCompletedContent">fetchCompletedContent</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchCompletedState">fetchCompletedState</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchContentInProgress">fetchContentInProgress</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchContentPageUserData">fetchContentPageUserData</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchNextContentDataForParent">fetchNextContentDataForParent</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchOwnedChallenges">fetchOwnedChallenges</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchPinnedPlaylists">fetchPinnedPlaylists</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchPlaylist">fetchPlaylist</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchPlaylistItem">fetchPlaylistItem</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchPlaylistItems">fetchPlaylistItems</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchSongsInProgress">fetchSongsInProgress</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchTopComment">fetchTopComment</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchUserAward">fetchUserAward</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchUserBadges">fetchUserBadges</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchUserChallengeProgress">fetchUserChallengeProgress</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchUserPlaylists">fetchUserPlaylists</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.likePlaylist">likePlaylist</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.pinPlaylist">pinPlaylist</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.postChallengesCommunityNotification">postChallengesCommunityNotification</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.postChallengesCompleteLesson">postChallengesCompleteLesson</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.postChallengesEnroll">postChallengesEnroll</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.postChallengesEnrollmentNotification">postChallengesEnrollmentNotification</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.postChallengesHideCompletedBanner">postChallengesHideCompletedBanner</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.postChallengesLeave">postChallengesLeave</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.postChallengesSetStartDate">postChallengesSetStartDate</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.postChallengesSoloNotification">postChallengesSoloNotification</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.postChallengesUnlock">postChallengesUnlock</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.reportPlaylist">reportPlaylist</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.setStudentViewForUser">setStudentViewForUser</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.unpinPlaylist">unpinPlaylist</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.updatePlaylist">updatePlaylist</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.updatePlaylistItem">updatePlaylistItem</a></li></ul></li><li><a href="module-Sanity-Services.html">Sanity-Services</a><ul class='methods'><li data-type='method'><a href="module-Sanity-Services.html#.fetchAll">fetchAll</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchAllFilterOptions">fetchAllFilterOptions</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchAllPacks">fetchAllPacks</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchArtistLessons">fetchArtistLessons</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchArtists">fetchArtists</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchByRailContentId">fetchByRailContentId</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchByRailContentIds">fetchByRailContentIds</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchByReference">fetchByReference</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchCoachLessons">fetchCoachLessons</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchComingSoon">fetchComingSoon</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchCommentModContentData">fetchCommentModContentData</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchFoundation">fetchFoundation</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchGenreLessons">fetchGenreLessons</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchLeaving">fetchLeaving</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchLessonContent">fetchLessonContent</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchMetadata">fetchMetadata</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchMethod">fetchMethod</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchMethodChildren">fetchMethodChildren</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchMethodChildrenIds">fetchMethodChildrenIds</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchMethodPreviousNextLesson">fetchMethodPreviousNextLesson</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchNewReleases">fetchNewReleases</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchNextPreviousLesson">fetchNextPreviousLesson</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchPackAll">fetchPackAll</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchPackData">fetchPackData</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchParentForDownload">fetchParentForDownload</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchRelatedLessons">fetchRelatedLessons</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchRelatedSongs">fetchRelatedSongs</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchReturning">fetchReturning</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchSanity">fetchSanity</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchScheduledReleases">fetchScheduledReleases</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchShowsData">fetchShowsData</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchSongArtistCount">fetchSongArtistCount</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchSongById">fetchSongById</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchUpcomingEvents">fetchUpcomingEvents</a></li><li data-type='method'><a href="module-Sanity-Services.html#.jumpToContinueContent">jumpToContinueContent</a></li><li data-type='method'><a href="module-Sanity-Services.html#~getNextAndPreviousQuarterDates">getNextAndPreviousQuarterDates</a></li><li data-type='method'><a href="module-Sanity-Services.html#~getQueryFromPage">getQueryFromPage</a></li><li data-type='method'><a href="module-Sanity-Services.html#~handleCustomFetchAll">handleCustomFetchAll</a></li></ul></li><li><a href="module-Session-Management.html">Session-Management</a><ul class='methods'><li data-type='method'><a href="module-Session-Management.html#.login">login</a></li><li data-type='method'><a href="module-Session-Management.html#.logout">logout</a></li></ul></li><li><a href="module-User-Permissions.html">User-Permissions</a><ul class='methods'><li data-type='method'><a href="module-User-Permissions.html#.fetchUserPermissions">fetchUserPermissions</a></li><li data-type='method'><a href="module-User-Permissions.html#.reset">reset</a></li></ul></li></ul><h3><a href="global.html">Global</a></h3>
33
33
 
34
34
  </nav>
35
35
 
@@ -52,6 +52,7 @@
52
52
  export let globalConfig = {
53
53
  sanityConfig: {},
54
54
  railcontentConfig: {},
55
+ recommendationsConfig: {},
55
56
  localStorage: null,
56
57
  isMA: false,
57
58
  localTimezoneString: null, // In format: America/Vancouver
@@ -82,6 +83,8 @@ const excludeFromGeneratedIndex = []
82
83
  * @param {string} config.railcontentConfig.userId - The user ID for fetching user-specific data.
83
84
  * @param {string} config.railcontentConfig.baseUrl - The url for the environment.
84
85
  * @param {string} config.railcontentConfig.authToken - The bearer authorization token.
86
+ * @param {string} config.recommendationsConfig.token - The token for authenticating recommendation requests.
87
+ * @param {string} config.recommendationsConfig.baseUrl - The url for the recommendation server.
85
88
  * @param {Object} config.localStorage - Cache to use for localStorage
86
89
  * @param {boolean} config.isMA - Variable that tells if the library is used by MA or FEW
87
90
  * @param {string} config.localTimezoneString - The local timezone string in format: America/Vancouver
@@ -96,15 +99,20 @@ const excludeFromGeneratedIndex = []
96
99
  * dataset: 'your-dataset-name',
97
100
  * version: '2021-06-07',
98
101
  * debug: true,
99
- * useCachedAPI: false
102
+ * useCachedAPI: false,
100
103
  * },
101
104
  * railcontentConfig: {
102
105
  * token: 'your-user-api-token',
103
106
  * userId: 'current-user-id',
104
- * baseUrl: 'https://web-staging-one.musora.com'
107
+ * baseUrl: 'https://web-staging-one.musora.com',
108
+ * authToken 'your-auth-token',
109
+ * },
110
+ * recommendationsConfig: {
111
+ * token: 'your-user-api-token',
112
+ * baseUrl: 'https://MusoraProductDepartment-PWGenerator.hf.space',
105
113
  * },
106
114
  * localStorage: localStorage,
107
- * isMA: false
115
+ * isMA: false,
108
116
  * });
109
117
  */
110
118
  export function initializeService(config) {
@@ -113,6 +121,7 @@ export function initializeService(config) {
113
121
  globalConfig.localStorage = config.localStorage
114
122
  globalConfig.isMA = config.isMA || false
115
123
  globalConfig.localTimezoneString = config.localTimezoneString || null
124
+ globalConfig.recommendationsConfig = config.recommendationsConfig
116
125
  }
117
126
  </code></pre>
118
127
  </article>
@@ -128,7 +137,7 @@ export function initializeService(config) {
128
137
  <br class="clear">
129
138
 
130
139
  <footer>
131
- Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.3</a> on Fri Feb 21 2025 20:42:51 GMT+0000 (Coordinated Universal Time) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
140
+ Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.3</a> on Thu Mar 13 2025 09:07:06 GMT+0000 (Coordinated Universal Time) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
132
141
  </footer>
133
142
 
134
143
  <script>prettyPrint();</script>
@@ -0,0 +1,425 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+
5
+ <meta charset="utf-8">
6
+ <title>content.js - Documentation</title>
7
+
8
+
9
+ <script src="scripts/prettify/prettify.js"></script>
10
+ <script src="scripts/prettify/lang-css.js"></script>
11
+ <!--[if lt IE 9]>
12
+ <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
13
+ <![endif]-->
14
+ <link type="text/css" rel="stylesheet" href="styles/prettify.css">
15
+ <link type="text/css" rel="stylesheet" href="styles/jsdoc.css">
16
+ <script src="scripts/nav.js" defer></script>
17
+
18
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
19
+ </head>
20
+ <body>
21
+
22
+ <input type="checkbox" id="nav-trigger" class="nav-trigger" />
23
+ <label for="nav-trigger" class="navicon-button x">
24
+ <div class="navicon"></div>
25
+ </label>
26
+
27
+ <label for="nav-trigger" class="overlay"></label>
28
+
29
+ <nav >
30
+
31
+
32
+ <h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-Config.html">Config</a><ul class='methods'><li data-type='method'><a href="module-Config.html#.initializeService">initializeService</a></li></ul></li><li><a href="module-Content-Services-V2.html">Content-Services-V2</a><ul class='methods'><li data-type='method'><a href="module-Content-Services-V2.html#.getContentRows">getContentRows</a></li><li data-type='method'><a href="module-Content-Services-V2.html#.getNewAndUpcoming">getNewAndUpcoming</a></li><li data-type='method'><a href="module-Content-Services-V2.html#.getRecent">getRecent</a></li><li data-type='method'><a href="module-Content-Services-V2.html#.getRecommendedForYou">getRecommendedForYou</a></li><li data-type='method'><a href="module-Content-Services-V2.html#.getScheduleContentRows">getScheduleContentRows</a></li><li data-type='method'><a href="module-Content-Services-V2.html#.getTabResults">getTabResults</a></li></ul></li><li><a href="module-Railcontent-Services.html">Railcontent-Services</a><ul class='methods'><li data-type='method'><a href="module-Railcontent-Services.html#.addItemToPlaylist">addItemToPlaylist</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.countAssignmentsAndLessons">countAssignmentsAndLessons</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.createPlaylist">createPlaylist</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.deletePlaylist">deletePlaylist</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.deletePlaylistItem">deletePlaylistItem</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.deletePlaylistLike">deletePlaylistLike</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.duplicatePlaylist">duplicatePlaylist</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchAllCompletedStates">fetchAllCompletedStates</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchCarouselCardData">fetchCarouselCardData</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchChallengeIndexMetadata">fetchChallengeIndexMetadata</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchChallengeLessonData">fetchChallengeLessonData</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchChallengeMetadata">fetchChallengeMetadata</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchChallengeUserActiveChallenges">fetchChallengeUserActiveChallenges</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchCommentRelies">fetchCommentRelies</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchComments">fetchComments</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchCompletedChallenges">fetchCompletedChallenges</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchCompletedContent">fetchCompletedContent</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchCompletedState">fetchCompletedState</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchContentInProgress">fetchContentInProgress</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchContentPageUserData">fetchContentPageUserData</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchNextContentDataForParent">fetchNextContentDataForParent</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchOwnedChallenges">fetchOwnedChallenges</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchPinnedPlaylists">fetchPinnedPlaylists</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchPlaylist">fetchPlaylist</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchPlaylistItem">fetchPlaylistItem</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchPlaylistItems">fetchPlaylistItems</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchSongsInProgress">fetchSongsInProgress</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchTopComment">fetchTopComment</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchUserAward">fetchUserAward</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchUserBadges">fetchUserBadges</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchUserChallengeProgress">fetchUserChallengeProgress</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchUserPlaylists">fetchUserPlaylists</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.likePlaylist">likePlaylist</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.pinPlaylist">pinPlaylist</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.postChallengesCommunityNotification">postChallengesCommunityNotification</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.postChallengesCompleteLesson">postChallengesCompleteLesson</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.postChallengesEnroll">postChallengesEnroll</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.postChallengesEnrollmentNotification">postChallengesEnrollmentNotification</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.postChallengesHideCompletedBanner">postChallengesHideCompletedBanner</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.postChallengesLeave">postChallengesLeave</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.postChallengesSetStartDate">postChallengesSetStartDate</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.postChallengesSoloNotification">postChallengesSoloNotification</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.postChallengesUnlock">postChallengesUnlock</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.reportPlaylist">reportPlaylist</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.setStudentViewForUser">setStudentViewForUser</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.unpinPlaylist">unpinPlaylist</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.updatePlaylist">updatePlaylist</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.updatePlaylistItem">updatePlaylistItem</a></li></ul></li><li><a href="module-Sanity-Services.html">Sanity-Services</a><ul class='methods'><li data-type='method'><a href="module-Sanity-Services.html#.fetchAll">fetchAll</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchAllFilterOptions">fetchAllFilterOptions</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchAllPacks">fetchAllPacks</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchArtistLessons">fetchArtistLessons</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchArtists">fetchArtists</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchByRailContentId">fetchByRailContentId</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchByRailContentIds">fetchByRailContentIds</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchByReference">fetchByReference</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchCoachLessons">fetchCoachLessons</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchComingSoon">fetchComingSoon</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchCommentModContentData">fetchCommentModContentData</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchFoundation">fetchFoundation</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchGenreLessons">fetchGenreLessons</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchLeaving">fetchLeaving</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchLessonContent">fetchLessonContent</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchMetadata">fetchMetadata</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchMethod">fetchMethod</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchMethodChildren">fetchMethodChildren</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchMethodChildrenIds">fetchMethodChildrenIds</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchMethodPreviousNextLesson">fetchMethodPreviousNextLesson</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchNewReleases">fetchNewReleases</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchNextPreviousLesson">fetchNextPreviousLesson</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchPackAll">fetchPackAll</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchPackData">fetchPackData</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchParentForDownload">fetchParentForDownload</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchRelatedLessons">fetchRelatedLessons</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchRelatedSongs">fetchRelatedSongs</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchReturning">fetchReturning</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchSanity">fetchSanity</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchScheduledReleases">fetchScheduledReleases</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchShowsData">fetchShowsData</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchSongArtistCount">fetchSongArtistCount</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchSongById">fetchSongById</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchUpcomingEvents">fetchUpcomingEvents</a></li><li data-type='method'><a href="module-Sanity-Services.html#.jumpToContinueContent">jumpToContinueContent</a></li><li data-type='method'><a href="module-Sanity-Services.html#~getNextAndPreviousQuarterDates">getNextAndPreviousQuarterDates</a></li><li data-type='method'><a href="module-Sanity-Services.html#~getQueryFromPage">getQueryFromPage</a></li><li data-type='method'><a href="module-Sanity-Services.html#~handleCustomFetchAll">handleCustomFetchAll</a></li></ul></li><li><a href="module-Session-Management.html">Session-Management</a><ul class='methods'><li data-type='method'><a href="module-Session-Management.html#.login">login</a></li><li data-type='method'><a href="module-Session-Management.html#.logout">logout</a></li></ul></li><li><a href="module-User-Permissions.html">User-Permissions</a><ul class='methods'><li data-type='method'><a href="module-User-Permissions.html#.fetchUserPermissions">fetchUserPermissions</a></li><li data-type='method'><a href="module-User-Permissions.html#.reset">reset</a></li></ul></li></ul><h3><a href="global.html">Global</a></h3>
33
+
34
+ </nav>
35
+
36
+ <div id="main">
37
+
38
+ <h1 class="page-title">content.js</h1>
39
+
40
+
41
+
42
+
43
+
44
+
45
+
46
+ <section>
47
+ <article>
48
+ <pre class="prettyprint source linenums"><code>/**
49
+ * @module Content-Services-V2
50
+ */
51
+
52
+ import {
53
+ fetchAll,
54
+ fetchByRailContentIds,
55
+ fetchMetadata,
56
+ fetchRecent,
57
+ fetchTabData,
58
+ fetchNewReleases,
59
+ fetchUpcomingEvents,
60
+ fetchScheduledReleases,
61
+ fetchReturning,
62
+ fetchLeaving, fetchScheduledAndNewReleases
63
+ } from './sanity.js'
64
+ import {TabResponseType, Tabs, capitalizeFirstLetter} from '../contentMetaData.js'
65
+ import {getAllStartedOrCompleted} from "./contentProgress";
66
+ import {fetchHandler} from "./railcontent";
67
+ import {recommendations} from "./recommendations";
68
+
69
+ export async function getLessonContentRows (brand='drumeo', pageName = 'lessons') {
70
+ let recentContentIds = await fetchRecent(brand, pageName, { progress: 'recent' });
71
+ recentContentIds = recentContentIds.map(item => item.id);
72
+
73
+ let contentRows = await getContentRows(brand, pageName);
74
+ contentRows = Array.isArray(contentRows) ? contentRows : [];
75
+ contentRows.unshift({
76
+ id: 'recent',
77
+ title: 'Recent ' + capitalizeFirstLetter(pageName),
78
+ content: recentContentIds || []
79
+ });
80
+
81
+ const results = await Promise.all(
82
+ contentRows.map(async (row) => {
83
+ if (row.content.length == 0){
84
+ return { id: row.id, title: row.title, items: [] }
85
+ }
86
+ const data = await fetchByRailContentIds(row.content)
87
+ return { id: row.id, title: row.title, items: data }
88
+ })
89
+ )
90
+ return results
91
+ }
92
+
93
+ /**
94
+ * Get data that should be displayed for a specific tab with pagination
95
+ * @param {string} brand - The brand for which to fetch data.
96
+ * @param {string} pageName - The page name (e.g., 'lessons', 'songs','challenges).
97
+ * @param {string} tabName - The name for the selected tab. Should be same name received from fetchMetadata (e.g., 'Individuals', 'Collections','For You').
98
+ * @param {Object} params - Parameters for pagination, sorting, and filter.
99
+ * @param {number} [params.page=1] - The page number for pagination.
100
+ * @param {number} [params.limit=10] - The number of items per page.
101
+ * @param {string} [params.sort="-published_on"] - The field to sort the data by.
102
+ * @param {Array&lt;string>} [params.selectedFilters=[]] - The selected filter.
103
+ * @returns {Promise&lt;Object|null>} - The fetched content data or null if not found.
104
+ *
105
+ * @example
106
+ * getTabResults('drumeo', 'lessons','Singles', {
107
+ * page: 2,
108
+ * limit: 20,
109
+ * sort: '-popularity',
110
+ * includedFields: ['difficulty,Intermediate'],
111
+ * })
112
+ * .then(content => console.log(content))
113
+ * .catch(error => console.error(error));
114
+ */
115
+ export async function getTabResults(brand, pageName, tabName, {
116
+ page = 1,
117
+ limit = 10,
118
+ sort = 'recommended',
119
+ selectedFilters = []
120
+ } = {}) {
121
+
122
+ // Extract and handle 'progress' filter separately
123
+ const progressFilter = selectedFilters.find(f => f.startsWith('progress,')) || 'progress,all';
124
+ const progressValue = progressFilter.split(',')[1].toLowerCase();
125
+ const filteredSelectedFilters = selectedFilters.filter(f => !f.startsWith('progress,'));
126
+
127
+ // Prepare included fields
128
+ const mergedIncludedFields = [...filteredSelectedFilters, `tab,${tabName.toLowerCase()}`];
129
+
130
+ // Fetch data
131
+ const results = tabName === Tabs.ForYou.name
132
+ ? { entity: await getLessonContentRows(brand, pageName) }
133
+ : await fetchTabData(brand, pageName, { page, limit, sort, includedFields: mergedIncludedFields, progress: progressValue });
134
+
135
+ // Fetch metadata
136
+ const metaData = await fetchMetadata(brand, pageName);
137
+
138
+ // Process filters
139
+ const filters = (metaData.filters ?? []).map(filter => ({
140
+ ...filter,
141
+ items: filter.items.map(item => {
142
+ const value = item.value.split(',')[1];
143
+ return {
144
+ ...item,
145
+ selected: selectedFilters.includes(`${filter.key},${value}`) ||
146
+ (filter.key === 'progress' &amp;&amp; value === 'all' &amp;&amp; !selectedFilters.some(f => f.startsWith('progress,')))
147
+ };
148
+ })
149
+ }));
150
+
151
+ // Process sort options
152
+ const sortOptions = {
153
+ title: metaData.sort?.title ?? 'Sort By',
154
+ type: metaData.sort?.type ?? 'radio',
155
+ items: (metaData.sort?.items ?? []).map(option => ({
156
+ ...option,
157
+ selected: option.value === sort
158
+ }))
159
+ };
160
+
161
+ return {
162
+ type: tabName === Tabs.ForYou.name ? TabResponseType.SECTIONS : TabResponseType.CATALOG,
163
+ data: results.entity,
164
+ meta: { filters, sort: sortOptions }
165
+ };
166
+ }
167
+
168
+ /**
169
+ * Fetches recent content for a given brand and page with pagination.
170
+ *
171
+ * @param {string} brand - The brand for which to fetch data.
172
+ * @param {string} pageName - The page name (e.g., 'all', 'incomplete', 'completed').
173
+ * @param {string} [tabName='all'] - The tab name (defaults to 'all' for recent content).
174
+ * @param {Object} params - Parameters for pagination and sorting.
175
+ * @param {number} [params.page=1] - The page number for pagination.
176
+ * @param {number} [params.limit=10] - The number of items per page.
177
+ * @param {string} [params.sort="-published_on"] - The field to sort the data by.
178
+ * @returns {Promise&lt;Object>} - The fetched content data.
179
+ *
180
+ * @example
181
+ * getRecent('drumeo', 'lessons', 'all', {
182
+ * page: 2,
183
+ * limit: 15,
184
+ * sort: '-popularity'
185
+ * })
186
+ * .then(content => console.log(content))
187
+ * .catch(error => console.error(error));
188
+ */
189
+ export async function getRecent(brand, pageName, tabName = 'all', {
190
+ page = 1,
191
+ limit = 10,
192
+ sort = '-published_on',
193
+ } = {}) {
194
+ const progress = tabName.toLowerCase() == 'all' ? 'recent':tabName.toLowerCase();
195
+ const recentContentIds = await fetchRecent(brand, pageName, { page:page, limit:limit, progress: progress });
196
+ const metaData = await fetchMetadata(brand, 'recent');
197
+ return {
198
+ type: TabResponseType.CATALOG,
199
+ data: recentContentIds,
200
+ meta: { tabs: metaData.tabs }
201
+ };
202
+ }
203
+
204
+ /**
205
+ * Fetches content rows for a given brand and page with optional filtering by content row id.
206
+ *
207
+ * @param {string} brand - The brand for which to fetch content rows.
208
+ * @param {string} pageName - The page name (e.g., 'lessons', 'songs', 'challenges').
209
+ * @param {string} [contentRowId] - The specific content row ID to fetch.
210
+ * @param {Object} params - Parameters for pagination.
211
+ * @param {number} [params.page=1] - The page number for pagination.
212
+ * @param {number} [params.limit=10] - The maximum number of content items per row.
213
+ * @returns {Promise&lt;Object>} - The fetched content rows.
214
+ *
215
+ * @example
216
+ * getContentRows('drumeo', 'lessons', 'Your-Daily-Warmup', {
217
+ * page: 1,
218
+ * limit: 5
219
+ * })
220
+ * .then(content => console.log(content))
221
+ * .catch(error => console.error(error));
222
+ */
223
+ export async function getContentRows(brand, pageName, contentRowId , {
224
+ page = 1,
225
+ limit = 10,
226
+ } = {}) {
227
+ const contentRow = contentRowId ? `&amp;content_row_id=${contentRowId}` : ''
228
+ const url = `/api/content/v1/rows?brand=${brand}&amp;page_name=${pageName}${contentRow}&amp;page=${page}&amp;limit=${limit}`;
229
+ return await fetchHandler(url, 'get', null);
230
+ }
231
+
232
+ /**
233
+ * Fetches new and upcoming releases for a given brand with pagination options.
234
+ *
235
+ * @param {string} brand - The brand for which to fetch new and upcoming releases.
236
+ * @param {Object} [params={}] - Pagination parameters.
237
+ * @param {number} [params.page=1] - The page number for pagination.
238
+ * @param {number} [params.limit=10] - The maximum number of content items to fetch.
239
+ * @returns {Promise&lt;{ data: Object[] } | null>} - A promise that resolves to the fetched content data or `null` if no data is found.
240
+ *
241
+ * @example
242
+ * // Fetch the first page with 10 results
243
+ * getNewAndUpcoming('drumeo')
244
+ * .then(response => console.log(response))
245
+ * .catch(error => console.error(error));
246
+ *
247
+ * @example
248
+ * // Fetch the second page with 20 results
249
+ * getNewAndUpcoming('drumeo', { page: 2, limit: 20 })
250
+ * .then(response => console.log(response))
251
+ * .catch(error => console.error(error));
252
+ */
253
+ export async function getNewAndUpcoming(brand, {
254
+ page = 1,
255
+ limit = 10,
256
+ } = {}) {
257
+
258
+ const data = await fetchScheduledAndNewReleases(brand, {page: page, limit: limit});
259
+ if (!data) {
260
+ return null;
261
+ }
262
+
263
+ return {
264
+ data: data,
265
+ };
266
+ }
267
+
268
+ /**
269
+ * Fetches scheduled content rows for a given brand with optional filtering by content row ID.
270
+ *
271
+ * @param {string} brand - The brand for which to fetch content rows.
272
+ * @param {string} [contentRowId=null] - The specific content row ID to fetch (optional).
273
+ * @param {Object} [params={}] - Pagination parameters.
274
+ * @param {number} [params.page=1] - The page number for pagination.
275
+ * @param {number} [params.limit=10] - The maximum number of content items per row.
276
+ * @returns {Promise&lt;Object>} - A promise that resolves to the fetched content rows.
277
+ *
278
+ * @example
279
+ * // Fetch all sections with default pagination
280
+ * getScheduleContentRows('drumeo')
281
+ * .then(content => console.log(content))
282
+ * .catch(error => console.error(error));
283
+ *
284
+ * @example
285
+ * // Fetch only the 'New-Releases' section with custom pagination
286
+ * getScheduleContentRows('drumeo', 'New-Releases', { page: 1, limit: 30 })
287
+ * .then(content => console.log(content))
288
+ * .catch(error => console.error(error));
289
+ *
290
+ * @example
291
+ * // Fetch only the 'Live-Streams' section with unlimited results
292
+ * getScheduleContentRows('drumeo', 'Live-Streams')
293
+ * .then(content => console.log(content))
294
+ * .catch(error => console.error(error));
295
+ */
296
+ export async function getScheduleContentRows(brand, contentRowId = null, { page = 1, limit = 10 } = {}) {
297
+ const sections = {
298
+ 'New-Releases': {
299
+ title: 'New Releases',
300
+ fetchMethod: fetchNewReleases
301
+ },
302
+ 'Live-Streams': {
303
+ title: 'Live Streams',
304
+ fetchMethod: fetchUpcomingEvents
305
+ },
306
+ 'Upcoming-Releases': {
307
+ title: 'Upcoming Releases',
308
+ fetchMethod: fetchScheduledReleases
309
+ },
310
+ 'Returning-Soon': {
311
+ title: 'Returning Soon',
312
+ fetchMethod: fetchReturning
313
+ },
314
+ 'Leaving-Soon': {
315
+ title: 'Leaving Soon',
316
+ fetchMethod: fetchLeaving
317
+ }
318
+ };
319
+
320
+ if (contentRowId) {
321
+ if (!sections[contentRowId]) {
322
+ return null; // Return null if the requested section does not exist
323
+ }
324
+
325
+ // Fetch only the requested section
326
+ const result = {
327
+ id: contentRowId,
328
+ title: sections[contentRowId].title,
329
+ content: await sections[contentRowId].fetchMethod(brand, { page, limit })
330
+ };
331
+
332
+ return {
333
+ type: TabResponseType.CATALOG,
334
+ data: result,
335
+ meta: {}
336
+ };
337
+ }
338
+
339
+ // If no specific contentRowId, fetch all sections
340
+ const results = await Promise.all(
341
+ Object.entries(sections).map(async ([id, section]) => {
342
+ // Apply special pagination rules
343
+ const isNewReleases = id === 'New-Releases';
344
+ const pagination = isNewReleases ? { page: 1, limit: 30 } : { page: 1, limit: Number.MAX_SAFE_INTEGER };
345
+
346
+ return {
347
+ id,
348
+ title: section.title,
349
+ content: await section.fetchMethod(brand, pagination)
350
+ };
351
+ })
352
+ );
353
+
354
+ return {
355
+ type: TabResponseType.SECTIONS,
356
+ data: results,
357
+ meta: {}
358
+ };
359
+ }
360
+
361
+ /**
362
+ * Fetches recommended content for a given brand with pagination support.
363
+ *
364
+ * @param {string} brand - The brand for which to fetch recommended content.
365
+ * @param {Object} [params={}] - Pagination parameters.
366
+ * @param {number} [params.page=1] - The page number for pagination.
367
+ * @param {number} [params.limit=10] - The maximum number of recommended content items per page.
368
+ * @returns {Promise&lt;Object>} - A promise that resolves to an object containing recommended content.
369
+ *
370
+ * @example
371
+ * // Fetch recommended content for a brand with default pagination
372
+ * getRecommendedForYou('drumeo')
373
+ * .then(content => console.log(content))
374
+ * .catch(error => console.error(error));
375
+ *
376
+ * @example
377
+ * // Fetch recommended content for a brand with custom pagination
378
+ * getRecommendedForYou('drumeo', { page: 2, limit: 5 })
379
+ * .then(content => console.log(content))
380
+ * .catch(error => console.error(error));
381
+ */
382
+ export async function getRecommendedForYou(brand, {
383
+ page = 1,
384
+ limit = 10,
385
+ } = {}) {
386
+ const requiredItems = page * limit;
387
+ const data = await recommendations(brand, {limit: requiredItems});
388
+ if (!data || !data.length) {
389
+ return { id: 'recommended', title: 'Recommended For You', items: [] };
390
+ }
391
+
392
+ // Apply pagination before calling fetchByRailContentIds
393
+ const startIndex = (page - 1) * limit;
394
+ const paginatedData = data.slice(startIndex, startIndex + limit);
395
+
396
+ const contents = await fetchByRailContentIds(paginatedData);
397
+ return { id: 'recommended', title: 'Recommended For You', items: contents }
398
+ }
399
+
400
+
401
+ </code></pre>
402
+ </article>
403
+ </section>
404
+
405
+
406
+
407
+
408
+
409
+
410
+ </div>
411
+
412
+ <br class="clear">
413
+
414
+ <footer>
415
+ Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.3</a> on Thu Mar 13 2025 09:07:06 GMT+0000 (Coordinated Universal Time) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
416
+ </footer>
417
+
418
+ <script>prettyPrint();</script>
419
+ <script src="scripts/polyfill.js"></script>
420
+ <script src="scripts/linenumber.js"></script>
421
+
422
+
423
+
424
+ </body>
425
+ </html>