musora-content-services 1.6.6 → 1.6.8

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 (76) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/docs/v2/ContentOrganization.html +2 -2
  3. package/docs/v2/Forums.html +269 -0
  4. package/docs/v2/Gamification.html +2 -2
  5. package/docs/v2/UserManagementSystem.html +2 -2
  6. package/docs/v2/api_types.js.html +2 -2
  7. package/docs/v2/config.js.html +2 -8
  8. package/docs/v2/content-org_content-org.js.html +2 -2
  9. package/docs/v2/content-org_guided-courses.ts.html +110 -0
  10. package/docs/v2/content-org_playlists-types.js.html +14 -2
  11. package/docs/v2/content-org_playlists.js.html +39 -17
  12. package/docs/v2/content.js.html +120 -64
  13. package/docs/v2/forums_categories.ts.html +137 -0
  14. package/docs/v2/forums_discussions.js.html +95 -0
  15. package/docs/v2/forums_forum.js.html +95 -0
  16. package/docs/v2/forums_forums.ts.html +77 -0
  17. package/docs/v2/forums_posts.ts.html +158 -0
  18. package/docs/v2/forums_threads.ts.html +271 -0
  19. package/docs/v2/gamification_awards.js.html +35 -534
  20. package/docs/v2/gamification_awards.ts.html +181 -0
  21. package/docs/v2/gamification_gamification.js.html +2 -2
  22. package/docs/v2/gamification_types.js.html +7 -25
  23. package/docs/v2/global.html +296 -492
  24. package/docs/v2/index.html +2 -3
  25. package/docs/v2/module-Accounts.html +1471 -0
  26. package/docs/v2/module-Awards.html +396 -14
  27. package/docs/v2/module-Categories.html +711 -0
  28. package/docs/v2/module-Config.html +4 -8
  29. package/docs/v2/module-Content-Services-V2.html +460 -46
  30. package/docs/v2/module-ForumCategories.html +687 -0
  31. package/docs/v2/module-ForumDiscussions.html +370 -0
  32. package/docs/v2/module-Forums.html +11961 -0
  33. package/docs/v2/module-GuidedCourses.html +108 -0
  34. package/docs/v2/module-Interests.html +2 -2
  35. package/docs/v2/module-Payments.html +250 -0
  36. package/docs/v2/module-Permissions.html +2 -2
  37. package/docs/v2/module-Playlists.html +212 -44
  38. package/docs/v2/module-Railcontent-Services.html +691 -2177
  39. package/docs/v2/module-Sanity-Services.html +200 -941
  40. package/docs/v2/module-Sessions.html +3 -3
  41. package/docs/v2/module-Threads.html +1119 -0
  42. package/docs/v2/module-UserActivity.html +193 -23
  43. package/docs/v2/module-UserChat.html +410 -0
  44. package/docs/v2/module-UserManagement.html +585 -12
  45. package/docs/v2/module-UserMemberships.html +556 -0
  46. package/docs/v2/module-UserNotifications.html +1399 -27
  47. package/docs/v2/module-UserProfile.html +106 -2
  48. package/docs/v2/railcontent.js.html +105 -235
  49. package/docs/v2/sanity.js.html +263 -415
  50. package/docs/v2/userActivity.js.html +532 -451
  51. package/docs/v2/user_account.ts.html +190 -0
  52. package/docs/v2/user_chat.js.html +98 -0
  53. package/docs/v2/user_interests.js.html +2 -2
  54. package/docs/v2/user_management.js.html +45 -2
  55. package/docs/v2/user_memberships.js.html +144 -0
  56. package/docs/v2/user_notifications.js.html +203 -21
  57. package/docs/v2/user_payments.ts.html +97 -0
  58. package/docs/v2/user_permissions.js.html +2 -2
  59. package/docs/v2/user_profile.js.html +12 -2
  60. package/docs/v2/user_sessions.js.html +33 -2
  61. package/docs/v2/user_types.js.html +10 -2
  62. package/docs/v2/user_user-management-system.js.html +2 -2
  63. package/link_mcs.sh +0 -0
  64. package/package.json +1 -1
  65. package/src/contentTypeConfig.js +3 -3
  66. package/src/services/sanity.js +5 -2
  67. package/docs/v2/Content-Organization.html +0 -245
  68. package/docs/v2/UserManagement.html +0 -269
  69. package/docs/v2/global.html#User +0 -293
  70. package/docs/v2/module-Notifications.html +0 -1183
  71. package/docs/v2/module-Session-Management.html +0 -575
  72. package/docs/v2/module-User-Activity.html +0 -4410
  73. package/docs/v2/module-User-Management.html +0 -490
  74. package/docs/v2/module-User-Permissions.html +0 -406
  75. package/docs/v2/types.js.html +0 -122
  76. package/docs/v2/user_user-management.js.html +0 -78
@@ -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-Awards.html">Awards</a><ul class='methods'><li data-type='method'><a href="module-Awards.html#.fetchAwardsForUser">fetchAwardsForUser</a></li></ul></li><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-Interests.html">Interests</a><ul class='methods'><li data-type='method'><a href="module-Interests.html#.fetchInterests">fetchInterests</a></li><li data-type='method'><a href="module-Interests.html#.fetchUninterests">fetchUninterests</a></li><li data-type='method'><a href="module-Interests.html#.markContentAsInterested">markContentAsInterested</a></li><li data-type='method'><a href="module-Interests.html#.markContentAsNotInterested">markContentAsNotInterested</a></li><li data-type='method'><a href="module-Interests.html#.removeContentAsInterested">removeContentAsInterested</a></li><li data-type='method'><a href="module-Interests.html#.removeContentAsNotInterested">removeContentAsNotInterested</a></li></ul></li><li><a href="module-Permissions.html">Permissions</a><ul class='methods'><li data-type='method'><a href="module-Permissions.html#.fetchUserPermissions">fetchUserPermissions</a></li><li data-type='method'><a href="module-Permissions.html#.reset">reset</a></li></ul></li><li><a href="module-Playlists.html">Playlists</a><ul class='methods'><li data-type='method'><a href="module-Playlists.html#.addItemToPlaylist">addItemToPlaylist</a></li><li data-type='method'><a href="module-Playlists.html#.createPlaylist">createPlaylist</a></li><li data-type='method'><a href="module-Playlists.html#.deletePlaylist">deletePlaylist</a></li><li data-type='method'><a href="module-Playlists.html#.duplicatePlaylist">duplicatePlaylist</a></li><li data-type='method'><a href="module-Playlists.html#.fetchPlaylist">fetchPlaylist</a></li><li data-type='method'><a href="module-Playlists.html#.fetchPlaylistItems">fetchPlaylistItems</a></li><li data-type='method'><a href="module-Playlists.html#.fetchUserPlaylists">fetchUserPlaylists</a></li><li data-type='method'><a href="module-Playlists.html#.togglePlaylistPrivate">togglePlaylistPrivate</a></li><li data-type='method'><a href="module-Playlists.html#.undeletePlaylist">undeletePlaylist</a></li><li data-type='method'><a href="module-Playlists.html#.updatePlaylist">updatePlaylist</a></li><li data-type='method'><a href="module-Playlists.html#~likePlaylist">likePlaylist</a></li><li data-type='method'><a href="module-Playlists.html#~reportPlaylist">reportPlaylist</a></li><li data-type='method'><a href="module-Playlists.html#~togglePlaylistPrivate">togglePlaylistPrivate</a></li><li data-type='method'><a href="module-Playlists.html#~unlikePlaylist">unlikePlaylist</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#.assignModeratorToComment">assignModeratorToComment</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.closeComment">closeComment</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.createComment">createComment</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.deleteComment">deleteComment</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.editComment">editComment</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#.fetchRecentUserActivities">fetchRecentUserActivities</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#.fetchUserPracticeNotes">fetchUserPracticeNotes</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.likeComment">likeComment</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.openComment">openComment</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#.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#.replyToComment">replyToComment</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.reportComment">reportComment</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#.unassignModeratorToComment">unassignModeratorToComment</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.unlikeComment">unlikeComment</a></li><li data-type='method'><a href="module-Railcontent-Services.html#~fetchLastInteractedChild">fetchLastInteractedChild</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#.fetchLessonsFeaturingThisContent">fetchLessonsFeaturingThisContent</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#.fetchOtherSongVersions">fetchOtherSongVersions</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#.fetchRelatedRecommendedContent">fetchRelatedRecommendedContent</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#~fetchRelatedByLicense">fetchRelatedByLicense</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-Sessions.html">Sessions</a><ul class='methods'><li data-type='method'><a href="module-Sessions.html#.login">login</a></li><li data-type='method'><a href="module-Sessions.html#.logout">logout</a></li></ul></li><li><a href="module-UserActivity.html">UserActivity</a><ul class='methods'><li data-type='method'><a href="module-UserActivity.html#.calculateLongestStreaks">calculateLongestStreaks</a></li><li data-type='method'><a href="module-UserActivity.html#.createPracticeNotes">createPracticeNotes</a></li><li data-type='method'><a href="module-UserActivity.html#.deletePracticeSession">deletePracticeSession</a></li><li data-type='method'><a href="module-UserActivity.html#.deleteUserActivity">deleteUserActivity</a></li><li data-type='method'><a href="module-UserActivity.html#.getPracticeNotes">getPracticeNotes</a></li><li data-type='method'><a href="module-UserActivity.html#.getPracticeSessions">getPracticeSessions</a></li><li data-type='method'><a href="module-UserActivity.html#.getProgressRows">getProgressRows</a></li><li data-type='method'><a href="module-UserActivity.html#.getRecentActivity">getRecentActivity</a></li><li data-type='method'><a href="module-UserActivity.html#.getUserMonthlyStats">getUserMonthlyStats</a></li><li data-type='method'><a href="module-UserActivity.html#.getUserWeeklyStats">getUserWeeklyStats</a></li><li data-type='method'><a href="module-UserActivity.html#.pinProgressRow">pinProgressRow</a></li><li data-type='method'><a href="module-UserActivity.html#.recordUserActivity">recordUserActivity</a></li><li data-type='method'><a href="module-UserActivity.html#.recordUserPractice">recordUserPractice</a></li><li data-type='method'><a href="module-UserActivity.html#.removeUserPractice">removeUserPractice</a></li><li data-type='method'><a href="module-UserActivity.html#.restorePracticeSession">restorePracticeSession</a></li><li data-type='method'><a href="module-UserActivity.html#.restoreUserPractice">restoreUserPractice</a></li><li data-type='method'><a href="module-UserActivity.html#.unpinProgressRow">unpinProgressRow</a></li><li data-type='method'><a href="module-UserActivity.html#.updatePracticeNotes">updatePracticeNotes</a></li><li data-type='method'><a href="module-UserActivity.html#.updateUserPractice">updateUserPractice</a></li></ul></li><li><a href="module-UserChat.html">UserChat</a><ul class='methods'><li data-type='method'><a href="module-UserChat.html#.fetchChatSettings">fetchChatSettings</a></li></ul></li><li><a href="module-UserManagement.html">UserManagement</a><ul class='methods'><li data-type='method'><a href="module-UserManagement.html#.blockUser">blockUser</a></li><li data-type='method'><a href="module-UserManagement.html#.deletePicture">deletePicture</a></li><li data-type='method'><a href="module-UserManagement.html#.unblockUser">unblockUser</a></li><li data-type='method'><a href="module-UserManagement.html#.uploadPicture">uploadPicture</a></li><li data-type='method'><a href="module-UserManagement.html#.uploadPictureFromS3">uploadPictureFromS3</a></li></ul></li><li><a href="module-UserNotifications.html">UserNotifications</a><ul class='methods'><li data-type='method'><a href="module-UserNotifications.html#.deleteNotification">deleteNotification</a></li><li data-type='method'><a href="module-UserNotifications.html#.fetchNotifications">fetchNotifications</a></li><li data-type='method'><a href="module-UserNotifications.html#.markAllNotificationsAsRead">markAllNotificationsAsRead</a></li><li data-type='method'><a href="module-UserNotifications.html#.markNotificationAsRead">markNotificationAsRead</a></li><li data-type='method'><a href="module-UserNotifications.html#.markNotificationAsUnread">markNotificationAsUnread</a></li></ul></li><li><a href="module-UserProfile.html">UserProfile</a><ul class='methods'><li data-type='method'><a href="module-UserProfile.html#.otherStats">otherStats</a></li></ul></li></ul><h3>Namespaces</h3><ul><li><a href="ContentOrganization.html">ContentOrganization</a></li><li><a href="Gamification.html">Gamification</a></li><li><a href="UserManagementSystem.html">UserManagementSystem</a></li></ul><h3><a href="global.html">Global</a></h3>
32
+ <h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-Accounts.html">Accounts</a><ul class='methods'><li data-type='method'><a href="module-Accounts.html#~confirmEmailChange">confirmEmailChange</a></li><li data-type='method'><a href="module-Accounts.html#~requestEmailChange">requestEmailChange</a></li><li data-type='method'><a href="module-Accounts.html#~resetPassword">resetPassword</a></li><li data-type='method'><a href="module-Accounts.html#~sendAccountSetupEmail">sendAccountSetupEmail</a></li><li data-type='method'><a href="module-Accounts.html#~sendPasswordResetEmail">sendPasswordResetEmail</a></li><li data-type='method'><a href="module-Accounts.html#~setupAccount">setupAccount</a></li><li data-type='method'><a href="module-Accounts.html#~status">status</a></li></ul></li><li><a href="module-Awards.html">Awards</a><ul class='methods'><li data-type='method'><a href="module-Awards.html#~fetchAwardsForUser">fetchAwardsForUser</a></li><li data-type='method'><a href="module-Awards.html#~fetchCertificate">fetchCertificate</a></li><li data-type='method'><a href="module-Awards.html#~getAwardDataForGuidedContent">getAwardDataForGuidedContent</a></li></ul></li><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#.getRecentForTab">getRecentForTab</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-Forums.html">Forums</a><ul class='methods'><li data-type='method'><a href="module-Forums.html#~createForumCategory">createForumCategory</a></li><li data-type='method'><a href="module-Forums.html#~createPost">createPost</a></li><li data-type='method'><a href="module-Forums.html#~createThread">createThread</a></li><li data-type='method'><a href="module-Forums.html#~deletePost">deletePost</a></li><li data-type='method'><a href="module-Forums.html#~deleteThread">deleteThread</a></li><li data-type='method'><a href="module-Forums.html#~fetchCommunityGuidelines">fetchCommunityGuidelines</a></li><li data-type='method'><a href="module-Forums.html#~fetchFollowedThreads">fetchFollowedThreads</a></li><li data-type='method'><a href="module-Forums.html#~fetchForumCategories">fetchForumCategories</a></li><li data-type='method'><a href="module-Forums.html#~fetchLatestThreads">fetchLatestThreads</a></li><li data-type='method'><a href="module-Forums.html#~fetchPosts">fetchPosts</a></li><li data-type='method'><a href="module-Forums.html#~fetchThreads">fetchThreads</a></li><li data-type='method'><a href="module-Forums.html#~followThread">followThread</a></li><li data-type='method'><a href="module-Forums.html#~lockThread">lockThread</a></li><li data-type='method'><a href="module-Forums.html#~pinThread">pinThread</a></li><li data-type='method'><a href="module-Forums.html#~unfollowThread">unfollowThread</a></li><li data-type='method'><a href="module-Forums.html#~unlockThread">unlockThread</a></li><li data-type='method'><a href="module-Forums.html#~unpinThread">unpinThread</a></li><li data-type='method'><a href="module-Forums.html#~updateForumCategory">updateForumCategory</a></li><li data-type='method'><a href="module-Forums.html#~updateThread">updateThread</a></li></ul></li><li></li><li></li><li><a href="module-GuidedCourses.html">GuidedCourses</a></li><li><a href="module-Interests.html">Interests</a><ul class='methods'><li data-type='method'><a href="module-Interests.html#.fetchInterests">fetchInterests</a></li><li data-type='method'><a href="module-Interests.html#.fetchUninterests">fetchUninterests</a></li><li data-type='method'><a href="module-Interests.html#.markContentAsInterested">markContentAsInterested</a></li><li data-type='method'><a href="module-Interests.html#.markContentAsNotInterested">markContentAsNotInterested</a></li><li data-type='method'><a href="module-Interests.html#.removeContentAsInterested">removeContentAsInterested</a></li><li data-type='method'><a href="module-Interests.html#.removeContentAsNotInterested">removeContentAsNotInterested</a></li></ul></li><li><a href="module-Payments.html">Payments</a><ul class='methods'><li data-type='method'><a href="module-Payments.html#~fetchCustomerPayments">fetchCustomerPayments</a></li></ul></li><li><a href="module-Permissions.html">Permissions</a><ul class='methods'><li data-type='method'><a href="module-Permissions.html#.fetchUserPermissions">fetchUserPermissions</a></li><li data-type='method'><a href="module-Permissions.html#.reset">reset</a></li></ul></li><li><a href="module-Playlists.html">Playlists</a><ul class='methods'><li data-type='method'><a href="module-Playlists.html#.addItemToPlaylist">addItemToPlaylist</a></li><li data-type='method'><a href="module-Playlists.html#.createPlaylist">createPlaylist</a></li><li data-type='method'><a href="module-Playlists.html#.deletePlaylist">deletePlaylist</a></li><li data-type='method'><a href="module-Playlists.html#.duplicatePlaylist">duplicatePlaylist</a></li><li data-type='method'><a href="module-Playlists.html#.fetchPlaylist">fetchPlaylist</a></li><li data-type='method'><a href="module-Playlists.html#.fetchPlaylistItems">fetchPlaylistItems</a></li><li data-type='method'><a href="module-Playlists.html#.fetchUserPlaylists">fetchUserPlaylists</a></li><li data-type='method'><a href="module-Playlists.html#.togglePlaylistPrivate">togglePlaylistPrivate</a></li><li data-type='method'><a href="module-Playlists.html#.undeletePlaylist">undeletePlaylist</a></li><li data-type='method'><a href="module-Playlists.html#.updatePlaylist">updatePlaylist</a></li><li data-type='method'><a href="module-Playlists.html#~deleteItemsFromPlaylist">deleteItemsFromPlaylist</a></li><li data-type='method'><a href="module-Playlists.html#~likePlaylist">likePlaylist</a></li><li data-type='method'><a href="module-Playlists.html#~reportPlaylist">reportPlaylist</a></li><li data-type='method'><a href="module-Playlists.html#~restoreItemFromPlaylist">restoreItemFromPlaylist</a></li><li data-type='method'><a href="module-Playlists.html#~unlikePlaylist">unlikePlaylist</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#.assignModeratorToComment">assignModeratorToComment</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.closeComment">closeComment</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.createComment">createComment</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.deleteComment">deleteComment</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.editComment">editComment</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#.fetchComment">fetchComment</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#.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#.fetchRecentUserActivities">fetchRecentUserActivities</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#.fetchUserPracticeNotes">fetchUserPracticeNotes</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.likeComment">likeComment</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.openComment">openComment</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.postContentComplete">postContentComplete</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.postContentReset">postContentReset</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.postContentRestore">postContentRestore</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.postContentStart">postContentStart</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.replyToComment">replyToComment</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.reportComment">reportComment</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.restoreComment">restoreComment</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#.unassignModeratorToComment">unassignModeratorToComment</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.unlikeComment">unlikeComment</a></li><li data-type='method'><a href="module-Railcontent-Services.html#~fetchLastInteractedChild">fetchLastInteractedChild</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#.fetchLessonsFeaturingThisContent">fetchLessonsFeaturingThisContent</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#.fetchOtherSongVersions">fetchOtherSongVersions</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#.fetchRelatedLessons">fetchRelatedLessons</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchRelatedRecommendedContent">fetchRelatedRecommendedContent</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#.fetchSiblingContent">fetchSiblingContent</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#~fetchRelatedByLicense">fetchRelatedByLicense</a></li><li data-type='method'><a href="module-Sanity-Services.html#~getQueryFromPage">getQueryFromPage</a></li></ul></li><li><a href="module-Sessions.html">Sessions</a><ul class='methods'><li data-type='method'><a href="module-Sessions.html#.login">login</a></li><li data-type='method'><a href="module-Sessions.html#.logout">logout</a></li></ul></li><li><a href="module-UserActivity.html">UserActivity</a><ul class='methods'><li data-type='method'><a href="module-UserActivity.html#.calculateLongestStreaks">calculateLongestStreaks</a></li><li data-type='method'><a href="module-UserActivity.html#.createPracticeNotes">createPracticeNotes</a></li><li data-type='method'><a href="module-UserActivity.html#.deletePracticeSession">deletePracticeSession</a></li><li data-type='method'><a href="module-UserActivity.html#.deleteUserActivity">deleteUserActivity</a></li><li data-type='method'><a href="module-UserActivity.html#.getPracticeNotes">getPracticeNotes</a></li><li data-type='method'><a href="module-UserActivity.html#.getPracticeSessions">getPracticeSessions</a></li><li data-type='method'><a href="module-UserActivity.html#.getProgressRows">getProgressRows</a></li><li data-type='method'><a href="module-UserActivity.html#.getRecentActivity">getRecentActivity</a></li><li data-type='method'><a href="module-UserActivity.html#.getUserMonthlyStats">getUserMonthlyStats</a></li><li data-type='method'><a href="module-UserActivity.html#.getUserWeeklyStats">getUserWeeklyStats</a></li><li data-type='method'><a href="module-UserActivity.html#.pinProgressRow">pinProgressRow</a></li><li data-type='method'><a href="module-UserActivity.html#.recordUserActivity">recordUserActivity</a></li><li data-type='method'><a href="module-UserActivity.html#.recordUserPractice">recordUserPractice</a></li><li data-type='method'><a href="module-UserActivity.html#.removeUserPractice">removeUserPractice</a></li><li data-type='method'><a href="module-UserActivity.html#.restorePracticeSession">restorePracticeSession</a></li><li data-type='method'><a href="module-UserActivity.html#.restoreUserActivity">restoreUserActivity</a></li><li data-type='method'><a href="module-UserActivity.html#.restoreUserPractice">restoreUserPractice</a></li><li data-type='method'><a href="module-UserActivity.html#.unpinProgressRow">unpinProgressRow</a></li><li data-type='method'><a href="module-UserActivity.html#.updatePracticeNotes">updatePracticeNotes</a></li><li data-type='method'><a href="module-UserActivity.html#.updateUserPractice">updateUserPractice</a></li></ul></li><li><a href="module-UserChat.html">UserChat</a><ul class='methods'><li data-type='method'><a href="module-UserChat.html#.fetchChatSettings">fetchChatSettings</a></li></ul></li><li><a href="module-UserManagement.html">UserManagement</a><ul class='methods'><li data-type='method'><a href="module-UserManagement.html#.blockUser">blockUser</a></li><li data-type='method'><a href="module-UserManagement.html#.blockedUsers">blockedUsers</a></li><li data-type='method'><a href="module-UserManagement.html#.deletePicture">deletePicture</a></li><li data-type='method'><a href="module-UserManagement.html#.getUserData">getUserData</a></li><li data-type='method'><a href="module-UserManagement.html#.isDisplayNameAvailable">isDisplayNameAvailable</a></li><li data-type='method'><a href="module-UserManagement.html#.unblockUser">unblockUser</a></li><li data-type='method'><a href="module-UserManagement.html#.updateDisplayName">updateDisplayName</a></li><li data-type='method'><a href="module-UserManagement.html#.uploadPicture">uploadPicture</a></li><li data-type='method'><a href="module-UserManagement.html#.uploadPictureFromS3">uploadPictureFromS3</a></li></ul></li><li><a href="module-UserMemberships.html">UserMemberships</a><ul class='methods'><li data-type='method'><a href="module-UserMemberships.html#.fetchMemberships">fetchMemberships</a></li><li data-type='method'><a href="module-UserMemberships.html#.fetchRechargeTokens">fetchRechargeTokens</a></li><li data-type='method'><a href="module-UserMemberships.html#.upgradeSubscription">upgradeSubscription</a></li></ul></li><li><a href="module-UserNotifications.html">UserNotifications</a><ul class='methods'><li data-type='method'><a href="module-UserNotifications.html#.deleteNotification">deleteNotification</a></li><li data-type='method'><a href="module-UserNotifications.html#.fetchLiveEventPollingState">fetchLiveEventPollingState</a></li><li data-type='method'><a href="module-UserNotifications.html#.fetchNotificationSettings">fetchNotificationSettings</a></li><li data-type='method'><a href="module-UserNotifications.html#.fetchNotifications">fetchNotifications</a></li><li data-type='method'><a href="module-UserNotifications.html#.fetchUnreadCount">fetchUnreadCount</a></li><li data-type='method'><a href="module-UserNotifications.html#.markAllNotificationsAsRead">markAllNotificationsAsRead</a></li><li data-type='method'><a href="module-UserNotifications.html#.markNotificationAsRead">markNotificationAsRead</a></li><li data-type='method'><a href="module-UserNotifications.html#.markNotificationAsUnread">markNotificationAsUnread</a></li><li data-type='method'><a href="module-UserNotifications.html#.pauseLiveEventPolling">pauseLiveEventPolling</a></li><li data-type='method'><a href="module-UserNotifications.html#.restoreNotification">restoreNotification</a></li><li data-type='method'><a href="module-UserNotifications.html#.startLiveEventPolling">startLiveEventPolling</a></li><li data-type='method'><a href="module-UserNotifications.html#.updateNotificationSetting">updateNotificationSetting</a></li></ul></li><li><a href="module-UserProfile.html">UserProfile</a><ul class='methods'><li data-type='method'><a href="module-UserProfile.html#.deleteProfilePicture">deleteProfilePicture</a></li><li data-type='method'><a href="module-UserProfile.html#.otherStats">otherStats</a></li></ul></li></ul><h3>Namespaces</h3><ul><li><a href="ContentOrganization.html">ContentOrganization</a></li><li><a href="Forums.html">Forums</a></li><li><a href="Gamification.html">Gamification</a></li><li><a href="UserManagementSystem.html">UserManagementSystem</a></li></ul><h3><a href="global.html">Global</a></h3>
33
33
 
34
34
  </nav>
35
35
 
@@ -50,6 +50,8 @@
50
50
  */
51
51
  import {
52
52
  artistOrInstructorName,
53
+ instructorField,
54
+ chapterField,
53
55
  assignmentsField,
54
56
  descriptionField,
55
57
  resourcesField,
@@ -61,30 +63,31 @@ import {
61
63
  showsTypes,
62
64
  getNewReleasesTypes,
63
65
  coachLessonsTypes,
66
+ getFieldsForContentTypeWithFilteredChildren,
64
67
  getChildFieldsForContentType,
65
68
  SONG_TYPES,
69
+ recentTypes
66
70
  } from '../contentTypeConfig.js'
67
- import { fetchSimilarItems } from './recommendations.js'
71
+ import {fetchSimilarItems, recommendations} from './recommendations.js'
68
72
  import { processMetadata, typeWithSortOrder } from '../contentMetaData.js'
69
73
 
70
74
  import { globalConfig } from './config.js'
71
75
 
72
76
  import {
73
- fetchCompletedChallenges,
74
- fetchOwnedChallenges,
75
77
  fetchNextContentDataForParent,
76
78
  fetchHandler,
77
79
  } from './railcontent.js'
78
80
  import { arrayToStringRepresentation, FilterBuilder } from '../filterBuilder.js'
79
81
  import { fetchUserPermissions } from './user/permissions.js'
80
82
  import { getAllCompleted, getAllStarted, getAllStartedOrCompleted } from './contentProgress.js'
83
+ import {fetchRecentActivitiesActiveTabs} from "./userActivity.js";
81
84
 
82
85
  /**
83
86
  * Exported functions that are excluded from index generation.
84
87
  *
85
88
  * @type {string[]}
86
89
  */
87
- const excludeFromGeneratedIndex = ['handleCustomFetchAll', 'fetchRelatedByLicense']
90
+ const excludeFromGeneratedIndex = ['fetchRelatedByLicense']
88
91
 
89
92
  /**
90
93
  * Fetch a song by its document ID from Sanity.
@@ -120,18 +123,19 @@ export async function fetchSongById(documentId) {
120
123
  * @returns {Promise&lt;Object|null>}
121
124
  */
122
125
  export async function fetchLeaving(brand, { pageNumber = 1, contentPerPage = 20 } = {}) {
123
- const nextQuarter = getNextAndPreviousQuarterDates()['next']
124
- const filterString = `brand == '${brand}' &amp;&amp; quarter_removed == '${nextQuarter}'`
126
+ const today = new Date()
127
+ const isoDateOnly = getDateOnly(today)
128
+ const filterString = `brand == '${brand}' &amp;&amp; quarter_removed > '${isoDateOnly}'`
125
129
  const startEndOrder = getQueryFromPage(pageNumber, contentPerPage)
126
130
  const sortOrder = {
127
- sortOrder: 'published_on desc, id desc',
131
+ sortOrder: 'quarter_removed asc, published_on desc, id desc',
128
132
  start: startEndOrder['start'],
129
133
  end: startEndOrder['end'],
130
134
  }
131
135
  const query = await buildQuery(
132
136
  filterString,
133
137
  { pullFutureContent: false, availableContentStatuses: ['published'] },
134
- getFieldsForContentType(),
138
+ getFieldsForContentType('leaving'),
135
139
  sortOrder
136
140
  )
137
141
  return fetchSanity(query, true)
@@ -146,11 +150,12 @@ export async function fetchLeaving(brand, { pageNumber = 1, contentPerPage = 20
146
150
  * @returns {Promise&lt;Object|null>}
147
151
  */
148
152
  export async function fetchReturning(brand, { pageNumber = 1, contentPerPage = 20 } = {}) {
149
- const nextQuarter = getNextAndPreviousQuarterDates()['next']
150
- const filterString = `brand == '${brand}' &amp;&amp; quarter_published == '${nextQuarter}'`
153
+ const today = new Date()
154
+ const isoDateOnly = getDateOnly(today)
155
+ const filterString = `brand == '${brand}' &amp;&amp; quarter_published >= '${isoDateOnly}'`
151
156
  const startEndOrder = getQueryFromPage(pageNumber, contentPerPage)
152
157
  const sortOrder = {
153
- sortOrder: 'published_on desc, id desc',
158
+ sortOrder: 'quarter_published asc, published_on desc, id desc',
154
159
  start: startEndOrder['start'],
155
160
  end: startEndOrder['end'],
156
161
  }
@@ -203,41 +208,6 @@ function getQueryFromPage(pageNumber, contentPerPage) {
203
208
  return result
204
209
  }
205
210
 
206
- /**
207
- * returns array of next and previous quarter dates as strings
208
- *
209
- * @returns {string[]}
210
- */
211
- function getNextAndPreviousQuarterDates() {
212
- const january = 1
213
- const april = 4
214
- const july = 7
215
- const october = 10
216
- const month = new Date().getMonth()
217
- let year = new Date().getFullYear()
218
- let nextQuarter = ''
219
- let prevQuarter = ''
220
- if (month &lt; april) {
221
- nextQuarter = `${year}-0${april}-01`
222
- prevQuarter = `${year}-0${january}-01`
223
- } else if (month &lt; july) {
224
- nextQuarter = `${year}-0${july}-01`
225
- prevQuarter = `${year}-0${april}-01`
226
- } else if (month &lt; october) {
227
- nextQuarter = `${year}-${october}-01`
228
- prevQuarter = `${year}-0${july}-01`
229
- } else {
230
- prevQuarter = `${year}-${october}-01`
231
- year++
232
- nextQuarter = `${year}-0${january}-01`
233
- }
234
-
235
- let result = []
236
- result['next'] = nextQuarter
237
- result['previous'] = prevQuarter
238
- return result
239
- }
240
-
241
211
  /**
242
212
  * Fetch all artists with lessons available for a specific brand.
243
213
  *
@@ -394,8 +364,8 @@ export async function fetchNewReleases(
394
364
  const start = (page - 1) * limit
395
365
  const end = start + limit
396
366
  const sortOrder = getSortOrder(sort, brand)
397
- const nextQuarter = getNextAndPreviousQuarterDates()['next']
398
- const filter = `_type in ${typesString} &amp;&amp; brand == '${brand}' &amp;&amp; show_in_new_feed == true &amp;&amp; (!defined(quarter_published) || quarter_published != '${nextQuarter}')`
367
+ const now = getDateOnly()
368
+ const filter = `_type in ${typesString} &amp;&amp; brand == '${brand}' &amp;&amp; (status == 'published' &amp;&amp; show_in_new_feed == true &amp;&amp; published_on &lt;= '${now}')`
399
369
  const fields = `
400
370
  "id": railcontent_id,
401
371
  title,
@@ -411,12 +381,7 @@ export async function fetchNewReleases(
411
381
  web_url_path,
412
382
  "permission_id": permission[]->railcontent_id,
413
383
  `
414
- const filterParams = { allowsPullSongsContent: false }
415
- const query = await buildQuery(filter, filterParams, fields, {
416
- sortOrder: sortOrder,
417
- start,
418
- end: end,
419
- })
384
+ const query = buildRawQuery(filter, fields, {sortOrder: sortOrder, start, end: end})
420
385
  return fetchSanity(query, true)
421
386
  }
422
387
 
@@ -435,8 +400,6 @@ export async function fetchNewReleases(
435
400
  * .catch(error => console.error(error));
436
401
  */
437
402
  export async function fetchUpcomingEvents(brand, { page = 1, limit = 10 } = {}) {
438
- const liveTypes = getUpcomingEventsTypes(brand)
439
- const typesString = arrayToStringRepresentation(liveTypes)
440
403
  const now = getSanityDate(new Date())
441
404
  const start = (page - 1) * limit
442
405
  const end = start + limit
@@ -454,9 +417,11 @@ export async function fetchUpcomingEvents(brand, { page = 1, limit = 10 } = {})
454
417
  "type": _type,
455
418
  web_url_path,
456
419
  "permission_id": permission[]->railcontent_id,
420
+ live_event_start_time,
421
+ live_event_end_time,
457
422
  "isLive": live_event_start_time &lt;= '${now}' &amp;&amp; live_event_end_time >= '${now}'`
458
423
  const query = buildRawQuery(
459
- `_type in ${typesString} &amp;&amp; brand == '${brand}' &amp;&amp; published_on > '${now}' &amp;&amp; status == 'scheduled'`,
424
+ `defined(live_event_start_time) &amp;&amp; (!defined(live_event_end_time) || live_event_end_time >= '${now}' ) &amp;&amp; brand == '${brand}' &amp;&amp; published_on > '${now}' &amp;&amp; status == 'scheduled'`,
460
425
  fields,
461
426
  {
462
427
  sortOrder: 'published_on asc',
@@ -490,7 +455,7 @@ export async function fetchScheduledReleases(brand, { page = 1, limit = 10 }) {
490
455
  const now = getSanityDate(new Date())
491
456
  const start = (page - 1) * limit
492
457
  const end = start + limit
493
- const query = `*[_type in [${typesString}] &amp;&amp; brand == '${brand}' &amp;&amp; status in ['published','scheduled'] &amp;&amp; published_on > '${now}']{
458
+ const query = `*[_type in [${typesString}] &amp;&amp; brand == '${brand}' &amp;&amp; status in ['published','scheduled'] &amp;&amp; (!defined(live_event_end_time) || live_event_end_time &lt; '${now}' ) &amp;&amp; published_on > '${now}']{
494
459
  "id": railcontent_id,
495
460
  title,
496
461
  "image": thumbnail.asset->url,
@@ -521,12 +486,12 @@ export async function fetchScheduledReleases(brand, { page = 1, limit = 10 }) {
521
486
  * .catch(error => console.error(error));
522
487
  */
523
488
  export async function fetchByRailContentId(id, contentType) {
524
- const fields = getFieldsForContentType(contentType)
525
- const childFields = getChildFieldsForContentType(contentType)
489
+ const fields = await getFieldsForContentTypeWithFilteredChildren(contentType)
490
+ const lessonFields = getChildFieldsForContentType(contentType)
526
491
  const childrenFilter = await new FilterBuilder(``, { isChildrenFilter: true }).buildFilter()
527
492
  const entityFieldsString = ` ${fields}
528
493
  'child_count': coalesce(count(child[${childrenFilter}]->), 0) ,
529
- "lessons": child[${childrenFilter}]->{${childFields}},
494
+ "lessons": child[${childrenFilter}]->{${lessonFields}},
530
495
  'length_in_seconds': coalesce(
531
496
  math::sum(
532
497
  select(
@@ -550,7 +515,7 @@ export async function fetchByRailContentId(id, contentType) {
550
515
  /**
551
516
  * Fetch content by an array of Railcontent IDs.
552
517
  *
553
- * @param {Array&lt;string>} ids - The array of Railcontent IDs of the content to fetch.
518
+ * @param {Array&lt;string|number>} ids - The array of Railcontent IDs of the content to fetch.
554
519
  * @param {string} [contentType] - The content type the IDs to add needed fields to the response.
555
520
  * @returns {Promise&lt;Array&lt;Object>|null>} - A promise that resolves to an array of content objects or null if not found.
556
521
  *
@@ -559,19 +524,40 @@ export async function fetchByRailContentId(id, contentType) {
559
524
  * .then(contents => console.log(contents))
560
525
  * .catch(error => console.error(error));
561
526
  */
562
- export async function fetchByRailContentIds(ids, contentType = undefined, brand= undefined) {
563
- if (!ids) {
527
+ export async function fetchByRailContentIds(ids, contentType = undefined, brand = undefined, includePermissionsAndStatusFilter = false) {
528
+ if (!ids?.length) {
564
529
  return []
565
530
  }
531
+ ids = [...new Set(ids.filter(item => item !== null &amp;&amp; item !== undefined))];
566
532
  const idsString = ids.join(',')
567
533
  const brandFilter = brand ? ` &amp;&amp; brand == "${brand}"` : ''
534
+ const lessonCountFilter = await new FilterBuilder(`_id in ^.child[]._ref`, {pullFutureContent: true}).buildFilter()
535
+ const fields = await getFieldsForContentTypeWithFilteredChildren(contentType, true)
536
+ const baseFilter = `railcontent_id in [${idsString}]${brandFilter}`
537
+ const finalFilter = includePermissionsAndStatusFilter ? await new FilterBuilder(baseFilter).buildFilter() : baseFilter
568
538
  const query = `*[
569
- railcontent_id in [${idsString}]${brandFilter}
539
+ ${finalFilter}
570
540
  ]{
571
- ${getFieldsForContentType(contentType)}
541
+ ${fields}
542
+ 'lesson_count': coalesce(count(*[${lessonCountFilter}]), 0),
543
+ live_event_start_time,
544
+ live_event_end_time,
572
545
  }`
573
-
574
- const results = await fetchSanity(query, true)
546
+ const customPostProcess = (results) => {
547
+ const now = getSanityDate(new Date(), false);
548
+ const liveProcess = (result) => {
549
+ if (result.live_event_start_time &amp;&amp; result.live_event_end_time) {
550
+ result.isLive =
551
+ result.live_event_start_time &lt;= now &amp;&amp;
552
+ result.live_event_end_time >= now;
553
+ } else {
554
+ result.isLive = false;
555
+ }
556
+ return result;
557
+ };
558
+ return results.map(liveProcess);
559
+ }
560
+ const results = await fetchSanity(query, true, { customPostProcess: customPostProcess })
575
561
 
576
562
  const sortFuction = function compare(a, b) {
577
563
  const indexA = ids.indexOf(a['id'])
@@ -582,11 +568,35 @@ export async function fetchByRailContentIds(ids, contentType = undefined, brand=
582
568
  }
583
569
 
584
570
  // Sort results to match the order of the input IDs
585
- const sortedResults = results.sort(sortFuction)
571
+ const sortedResults = results?.sort(sortFuction) ?? null
586
572
 
587
573
  return sortedResults
588
574
  }
589
575
 
576
+ export async function fetchContentRows(brand, pageName, contentRowSlug)
577
+ {
578
+ if (pageName === 'lessons') pageName = 'lesson'
579
+ if (pageName === 'songs') pageName = 'song'
580
+ const rowString = contentRowSlug ? ` &amp;&amp; slug.current == "${contentRowSlug.toLowerCase()}"` : ''
581
+ const lessonCountFilter = await new FilterBuilder(`_id in ^.child[]._ref`, {pullFutureContent: true}).buildFilter()
582
+ const childFilter = await new FilterBuilder('', {isChildrenFilter: true}).buildFilter()
583
+ const query = `*[_type == 'recommended-content-row' &amp;&amp; brand == '${brand}' &amp;&amp; type == '${pageName}'${rowString}]{
584
+ brand,
585
+ name,
586
+ 'slug': slug.current,
587
+ 'content': content[${childFilter}]->{
588
+ 'children': child[${childFilter}]->{ 'id': railcontent_id,
589
+ 'type': _type, brand, 'thumbnail': thumbnail.asset->url,
590
+ 'children': child[${childFilter}]->{'id': railcontent_id}, },
591
+ ${getFieldsForContentType('tab-data')}
592
+ 'lesson_count': coalesce(count(*[${lessonCountFilter}]), 0),
593
+ },
594
+ }`
595
+ return fetchSanity(query, true)
596
+ }
597
+
598
+
599
+
590
600
  /**
591
601
  * Fetch all content for a specific brand and type with pagination, search, and grouping options.
592
602
  * @param {string} brand - The brand for which to fetch content.
@@ -635,21 +645,6 @@ export async function fetchAll(
635
645
  progress = 'all',
636
646
  } = {}
637
647
  ) {
638
- let customResults = await handleCustomFetchAll(brand, type, {
639
- page,
640
- limit,
641
- searchTerm,
642
- sort,
643
- includedFields,
644
- groupBy,
645
- progressIds,
646
- useDefaultFields,
647
- customFields,
648
- progress,
649
- })
650
- if (customResults) {
651
- return customResults
652
- }
653
648
  let config = contentTypeConfig[type] ?? {}
654
649
  let additionalFields = config?.fields ?? []
655
650
  let isGroupByOneToOne = (groupBy ? config?.relationships?.[groupBy]?.isOneToOne : false) ?? false
@@ -672,9 +667,7 @@ export async function fetchAll(
672
667
  } else {
673
668
  typeFilter = type
674
669
  ? `&amp;&amp; _type == '${type}'`
675
- : progress === 'in progress' || progress === 'completed'
676
- ? " &amp;&amp; (_type != 'challenge-part' &amp;&amp; _type != 'challenge')"
677
- : ''
670
+ : ''
678
671
  }
679
672
 
680
673
  // Construct the search filter
@@ -772,152 +765,6 @@ export async function fetchAll(
772
765
  return fetchSanity(query, true)
773
766
  }
774
767
 
775
- /**
776
- * Fetch all content that requires custom handling or a distinct external call
777
- * @param {string} brand - The brand for which to fetch content.
778
- * @param {string} type - The content type to fetch (e.g., 'song', 'artist').
779
- * @param {Object} params - Parameters for pagination, filtering, sorting, and grouping.
780
- * @param {number} [params.page=1] - The page number for pagination.
781
- * @param {number} [params.limit=10] - The number of items per page.
782
- * @param {string} [params.searchTerm=""] - The search term to filter content by title or artist.
783
- * @param {string} [params.sort="-published_on"] - The field to sort the content by.
784
- * @param {Array&lt;string>} [params.includedFields=[]] - The fields to include in the query.
785
- * @param {string} [params.groupBy=""] - The field to group the results by (e.g., 'artist', 'genre').
786
- * @param {Array&lt;string>} [params.progressIds=undefined] - An array of railcontent IDs to filter the results by. Used for filtering by progress.
787
- * @param {boolean} [params.useDefaultFields=true] - use the default sanity fields for content Type
788
- * @param {Array&lt;string>} [params.customFields=[]] - An array of sanity fields to include in the request
789
- * @param {string} [params.progress="all"] - An string representing which progress filter to use ("all", "in progress", "complete", "not started").
790
- * @returns {Promise&lt;Object|null>} - The fetched content data or null if not found.
791
- */
792
- async function handleCustomFetchAll(
793
- brand,
794
- type,
795
- {
796
- page = 1,
797
- limit = 10,
798
- searchTerm = '',
799
- sort = '-published_on',
800
- includedFields = [],
801
- groupBy = '',
802
- progressIds = undefined,
803
- useDefaultFields = true,
804
- customFields = [],
805
- progress = 'all',
806
- } = {}
807
- ) {
808
- if (type === 'challenge') {
809
- if (groupBy === 'completed') {
810
- const completedIds = await fetchCompletedChallenges(brand, page, limit)
811
- return fetchAll(brand, type, {
812
- page,
813
- limit,
814
- searchTerm,
815
- sort,
816
- includedFields,
817
- groupBy: '',
818
- progressIds: completedIds,
819
- useDefaultFields,
820
- customFields,
821
- progress,
822
- })
823
- } else if (groupBy === 'owned') {
824
- const ownedIds = await fetchOwnedChallenges(brand, page, limit)
825
- return fetchAll(brand, type, {
826
- page,
827
- limit,
828
- searchTerm,
829
- sort,
830
- includedFields,
831
- groupBy: '',
832
- progressIds: ownedIds,
833
- useDefaultFields,
834
- customFields,
835
- progress,
836
- })
837
- } else if (groupBy === 'difficulty_string') {
838
- return fetchChallengesByDifficulty(
839
- brand,
840
- type,
841
- page,
842
- limit,
843
- searchTerm,
844
- sort,
845
- includedFields,
846
- groupBy,
847
- progressIds,
848
- useDefaultFields,
849
- customFields,
850
- progress
851
- )
852
- }
853
- }
854
- return null
855
- }
856
-
857
- async function fetchChallengesByDifficulty(
858
- brand,
859
- type,
860
- page,
861
- limit,
862
- searchTerm,
863
- sort,
864
- includedFields,
865
- groupBy,
866
- progressIds,
867
- useDefaultFields,
868
- customFields,
869
- progress
870
- ) {
871
- let config = contentTypeConfig['challenge'] ?? {}
872
- let additionalFields = config?.fields ?? []
873
-
874
- // Construct the search filter
875
- const searchFilter = searchTerm
876
- ? groupBy !== ''
877
- ? `&amp;&amp; (^.name match "${searchTerm}*" || title match "${searchTerm}*")`
878
- : `&amp;&amp; (artist->name match "${searchTerm}*" || instructor[]->name match "${searchTerm}*" || title match "${searchTerm}*" || name match "${searchTerm}*")`
879
- : ''
880
-
881
- // Construct the included fields filter, replacing 'difficulty' with 'difficulty_string'
882
- const includedFieldsFilter = includedFields.length > 0 ? filtersToGroq(includedFields) : ''
883
-
884
- // limits the results to supplied progressIds for started &amp; completed filters
885
- const progressFilter = await getProgressFilter(progress, progressIds)
886
-
887
- let fields = useDefaultFields
888
- ? customFields.concat(DEFAULT_FIELDS, additionalFields)
889
- : customFields
890
- let fieldsString = fields.join(',')
891
-
892
- const lessonsFilter = `_type == 'challenge' &amp;&amp; brand == '${brand}' &amp;&amp; ^.name == difficulty_string ${searchFilter} ${includedFieldsFilter} ${progressFilter}`
893
- const lessonsFilterWithRestrictions = await new FilterBuilder(lessonsFilter).buildFilter()
894
-
895
- const query = `{
896
- "entity": [
897
- {"name": "All"},
898
- {"name": "Novice"},
899
- {"name": "Beginner"},
900
- {"name": "Intermediate"},
901
- {"name": "Advanced"},
902
- {"name": "Expert"}]
903
- {
904
- 'id': 0,
905
- name,
906
- 'all_lessons_count': count(*[${lessonsFilterWithRestrictions}]._id),
907
- 'lessons': *[${lessonsFilterWithRestrictions}]{
908
- ${fieldsString},
909
- name
910
- }[0...20]
911
- },
912
- "total": 0
913
- }`
914
- let data = await fetchSanity(query, true)
915
- data.entity = data.entity.filter(function (difficulty) {
916
- return difficulty.lessons.length > 0
917
- })
918
- return data
919
- }
920
-
921
768
  async function getProgressFilter(progress, progressIds) {
922
769
  switch (progress) {
923
770
  case 'all':
@@ -935,11 +782,11 @@ async function getProgressFilter(progress, progressIds) {
935
782
  return `&amp;&amp; !(railcontent_id in [${ids.join(',')}])`
936
783
  }
937
784
  case 'recent': {
938
- const ids = await getAllStartedOrCompleted()
785
+ const ids = progressIds !== undefined ? progressIds : await getAllStartedOrCompleted()
939
786
  return `&amp;&amp; (railcontent_id in [${ids.join(',')}])`
940
787
  }
941
788
  case 'incomplete': {
942
- const ids = await getAllStarted()
789
+ const ids = progressIds !== undefined ? progressIds :await getAllStarted()
943
790
  return `&amp;&amp; railcontent_id in [${ids.join(',')}]`
944
791
  }
945
792
  default:
@@ -950,11 +797,11 @@ async function getProgressFilter(progress, progressIds) {
950
797
  export function getSortOrder(sort = '-published_on', brand, groupBy) {
951
798
  // Determine the sort order
952
799
  let sortOrder = ''
953
- const isDesc = sort.startsWith('-')
800
+ let isDesc = sort.startsWith('-')
954
801
  sort = isDesc ? sort.substring(1) : sort
955
802
  switch (sort) {
956
803
  case 'slug':
957
- sortOrder = groupBy ? 'name' : 'title'
804
+ sortOrder = groupBy ? 'name' : '!defined(title), lower(title)'
958
805
  break
959
806
  case 'name':
960
807
  sortOrder = sort
@@ -966,6 +813,10 @@ export function getSortOrder(sort = '-published_on', brand, groupBy) {
966
813
  sortOrder = isDesc ? 'coalesce(popularity, -1)' : 'popularity'
967
814
  }
968
815
  break
816
+ case 'recommended':
817
+ sortOrder = 'published_on'
818
+ isDesc = true
819
+ break
969
820
  case 'published_on':
970
821
  default:
971
822
  sortOrder = 'published_on'
@@ -1290,6 +1141,7 @@ export async function jumpToContinueContent(railcontentId) {
1290
1141
  /**
1291
1142
  * Fetch the page data for a specific lesson by Railcontent ID.
1292
1143
  * @param {string} railContentId - The Railcontent ID of the current lesson.
1144
+ * @parent {boolean} addParent - Whether to include parent content data in the response.
1293
1145
  * @returns {Promise&lt;Object|null>} - The fetched page data or null if found.
1294
1146
  *
1295
1147
  * @example
@@ -1297,80 +1149,61 @@ export async function jumpToContinueContent(railcontentId) {
1297
1149
  * .then(data => console.log(data))
1298
1150
  * .catch(error => console.error(error));
1299
1151
  */
1300
- export async function fetchLessonContent(railContentId) {
1152
+ export async function fetchLessonContent(railContentId, { addParent = false } = {}) {
1301
1153
  const filterParams = { isSingle: true, pullFutureContent: true }
1302
- // Format changes made to the `fields` object may also need to be reflected in Musora-web-platform SanityGateway.php $fields object
1303
- // Currently only for challenges and challenge lessons
1304
- // If you're unsure, message Adrian, or just add them.
1305
- const fields = `title,
1306
- published_on,
1307
- "type":_type,
1308
- "resources": ${resourcesField},
1309
- difficulty,
1310
- difficulty_string,
1311
- brand,
1312
- status,
1313
- soundslice,
1314
- instrumentless,
1315
- railcontent_id,
1316
- "id":railcontent_id,
1317
- slug, artist->,
1318
- "thumbnail":thumbnail.asset->url,
1319
- "url": web_url_path,
1320
- soundslice_slug,
1321
- "description": description[0].children[0].text,
1322
- "chapters": chapter[]{
1323
- chapter_description,
1324
- chapter_timecode,
1325
- "chapter_thumbnail_url": chapter_thumbnail_url.asset->url
1326
- },
1327
- 'artist': { 'name': artist->name, 'thumbnail': artist->thumbnail_url.asset->url},
1328
- "instructors":instructor[]->name,
1329
- "instructor": instructor[]->{
1330
- "id":railcontent_id,
1331
- name,
1332
- short_bio,
1333
- "biography": short_bio[0].children[0].text,
1334
- web_url_path,
1335
- "coach_card_image": coach_card_image.asset->url,
1336
- "coach_profile_image":thumbnail_url.asset->url
1337
- },
1338
- ${assignmentsField}
1339
- video,
1340
- length_in_seconds,
1341
- mp3_no_drums_no_click_url,
1342
- mp3_no_drums_yes_click_url,
1343
- mp3_yes_drums_no_click_url,
1344
- mp3_yes_drums_yes_click_url,
1345
- "permission_id": permission[]->railcontent_id,
1346
- "parent_content_data": parent_content_data[]{
1347
- "id": id,
1348
- "title": *[railcontent_id == ^.id][0].title,
1349
- "web_url_path": *[railcontent_id == ^.id][0].web_url_path,
1350
- "slug":*[railcontent_id == ^.id][0].slug,
1351
- "type": *[railcontent_id == ^.id][0]._type,
1352
- },
1353
- sort,
1354
- xp,
1355
- stbs,ds2stbs, bdsStbs,
1356
- ...select(
1357
- defined(live_event_start_time) &amp;&amp; defined(live_event_end_time) => {
1358
- "live_event_start_time": live_event_start_time,
1359
- "live_event_end_time": live_event_end_time,
1360
- "live_event_youtube_id": live_event_youtube_id,
1361
- "videoId": coalesce(live_event_youtube_id, video.external_id),
1362
- }
1363
- )`
1154
+
1155
+ const parentQuery = addParent
1156
+ ? `"parent_content_data": *[railcontent_id in [...(^.parent_content_data[].id)]]{
1157
+ "id": railcontent_id,
1158
+ title,
1159
+ slug,
1160
+ "type": _type,
1161
+ "logo" : logo_image_url.asset->url,
1162
+ "dark_mode_logo": dark_mode_logo_url.asset->url,
1163
+ "light_mode_logo": light_mode_logo_url.asset->url,
1164
+ "badge": *[references(^._id) &amp;&amp; _type == 'content-award'][0].badge.asset->url,
1165
+ },`
1166
+ : ''
1167
+
1168
+ const fields = `${getFieldsForContentType()}
1169
+ "resources": ${resourcesField},
1170
+ soundslice,
1171
+ instrumentless,
1172
+ soundslice_slug,
1173
+ "description": ${descriptionField},
1174
+ "chapters": ${chapterField},
1175
+ "instructors":instructor[]->name,
1176
+ "instructor": ${instructorField},
1177
+ ${assignmentsField}
1178
+ video,
1179
+ length_in_seconds,
1180
+ mp3_no_drums_no_click_url,
1181
+ mp3_no_drums_yes_click_url,
1182
+ mp3_yes_drums_no_click_url,
1183
+ mp3_yes_drums_yes_click_url,
1184
+ "permission_id": permission[]->railcontent_id,
1185
+ ${parentQuery}
1186
+ ...select(
1187
+ defined(live_event_start_time) => {
1188
+ "live_event_start_time": live_event_start_time,
1189
+ "live_event_end_time": live_event_end_time,
1190
+ "live_event_youtube_id": live_event_youtube_id,
1191
+ "videoId": coalesce(live_event_youtube_id, video.external_id),
1192
+ "live_event_is_global": live_global_event == true
1193
+ }
1194
+ )
1195
+ `
1196
+
1364
1197
  const query = await buildQuery(`railcontent_id == ${railContentId}`, filterParams, fields, {
1365
1198
  isSingle: true,
1366
1199
  })
1367
1200
  const chapterProcess = (result) => {
1368
1201
  const now = getSanityDate(new Date(), false)
1369
- if(result.live_event_start_time &amp;&amp; result.live_event_start_time){
1202
+ if (result.live_event_start_time &amp;&amp; result.live_event_end_time) {
1370
1203
  result.isLive = result.live_event_start_time &lt;= now &amp;&amp; result.live_event_end_time >= now
1371
1204
  }
1372
1205
  const chapters = result.chapters ?? []
1373
- if (chapters.length == 0) return result
1206
+ if (chapters.length === 0) return result
1374
1207
  result.chapters = chapters.map((chapter, index) => ({
1375
1208
  ...chapter,
1376
1209
  chapter_thumbnail_url: `https://musora-web-platform.s3.amazonaws.com/chapters/${result.brand}/Chapter${index + 1}.jpg`,
@@ -1382,15 +1215,23 @@ export async function fetchLessonContent(railContentId) {
1382
1215
  }
1383
1216
 
1384
1217
  /**
1218
+ * Returns a list of recommended content based on the provided railContentId.
1219
+ * If no recommendations found in recsys, falls back to fetching related lessons.
1385
1220
  *
1386
1221
  * @param railContentId
1387
1222
  * @param brand
1388
1223
  * @param count
1389
- * @returns {Promise&lt;Array&lt;Object>|null>}
1224
+ * @returns {Promise&lt;Array&lt;Object>>}
1390
1225
  */
1391
1226
  export async function fetchRelatedRecommendedContent(railContentId, brand, count = 10) {
1392
1227
  const recommendedItems = await fetchSimilarItems(railContentId, brand, count)
1393
- return fetchByRailContentIds(recommendedItems)
1228
+ if (recommendedItems &amp;&amp; recommendedItems.length > 0) {
1229
+ return fetchByRailContentIds(recommendedItems, 'tab-data', brand, true)
1230
+ }
1231
+
1232
+ return await fetchRelatedLessons(railContentId, brand).then((result) =>
1233
+ result.related_lessons?.splice(0, count)
1234
+ )
1394
1235
  }
1395
1236
 
1396
1237
  /**
@@ -1430,7 +1271,8 @@ export async function fetchLessonsFeaturingThisContent(railcontentId, brand, cou
1430
1271
  */
1431
1272
  async function fetchRelatedByLicense(railcontentId, brand, onlyUseSongTypes, count) {
1432
1273
  const typeCheck = `@->_type in [${arrayJoinWithQuotes(SONG_TYPES)}]`
1433
- const typeCheckString = onlyUseSongTypes ? `${typeCheck}` : `!(${typeCheck})`
1274
+ let typeCheckString = `@->brand == '${brand}' &amp;&amp; `
1275
+ typeCheckString += onlyUseSongTypes ? `${typeCheck}` : `!(${typeCheck})`
1434
1276
  const contentFromLicenseFilter = `_type == 'license' &amp;&amp; references(^._id)].content[${typeCheckString} &amp;&amp; @->railcontent_id != ${railcontentId}`
1435
1277
  let filterSongTypesWithSameLicense = await new FilterBuilder(contentFromLicenseFilter, {
1436
1278
  isChildrenFilter: true,
@@ -1447,45 +1289,85 @@ async function fetchRelatedByLicense(railcontentId, brand, onlyUseSongTypes, cou
1447
1289
  "related_by_license" :
1448
1290
  *[${filterSongTypesWithSameLicense}]->{${queryFields}}|order(published_on desc, title asc)[0...${count}],
1449
1291
  }[0...1]`
1450
-
1451
1292
  const results = await fetchSanity(query, false)
1452
- return results['related_by_license'] ?? []
1293
+ return results ? results['related_by_license'] ?? [] : []
1453
1294
  }
1454
1295
 
1455
1296
  /**
1456
- * Fetch related lessons for a specific lesson by RailContent ID and type.
1297
+ * Fetch sibling lessons to a specific lesson
1457
1298
  * @param {string} railContentId - The RailContent ID of the current lesson.
1458
1299
  * @param {string} brand - The current brand.
1459
1300
  * @returns {Promise&lt;Array&lt;Object>|null>} - The fetched related lessons data or null if not found.
1460
1301
  */
1461
- export async function fetchRelatedLessons(railContentId, brand) {
1462
- const filterSameTypeAndSortOrder = await new FilterBuilder(
1463
- `_type==^._type &amp;&amp; _type in ${JSON.stringify(typeWithSortOrder)} &amp;&amp; brand == "${brand}" &amp;&amp; railcontent_id !=${railContentId}`
1464
- ).buildFilter()
1465
- const filterSameType = await new FilterBuilder(
1466
- `_type==^._type &amp;&amp; !(_type in ${JSON.stringify(typeWithSortOrder)}) &amp;&amp; !(defined(parent_type)) &amp;&amp; brand == "${brand}" &amp;&amp; railcontent_id !=${railContentId}`
1467
- ).buildFilter()
1468
- const filterSongSameArtist = await new FilterBuilder(
1469
- `_type=="song" &amp;&amp; _type==^._type &amp;&amp; brand == "${brand}" &amp;&amp; references(^.artist->_id) &amp;&amp; railcontent_id !=${railContentId}`
1302
+ export async function fetchSiblingContent(railContentId, brand= null)
1303
+ {
1304
+ const filterGetParent = await new FilterBuilder(`references(^._id) &amp;&amp; _type == ^.parent_type`, {
1305
+ pullFutureContent: true
1306
+ }).buildFilter()
1307
+ const filterForParentList = await new FilterBuilder(`references(^._id) &amp;&amp; _type == ^.parent_type`, {
1308
+ pullFutureContent: true,
1309
+ isParentFilter: true,
1310
+ }).buildFilter()
1311
+
1312
+ const childrenFilter = await new FilterBuilder(``, { isChildrenFilter: true }).buildFilter()
1313
+
1314
+ const brandString = brand ? ` &amp;&amp; brand == "${brand}"` : ''
1315
+ const queryFields = `_id, "id":railcontent_id, published_on, "instructor": instructor[0]->name, title, "thumbnail":thumbnail.asset->url, length_in_seconds, status, "type": _type, difficulty, difficulty_string, artist->, "permission_id": permission[]->railcontent_id, "genre": genre[]->name, "parent_id": parent_content_data[0].id`
1316
+
1317
+ const query = `*[railcontent_id == ${railContentId}${brandString}]{
1318
+ _type, parent_type, 'parent_id': parent_content_data[0].id, railcontent_id,
1319
+ 'for-calculations': *[${filterGetParent}][0]{
1320
+ 'siblings-list': child[]->railcontent_id,
1321
+ 'parents-list': *[${filterForParentList}][0].child[]->railcontent_id
1322
+ },
1323
+ "related_lessons" : *[${filterGetParent}][0].child[${childrenFilter}]->{${queryFields}}
1324
+ }`
1325
+
1326
+ let result = await fetchSanity(query, false)
1327
+
1328
+ //there's no way in sanity to retrieve the index of an array, so we must calculate after fetch
1329
+ if (result['for-calculations'] &amp;&amp; result['for-calculations']['parents-list']) {
1330
+ const calc = result['for-calculations']
1331
+ const parentCount = calc['parents-list'].length
1332
+ const currentParentIndex = calc['parents-list'].indexOf(result['parent_id']) + 1
1333
+ const siblingCount = calc['siblings-list'].length
1334
+ const currentSiblingIndex = calc['siblings-list'].indexOf(result['railcontent_id']) + 1
1335
+
1336
+ delete result['for-calculations']
1337
+ result = { ...result, parentCount, currentParentIndex, siblingCount, currentSiblingIndex }
1338
+ return result
1339
+ } else {
1340
+ delete result['for-calculations']
1341
+ return result
1342
+ }
1343
+ }
1344
+
1345
+ /**
1346
+ * Fetch lessons related to a specific lesson by RailContent ID and type.
1347
+ * @param {string} railContentId - The RailContent ID of the current lesson.
1348
+ * @returns {Promise&lt;Array&lt;Object>|null>} - The fetched related lessons data or null if not found.
1349
+ */
1350
+ export async function fetchRelatedLessons(railContentId)
1351
+ {
1352
+ const defaultFilterFields = `_type==^._type &amp;&amp; brand == ^.brand &amp;&amp; railcontent_id != ${railContentId}`
1353
+
1354
+ const filterSameArtist = await new FilterBuilder(
1355
+ `${defaultFilterFields} &amp;&amp; references(^.artist->_id)`
1470
1356
  ).buildFilter()
1471
- const filterSongSameGenre = await new FilterBuilder(
1472
- `_type=="song" &amp;&amp; _type==^._type &amp;&amp; brand == "${brand}" &amp;&amp; references(^.genre[]->_id) &amp;&amp; railcontent_id !=${railContentId}`
1357
+ const filterSameGenre = await new FilterBuilder(
1358
+ `${defaultFilterFields} &amp;&amp; references(^.genre[]->_id)`
1473
1359
  ).buildFilter()
1474
- const filterNeighbouringSiblings = await new FilterBuilder(`references(^._id)`).buildFilter()
1475
- const childrenFilter = await new FilterBuilder(``, { isChildrenFilter: true }).buildFilter()
1476
- const queryFields = `_id, "id":railcontent_id, published_on, "instructor": instructor[0]->name, title, "thumbnail":thumbnail.asset->url, length_in_seconds, web_url_path, "type": _type, difficulty, difficulty_string, railcontent_id, artist->,"permission_id": permission[]->railcontent_id,_type, "genre": genre[]->name`
1477
- const queryFieldsWithSort = queryFields + ', sort'
1478
- const query = `*[railcontent_id == ${railContentId} &amp;&amp; brand == "${brand}" &amp;&amp; (!defined(permission) || references(*[_type=='permission']._id))]{
1360
+
1361
+ const queryFields = `_id, "id":railcontent_id, published_on, "instructor": instructor[0]->name, title, "thumbnail":thumbnail.asset->url, length_in_seconds, status, "type": _type, difficulty, difficulty_string, railcontent_id, artist->,"permission_id": permission[]->railcontent_id,_type, "genre": genre[]->name`
1362
+
1363
+ const query = `*[railcontent_id == ${railContentId} &amp;&amp; (!defined(permission) || references(*[_type=='permission']._id))]{
1479
1364
  _type, parent_type, railcontent_id,
1480
1365
  "related_lessons" : array::unique([
1481
- ...(*[${filterNeighbouringSiblings}][0].child[${childrenFilter}]->{${queryFields}}),
1482
- ...(*[${filterSongSameArtist}]{${queryFields}}|order(published_on desc, title asc)[0...10]),
1483
- ...(*[${filterSongSameGenre}]{${queryFields}}|order(published_on desc, title asc)[0...10]),
1484
- ...(*[${filterSameTypeAndSortOrder}]{${queryFieldsWithSort}}|order(sort asc, title asc)[0...10]),
1485
- ...(*[${filterSameType}]{${queryFields}}|order(published_on desc, title asc)[0...10])
1486
- ,
1366
+ ...(*[${filterSameArtist}]{${queryFields}}|order(published_on desc, title asc)[0...10]),
1367
+ ...(*[${filterSameGenre}]{${queryFields}}|order(published_on desc, title asc)[0...10]),
1487
1368
  ])[0...10]}`
1488
- return fetchSanity(query, false)
1369
+
1370
+ return await fetchSanity(query, false)
1489
1371
  }
1490
1372
 
1491
1373
  /**
@@ -1530,6 +1412,7 @@ export async function fetchPackAll(railcontentId, type = 'pack') {
1530
1412
  }
1531
1413
 
1532
1414
  export async function fetchLiveEvent(brand, forcedContentId = null) {
1415
+ const LIVE_EXTRA_MINUTES = 30
1533
1416
  //calendarIDs taken from addevent.php
1534
1417
  // TODO import instructor calendars to Sanity
1535
1418
  let defaultCalendarID = ''
@@ -1551,8 +1434,11 @@ export async function fetchLiveEvent(brand, forcedContentId = null) {
1551
1434
  }
1552
1435
  let startDateTemp = new Date()
1553
1436
  let endDateTemp = new Date()
1554
- startDateTemp = new Date(startDateTemp.setMinutes(startDateTemp.getMinutes() + 15))
1555
- endDateTemp = new Date(endDateTemp.setMinutes(endDateTemp.getMinutes() - 15))
1437
+
1438
+ startDateTemp = new Date(
1439
+ startDateTemp.setMinutes(startDateTemp.getMinutes() + LIVE_EXTRA_MINUTES)
1440
+ )
1441
+ endDateTemp = new Date(endDateTemp.setMinutes(endDateTemp.getMinutes() - LIVE_EXTRA_MINUTES))
1556
1442
 
1557
1443
  // See LiveStreamEventService.getCurrentOrNextLiveEvent for some nice complicated logic which I don't think is actually importart
1558
1444
  // this has some +- on times
@@ -1573,10 +1459,7 @@ export async function fetchLiveEvent(brand, forcedContentId = null) {
1573
1459
  "thumbnail": thumbnail.asset->url,
1574
1460
  ${artistOrInstructorName()},
1575
1461
  difficulty_string,
1576
- "instructors": instructor[]->{
1577
- name,
1578
- web_url_path,
1579
- },
1462
+ "instructors": ${instructorField},
1580
1463
  'videoId': coalesce(live_event_youtube_id, video.external_id),
1581
1464
  } | order(live_event_start_time)[0...1]`
1582
1465
  : `*[status == 'scheduled' &amp;&amp; brand == '${brand}' &amp;&amp; defined(live_event_start_time) &amp;&amp; live_event_start_time &lt;= '${getSanityDate(startDateTemp, false)}' &amp;&amp; live_event_end_time >= '${getSanityDate(endDateTemp, false)}']{
@@ -1610,12 +1493,13 @@ export async function fetchLiveEvent(brand, forcedContentId = null) {
1610
1493
  *
1611
1494
  * @example
1612
1495
  * fetchPackData(404048)
1613
- * .then(challenge => console.log(challenge))
1496
+ * .then(pack => console.log(pack))
1614
1497
  * .catch(error => console.error(error));
1615
1498
  */
1616
1499
  export async function fetchPackData(id) {
1617
- const query = `*[railcontent_id == ${id}]{
1618
- ${getFieldsForContentType('pack')}
1500
+ const builder = await new FilterBuilder(`railcontent_id == ${id}`).buildFilter()
1501
+ const query = `*[${builder}]{
1502
+ ${await getFieldsForContentTypeWithFilteredChildren('pack')}
1619
1503
  } [0...1]`
1620
1504
  return fetchSanity(query, false)
1621
1505
  }
@@ -1659,28 +1543,6 @@ export async function fetchCoachLessons(
1659
1543
  return fetchSanity(query, true)
1660
1544
  }
1661
1545
 
1662
- /**
1663
- * Fetch the data needed for the Course Overview screen.
1664
- * @param {string} id - The Railcontent ID of the course
1665
- * @returns {Promise&lt;Object|null>} - The course information and lessons or null if not found.
1666
- *
1667
- * @example
1668
- * fetchParentForDownload('course123')
1669
- * .then(course => console.log(course))
1670
- * .catch(error => console.error(error));
1671
- */
1672
- export async function fetchParentForDownload(id) {
1673
- const query = buildRawQuery(
1674
- `railcontent_id == ${id}`,
1675
- getFieldsForContentType('parent-download'),
1676
- {
1677
- isSingle: true,
1678
- }
1679
- )
1680
-
1681
- return fetchSanity(query, false)
1682
- }
1683
-
1684
1546
  /**
1685
1547
  * Fetch the data needed for the coach screen.
1686
1548
  * @param {string} id - The Railcontent ID of the coach
@@ -1969,14 +1831,10 @@ export async function fetchSanity(
1969
1831
  return null
1970
1832
  }
1971
1833
 
1972
- if (globalConfig.sanityConfig.debug) {
1973
- console.log('fetchSanity Query:', query)
1974
- }
1975
1834
  const perspective = globalConfig.sanityConfig.perspective ?? 'published'
1976
1835
  const api = globalConfig.sanityConfig.useCachedAPI ? 'apicdn' : 'api'
1977
1836
  const url = `https://${globalConfig.sanityConfig.projectId}.${api}.sanity.io/v${globalConfig.sanityConfig.version}/data/query/${globalConfig.sanityConfig.dataset}?perspective=${perspective}`
1978
1837
  const headers = {
1979
- Authorization: `Bearer ${globalConfig.sanityConfig.token}`,
1980
1838
  'Content-Type': 'application/json',
1981
1839
  }
1982
1840
 
@@ -2001,10 +1859,10 @@ export async function fetchSanity(
2001
1859
  }
2002
1860
  const result = await response.json()
2003
1861
  if (result.result) {
2004
- if (globalConfig.sanityConfig.debug) {
2005
- console.log('fetchSanity Results:', result)
2006
- }
2007
1862
  let results = isList ? result.result : result.result[0]
1863
+ if (!results) {
1864
+ throw new Error('No results found')
1865
+ }
2008
1866
  results = processNeedAccess
2009
1867
  ? await needsAccessDecorator(results, userPermissions, isAdmin)
2010
1868
  : results
@@ -2013,7 +1871,7 @@ export async function fetchSanity(
2013
1871
  throw new Error('No results found')
2014
1872
  }
2015
1873
  } catch (error) {
2016
- console.error('fetchSanity: Fetch error:', error)
1874
+ console.error('fetchSanity: Fetch error:', {error, query})
2017
1875
  return null
2018
1876
  }
2019
1877
  }
@@ -2104,7 +1962,12 @@ export async function fetchShowsData(brand) {
2104
1962
  * .catch(error => console.error(error));
2105
1963
  */
2106
1964
  export async function fetchMetadata(brand, type) {
2107
- const processedData = processMetadata(brand, type, true)
1965
+ let processedData = processMetadata(brand, type, true)
1966
+ if(processedData?.onlyAvailableTabs === true) {
1967
+ const activeTabs = await fetchRecentActivitiesActiveTabs()
1968
+ processedData.tabs = activeTabs
1969
+ }
1970
+
2108
1971
  return processedData ? processedData : {}
2109
1972
  }
2110
1973
 
@@ -2146,6 +2009,10 @@ function getSanityDate(date, roundToHourForCaching = true) {
2146
2009
  return date.toISOString()
2147
2010
  }
2148
2011
 
2012
+ function getDateOnly(date = new Date()) {
2013
+ return date.toISOString().split('T')[0]
2014
+ }
2015
+
2149
2016
  const merge = (a, b, predicate = (a, b) => a === b) => {
2150
2017
  const c = [...a] // copy to avoid side effects
2151
2018
  // add all items from B to copy C if they're not already present
@@ -2201,10 +2068,10 @@ function buildEntityAndTotalQuery(
2201
2068
  fields = '...',
2202
2069
  { sortOrder = 'published_on desc', start = 0, end = 10, isSingle = false }
2203
2070
  ) {
2204
- const sortString = sortOrder ? `order(${sortOrder})` : ''
2071
+ const sortString = sortOrder ? ` | order(${sortOrder})` : ''
2205
2072
  const countString = isSingle ? '[0...1]' : `[${start}...${end}]`
2206
2073
  const query = `{
2207
- "entity": *[${filter}] | ${sortString}${countString}
2074
+ "entity": *[${filter}] ${sortString}${countString}
2208
2075
  {
2209
2076
  ${fields}
2210
2077
  },
@@ -2316,37 +2183,35 @@ export async function fetchTabData(
2316
2183
  page = 1,
2317
2184
  limit = 10,
2318
2185
  sort = '-published_on',
2319
- includedFields = [],
2320
- progressIds = undefined,
2321
- progress = 'all',
2186
+ includedFields = []
2322
2187
  } = {}
2323
2188
  ) {
2324
2189
  const start = (page - 1) * limit
2325
2190
  const end = start + limit
2326
-
2327
2191
  // Construct the included fields filter, replacing 'difficulty' with 'difficulty_string'
2328
2192
  const includedFieldsFilter =
2329
2193
  includedFields.length > 0 ? filtersToGroq(includedFields, [], pageName) : ''
2330
2194
 
2331
- // limits the results to supplied progressIds for started &amp; completed filters
2332
- const progressFilter = await getProgressFilter(progress, progressIds)
2195
+ let sortOrder = getSortOrder(sort, brand, '')
2333
2196
 
2334
- // Determine the sort order
2335
- const sortOrder = getSortOrder(sort, brand, '')
2336
-
2337
- let fields = DEFAULT_FIELDS
2338
- let fieldsString = fields.join(',')
2197
+ const fieldsString = getFieldsForContentType('tab-data');
2198
+ const now = getSanityDate(new Date())
2339
2199
 
2340
2200
  // Determine the group by clause
2341
2201
  let query = ''
2342
2202
  let entityFieldsString = ''
2343
2203
  let filter = ''
2344
2204
 
2345
- filter = `brand == "${brand}" ${includedFieldsFilter} ${progressFilter}`
2346
- const childrenFilter = await new FilterBuilder(``, { isChildrenFilter: true }).buildFilter()
2347
- entityFieldsString = ` ${fieldsString},
2348
- 'lesson_count': coalesce(count(child[${childrenFilter}]->), 0) ,
2349
- 'length_in_seconds': coalesce(
2205
+ filter = `brand == "${brand}" ${includedFieldsFilter}`
2206
+ const childrenFilter = await new FilterBuilder(``, { isChildrenFilter: true, pullFutureContent: true }).buildFilter()
2207
+ const childrenFields = await getChildFieldsForContentType('tab-data')
2208
+ const lessonCountFilter = await new FilterBuilder(`_id in ^.child[]._ref`).buildFilter()
2209
+ entityFieldsString =
2210
+ ` ${fieldsString}
2211
+ 'children': child[${childrenFilter}]->{ ${childrenFields} 'children': child[${childrenFilter}]->{ ${childrenFields} }, },
2212
+ 'isLive': live_event_start_time &lt;= "${now}" &amp;&amp; live_event_end_time >= "${now}",
2213
+ 'lesson_count': coalesce(count(*[${lessonCountFilter}]), 0),
2214
+ 'length_in_seconds': coalesce(
2350
2215
  math::sum(
2351
2216
  select(
2352
2217
  child[${childrenFilter}]->length_in_seconds
@@ -2354,31 +2219,16 @@ export async function fetchTabData(
2354
2219
  ),
2355
2220
  length_in_seconds
2356
2221
  ),`
2357
-
2358
2222
  const filterWithRestrictions = await new FilterBuilder(filter, {}).buildFilter()
2359
2223
  query = buildEntityAndTotalQuery(filterWithRestrictions, entityFieldsString, {
2360
2224
  sortOrder: sortOrder,
2361
2225
  start: start,
2362
- end: end,
2226
+ end: end
2363
2227
  })
2364
2228
 
2365
- return fetchSanity(query, true)
2366
- }
2229
+ let results = await fetchSanity(query, true);
2367
2230
 
2368
- export async function fetchRecent(
2369
- brand,
2370
- pageName,
2371
- { page = 1, limit = 10, sort = '-published_on', includedFields = [], progress = 'recent' } = {}
2372
- ) {
2373
- const mergedIncludedFields = [...includedFields, `tab,all`]
2374
- const results = await fetchTabData(brand, pageName, {
2375
- page,
2376
- limit,
2377
- sort,
2378
- includedFields: mergedIncludedFields,
2379
- progress: progress.toLowerCase(),
2380
- })
2381
- return results.entity
2231
+ return results;
2382
2232
  }
2383
2233
 
2384
2234
  export async function fetchScheduledAndNewReleases(
@@ -2403,6 +2253,7 @@ export async function fetchScheduledAndNewReleases(
2403
2253
  "id": railcontent_id,
2404
2254
  title,
2405
2255
  "image": thumbnail.asset->url,
2256
+ "thumbnail": thumbnail.asset->url,
2406
2257
  ${artistOrInstructorName()},
2407
2258
  "artists": instructor[]->name,
2408
2259
  difficulty,
@@ -2418,17 +2269,14 @@ export async function fetchScheduledAndNewReleases(
2418
2269
  return fetchSanity(query, true)
2419
2270
  }
2420
2271
 
2421
- export async function fetchShows(
2422
- brand,
2423
- type,
2424
- sort = 'sort'
2425
- ) {
2272
+ export async function fetchShows(brand, type, sort = 'sort') {
2426
2273
  const sortOrder = getSortOrder(sort, brand)
2427
2274
  const filter = `_type == '${type}' &amp;&amp; brand == '${brand}'`
2428
2275
  const filterParams = {}
2429
2276
 
2430
2277
  const query = await buildQuery(filter, filterParams, getFieldsForContentType(type), {
2431
- sortOrder: sortOrder
2278
+ sortOrder: sortOrder,
2279
+ end: 100, // Adrian: added for homepage progress rows, this should be handled gracefully
2432
2280
  })
2433
2281
  return fetchSanity(query, true)
2434
2282
  }
@@ -2446,7 +2294,7 @@ export async function fetchShows(
2446
2294
  <br class="clear">
2447
2295
 
2448
2296
  <footer>
2449
- Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.3</a> on Mon Jun 16 2025 14:26:22 GMT+0300 (Eastern European Summer Time) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
2297
+ Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.3</a> on Thu Oct 02 2025 11:46:05 GMT+0300 (Eastern European Summer Time) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
2450
2298
  </footer>
2451
2299
 
2452
2300
  <script>prettyPrint();</script>