musora-content-services 1.0.173 → 1.0.174
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/node.js.yml +0 -0
- package/CHANGELOG.md +2 -0
- package/README.md +0 -0
- package/babel.config.js +0 -0
- package/docs/config.js.html +4 -3
- package/docs/fonts/Montserrat/Montserrat-Bold.eot +0 -0
- package/docs/fonts/Montserrat/Montserrat-Bold.ttf +0 -0
- package/docs/fonts/Montserrat/Montserrat-Bold.woff +0 -0
- package/docs/fonts/Montserrat/Montserrat-Bold.woff2 +0 -0
- package/docs/fonts/Montserrat/Montserrat-Regular.eot +0 -0
- package/docs/fonts/Montserrat/Montserrat-Regular.ttf +0 -0
- package/docs/fonts/Montserrat/Montserrat-Regular.woff +0 -0
- package/docs/fonts/Montserrat/Montserrat-Regular.woff2 +0 -0
- package/docs/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.eot +0 -0
- package/docs/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.svg +0 -0
- package/docs/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.ttf +0 -0
- package/docs/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.woff +0 -0
- package/docs/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.woff2 +0 -0
- package/docs/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.eot +0 -0
- package/docs/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.svg +0 -0
- package/docs/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.ttf +0 -0
- package/docs/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.woff +0 -0
- package/docs/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.woff2 +0 -0
- package/docs/index.html +2 -2
- package/docs/module-Config.html +28 -4
- package/docs/module-Railcontent-Services.html +340 -79
- package/docs/module-Sanity-Services.html +403 -47
- package/docs/railcontent.js.html +58 -48
- package/docs/sanity.js.html +650 -560
- package/docs/scripts/collapse.js +0 -0
- package/docs/scripts/commonNav.js +0 -0
- package/docs/scripts/linenumber.js +0 -0
- package/docs/scripts/nav.js +0 -0
- package/docs/scripts/polyfill.js +0 -0
- package/docs/scripts/prettify/Apache-License-2.0.txt +0 -0
- package/docs/scripts/prettify/lang-css.js +0 -0
- package/docs/scripts/prettify/prettify.js +0 -0
- package/docs/scripts/search.js +0 -0
- package/docs/styles/jsdoc.css +0 -0
- package/docs/styles/prettify.css +0 -0
- package/jest.config.js +0 -0
- package/jsdoc.json +0 -0
- package/package.json +1 -1
- package/src/contentMetaData.js +0 -0
- package/src/filterBuilder.js +0 -0
- package/src/index.d.ts +2 -0
- package/src/index.js +2 -0
- package/src/services/config.js +0 -0
- package/src/services/contentLikes.js +0 -0
- package/src/services/contentProgress.js +19 -0
- package/src/services/dataContext.js +0 -0
- package/src/services/lastUpdated.js +0 -0
- package/src/services/sanity.js +26 -2
- package/src/services/userPermissions.js +0 -0
- package/test/contentLikes.test.js +0 -0
- package/test/contentProgress.test.js +11 -1
- package/test/initializeTests.js +0 -0
- package/test/lastUpdated.test.js +0 -0
- package/test/localStorageMock.js +0 -0
- package/test/log.js +0 -0
- package/test/sanityQueryService.test.js +30 -0
- package/test/userPermissions.test.js +0 -0
- package/tools/generate-index.js +0 -0
package/docs/sanity.js.html
CHANGED
|
@@ -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#.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#.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#.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#.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#.postChallengesCommunityNotification">postChallengesCommunityNotification</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.
|
|
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#.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#.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#.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#.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#.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#.postChallengesUnlock">postChallengesUnlock</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#.fetchAllSongs">fetchAllSongs</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#.fetchAssignments">fetchAssignments</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#.fetchCatalogMetadata">fetchCatalogMetadata</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchChallengeOverview">fetchChallengeOverview</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchChildren">fetchChildren</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#.fetchCommentModContentData">fetchCommentModContentData</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchCourseOverview">fetchCourseOverview</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#.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#.fetchMethodNextLesson">fetchMethodNextLesson</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#.fetchMethods">fetchMethods</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#.fetchPackChildren">fetchPackChildren</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#.fetchParentByRailContentId">fetchParentByRailContentId</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#.fetchRelatedMethodLessons">fetchRelatedMethodLessons</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#.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#.fetchSongCount">fetchSongCount</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchSongFilterOptions">fetchSongFilterOptions</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#.fetchWorkouts">fetchWorkouts</a></li></ul></li></ul>
|
|
33
33
|
|
|
34
34
|
</nav>
|
|
35
35
|
|
|
@@ -70,8 +70,10 @@ import {
|
|
|
70
70
|
|
|
71
71
|
import {globalConfig} from "./config";
|
|
72
72
|
|
|
73
|
-
import {
|
|
73
|
+
import {fetchAllCompletedStates, fetchCurrentSongComplete} from './railcontent.js';
|
|
74
74
|
import {arrayToStringRepresentation, FilterBuilder} from "../filterBuilder";
|
|
75
|
+
import {fetchUserPermissions} from "./userPermissions";
|
|
76
|
+
import {getAllCompleted, getAllStarted, getAllStartedOrCompleted} from "./contentProgress";
|
|
75
77
|
|
|
76
78
|
/**
|
|
77
79
|
* Exported functions that are excluded from index generation.
|
|
@@ -79,21 +81,22 @@ import {arrayToStringRepresentation, FilterBuilder} from "../filterBuilder";
|
|
|
79
81
|
* @type {string[]}
|
|
80
82
|
*/
|
|
81
83
|
const excludeFromGeneratedIndex = [];
|
|
84
|
+
|
|
82
85
|
/**
|
|
83
|
-
* Fetch a song by its document ID from Sanity.
|
|
84
|
-
*
|
|
85
|
-
* @param {string} documentId - The ID of the document to fetch.
|
|
86
|
-
* @returns {Promise<Object|null>} - A promise that resolves to an object containing the song data or null if not found.
|
|
87
|
-
*
|
|
88
|
-
* @example
|
|
89
|
-
* fetchSongById('abc123')
|
|
90
|
-
* .then(song => console.log(song))
|
|
91
|
-
* .catch(error => console.error(error));
|
|
92
|
-
*/
|
|
86
|
+
* Fetch a song by its document ID from Sanity.
|
|
87
|
+
*
|
|
88
|
+
* @param {string} documentId - The ID of the document to fetch.
|
|
89
|
+
* @returns {Promise<Object|null>} - A promise that resolves to an object containing the song data or null if not found.
|
|
90
|
+
*
|
|
91
|
+
* @example
|
|
92
|
+
* fetchSongById('abc123')
|
|
93
|
+
* .then(song => console.log(song))
|
|
94
|
+
* .catch(error => console.error(error));
|
|
95
|
+
*/
|
|
93
96
|
export async function fetchSongById(documentId) {
|
|
94
97
|
const fields = getFieldsForContentType('song');
|
|
95
98
|
const filterParams = {};
|
|
96
|
-
const query = buildQuery(
|
|
99
|
+
const query = await buildQuery(
|
|
97
100
|
`_type == "song" && railcontent_id == ${documentId}`,
|
|
98
101
|
filterParams,
|
|
99
102
|
fields,
|
|
@@ -104,48 +107,48 @@ export async function fetchSongById(documentId) {
|
|
|
104
107
|
}
|
|
105
108
|
|
|
106
109
|
/**
|
|
107
|
-
* Fetch all artists with lessons available for a specific brand.
|
|
108
|
-
*
|
|
109
|
-
* @param {string} brand - The brand for which to fetch artists.
|
|
110
|
-
* @returns {Promise<Object|null>} - A promise that resolves to an array of artist objects or null if not found.
|
|
111
|
-
*
|
|
112
|
-
* @example
|
|
113
|
-
* fetchArtists('drumeo')
|
|
114
|
-
* .then(artists => console.log(artists))
|
|
115
|
-
* .catch(error => console.error(error));
|
|
116
|
-
*/
|
|
110
|
+
* Fetch all artists with lessons available for a specific brand.
|
|
111
|
+
*
|
|
112
|
+
* @param {string} brand - The brand for which to fetch artists.
|
|
113
|
+
* @returns {Promise<Object|null>} - A promise that resolves to an array of artist objects or null if not found.
|
|
114
|
+
*
|
|
115
|
+
* @example
|
|
116
|
+
* fetchArtists('drumeo')
|
|
117
|
+
* .then(artists => console.log(artists))
|
|
118
|
+
* .catch(error => console.error(error));
|
|
119
|
+
*/
|
|
117
120
|
export async function fetchArtists(brand) {
|
|
118
|
-
|
|
119
|
-
|
|
121
|
+
const filter = await new FilterBuilder(`_type == "song" && brand == "${brand}" && references(^._id)`, {bypassPermissions: true}).buildFilter();
|
|
122
|
+
const query = `
|
|
120
123
|
*[_type == "artist"]{
|
|
121
124
|
name,
|
|
122
125
|
"lessonsCount": count(*[${filter}])
|
|
123
126
|
}[lessonsCount > 0]`;
|
|
124
|
-
|
|
127
|
+
return fetchSanity(query, true, {processNeedAccess: false});
|
|
125
128
|
}
|
|
126
129
|
|
|
127
130
|
/**
|
|
128
|
-
* Fetch current number of artists for songs within a brand.
|
|
129
|
-
* @param {string} brand - The current brand.
|
|
130
|
-
* @returns {Promise<int|null>} - The fetched count of artists.
|
|
131
|
-
*/
|
|
131
|
+
* Fetch current number of artists for songs within a brand.
|
|
132
|
+
* @param {string} brand - The current brand.
|
|
133
|
+
* @returns {Promise<int|null>} - The fetched count of artists.
|
|
134
|
+
*/
|
|
132
135
|
export async function fetchSongArtistCount(brand) {
|
|
133
|
-
|
|
134
|
-
|
|
136
|
+
const query = `count(*[_type == 'artist']{'lessonsCount': count(*[_type == 'song' && brand == '${brand}' && references(^._id)]._id)}[lessonsCount > 0])`;
|
|
137
|
+
return fetchSanity(query, true, {processNeedAccess: false});
|
|
135
138
|
}
|
|
136
139
|
|
|
137
140
|
/**
|
|
138
|
-
* Fetch related songs for a specific brand and song ID.
|
|
139
|
-
*
|
|
140
|
-
* @param {string} brand - The brand for which to fetch related songs.
|
|
141
|
-
* @param {string} songId - The ID of the song to find related songs for.
|
|
142
|
-
* @returns {Promise<Object|null>} - A promise that resolves to an array of related song objects or null if not found.
|
|
143
|
-
*
|
|
144
|
-
* @example
|
|
145
|
-
* fetchRelatedSongs('drumeo', '12345')
|
|
146
|
-
* .then(relatedSongs => console.log(relatedSongs))
|
|
147
|
-
* .catch(error => console.error(error));
|
|
148
|
-
*/
|
|
141
|
+
* Fetch related songs for a specific brand and song ID.
|
|
142
|
+
*
|
|
143
|
+
* @param {string} brand - The brand for which to fetch related songs.
|
|
144
|
+
* @param {string} songId - The ID of the song to find related songs for.
|
|
145
|
+
* @returns {Promise<Object|null>} - A promise that resolves to an array of related song objects or null if not found.
|
|
146
|
+
*
|
|
147
|
+
* @example
|
|
148
|
+
* fetchRelatedSongs('drumeo', '12345')
|
|
149
|
+
* .then(relatedSongs => console.log(relatedSongs))
|
|
150
|
+
* .catch(error => console.error(error));
|
|
151
|
+
*/
|
|
149
152
|
export async function fetchRelatedSongs(brand, songId) {
|
|
150
153
|
const query = `
|
|
151
154
|
*[_type == "song" && railcontent_id == ${songId}]{
|
|
@@ -237,29 +240,29 @@ export async function fetchRelatedSongs(brand, songId) {
|
|
|
237
240
|
* .catch(error => console.error(error));
|
|
238
241
|
*/
|
|
239
242
|
export async function fetchAllSongs(brand, {
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
243
|
+
page = 1,
|
|
244
|
+
limit = 10,
|
|
245
|
+
searchTerm = "",
|
|
246
|
+
sort = "-published_on",
|
|
247
|
+
includedFields = [],
|
|
248
|
+
groupBy = ""
|
|
246
249
|
}) {
|
|
247
250
|
return fetchAll(brand, 'song', {page, limit, searchTerm, sort, includedFields, groupBy});
|
|
248
251
|
}
|
|
249
252
|
|
|
250
253
|
/**
|
|
251
|
-
* Fetch filter options for a specific brand.
|
|
252
|
-
*
|
|
253
|
-
* @param {string} brand - The brand for which to fetch filter options.
|
|
254
|
-
* @returns {Promise<Object|null>} - A promise that resolves to an object containing filter options or null if not found.
|
|
255
|
-
*
|
|
256
|
-
* @example
|
|
257
|
-
* fetchSongFilterOptions('drumeo')
|
|
258
|
-
* .then(options => console.log(options))
|
|
259
|
-
* .catch(error => console.error(error));
|
|
260
|
-
*/
|
|
254
|
+
* Fetch filter options for a specific brand.
|
|
255
|
+
*
|
|
256
|
+
* @param {string} brand - The brand for which to fetch filter options.
|
|
257
|
+
* @returns {Promise<Object|null>} - A promise that resolves to an object containing filter options or null if not found.
|
|
258
|
+
*
|
|
259
|
+
* @example
|
|
260
|
+
* fetchSongFilterOptions('drumeo')
|
|
261
|
+
* .then(options => console.log(options))
|
|
262
|
+
* .catch(error => console.error(error));
|
|
263
|
+
*/
|
|
261
264
|
export async function fetchSongFilterOptions(brand) {
|
|
262
|
-
|
|
265
|
+
const query = `
|
|
263
266
|
{
|
|
264
267
|
"difficulty": [
|
|
265
268
|
{"type": "Introductory", "count": count(*[_type == 'song' && brand == '${brand}' && difficulty_string == "Introductory"]._id)},
|
|
@@ -278,17 +281,17 @@ export async function fetchSongFilterOptions(brand) {
|
|
|
278
281
|
]
|
|
279
282
|
}`;
|
|
280
283
|
|
|
281
|
-
|
|
284
|
+
return fetchSanity(query, true);
|
|
282
285
|
}
|
|
283
286
|
|
|
284
287
|
/**
|
|
285
|
-
* Fetch the total count of songs for a specific brand.
|
|
286
|
-
* @param {string} brand - The brand for which to fetch the song count.
|
|
287
|
-
* @returns {Promise<number|null>} - The total count of songs or null if an error occurs.
|
|
288
|
-
*/
|
|
288
|
+
* Fetch the total count of songs for a specific brand.
|
|
289
|
+
* @param {string} brand - The brand for which to fetch the song count.
|
|
290
|
+
* @returns {Promise<number|null>} - The total count of songs or null if an error occurs.
|
|
291
|
+
*/
|
|
289
292
|
export async function fetchSongCount(brand) {
|
|
290
|
-
|
|
291
|
-
|
|
293
|
+
const query = `count(*[_type == 'song' && brand == "${brand}"])`;
|
|
294
|
+
return fetchSanity(query, true, {processNeedAccess: false});
|
|
292
295
|
}
|
|
293
296
|
|
|
294
297
|
/**
|
|
@@ -303,29 +306,29 @@ export async function fetchSongCount(brand) {
|
|
|
303
306
|
* @example
|
|
304
307
|
* fetchWorkouts('drumeo')
|
|
305
308
|
* .then(workouts => console.log(workouts))
|
|
306
|
-
* .catch(error => console.error(error));
|
|
309
|
+
* .catch(error => console.error(error));
|
|
307
310
|
*/
|
|
308
311
|
export async function fetchWorkouts(brand) {
|
|
309
|
-
|
|
310
|
-
|
|
312
|
+
const fields = getFieldsForContentType('workout');
|
|
313
|
+
const query = `*[_type == 'workout' && brand == '${brand}'] [0...5] {
|
|
311
314
|
${fields.toString()}
|
|
312
315
|
} | order(published_on desc)[0...5]`
|
|
313
|
-
|
|
316
|
+
return fetchSanity(query, true);
|
|
314
317
|
}
|
|
315
318
|
|
|
316
319
|
/**
|
|
317
|
-
* Fetch the latest new releases for a specific brand.
|
|
318
|
-
* @param {string} brand - The brand for which to fetch new releases.
|
|
319
|
-
* @returns {Promise<Object|null>} - The fetched new releases data or null if not found.
|
|
320
|
-
*/
|
|
321
|
-
export async function fetchNewReleases(brand, {
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
320
|
+
* Fetch the latest new releases for a specific brand.
|
|
321
|
+
* @param {string} brand - The brand for which to fetch new releases.
|
|
322
|
+
* @returns {Promise<Object|null>} - The fetched new releases data or null if not found.
|
|
323
|
+
*/
|
|
324
|
+
export async function fetchNewReleases(brand, {page = 1, limit = 20, sort = "-published_on"} = {}) {
|
|
325
|
+
const newTypes = getNewReleasesTypes(brand);
|
|
326
|
+
const typesString = arrayToStringRepresentation(newTypes);
|
|
327
|
+
const start = (page - 1) * limit;
|
|
328
|
+
const end = start + limit;
|
|
329
|
+
const sortOrder = getSortOrder(sort);
|
|
330
|
+
const filter = `_type in ${typesString} && brand == '${brand}'`;
|
|
331
|
+
const fields = `
|
|
329
332
|
"id": railcontent_id,
|
|
330
333
|
title,
|
|
331
334
|
"image": thumbnail.asset->url,
|
|
@@ -339,41 +342,41 @@ export async function fetchNewReleases(brand, { page = 1, limit = 20, sort="-pub
|
|
|
339
342
|
web_url_path,
|
|
340
343
|
"permission_id": permission[]->railcontent_id,
|
|
341
344
|
`;
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
345
|
+
const filterParams = {};
|
|
346
|
+
const query = await buildQuery(
|
|
347
|
+
filter,
|
|
348
|
+
filterParams,
|
|
349
|
+
fields,
|
|
350
|
+
{
|
|
351
|
+
sortOrder: sortOrder,
|
|
352
|
+
start,
|
|
353
|
+
end: end,
|
|
354
|
+
});
|
|
355
|
+
return fetchSanity(query, true);
|
|
353
356
|
}
|
|
354
357
|
|
|
355
358
|
|
|
356
359
|
/**
|
|
357
|
-
* Fetch upcoming events for a specific brand.
|
|
358
|
-
*
|
|
359
|
-
* @param {string} brand - The brand for which to fetch upcoming events.
|
|
360
|
-
* @returns {Promise<Object|null>} - A promise that resolves to an array of upcoming event objects or null if not found.
|
|
361
|
-
*
|
|
362
|
-
* @example
|
|
363
|
-
* fetchUpcomingEvents('drumeo', {
|
|
364
|
-
* page: 2,
|
|
365
|
-
* limit: 20,
|
|
366
|
-
* })
|
|
367
|
-
* .then(events => console.log(events))
|
|
368
|
-
* .catch(error => console.error(error));
|
|
369
|
-
*/
|
|
370
|
-
export async function fetchUpcomingEvents(brand, {
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
360
|
+
* Fetch upcoming events for a specific brand.
|
|
361
|
+
*
|
|
362
|
+
* @param {string} brand - The brand for which to fetch upcoming events.
|
|
363
|
+
* @returns {Promise<Object|null>} - A promise that resolves to an array of upcoming event objects or null if not found.
|
|
364
|
+
*
|
|
365
|
+
* @example
|
|
366
|
+
* fetchUpcomingEvents('drumeo', {
|
|
367
|
+
* page: 2,
|
|
368
|
+
* limit: 20,
|
|
369
|
+
* })
|
|
370
|
+
* .then(events => console.log(events))
|
|
371
|
+
* .catch(error => console.error(error));
|
|
372
|
+
*/
|
|
373
|
+
export async function fetchUpcomingEvents(brand, {page = 1, limit = 10} = {}) {
|
|
374
|
+
const liveTypes = getUpcomingEventsTypes(brand);
|
|
375
|
+
const typesString = arrayToStringRepresentation(liveTypes);
|
|
376
|
+
const now = getSanityDate(new Date());
|
|
377
|
+
const start = (page - 1) * limit;
|
|
378
|
+
const end = start + limit;
|
|
379
|
+
const fields = `
|
|
377
380
|
"id": railcontent_id,
|
|
378
381
|
title,
|
|
379
382
|
"image": thumbnail.asset->url,
|
|
@@ -386,16 +389,16 @@ export async function fetchUpcomingEvents(brand, { page = 1, limit = 10 } = {})
|
|
|
386
389
|
"type": _type,
|
|
387
390
|
web_url_path,
|
|
388
391
|
"permission_id": permission[]->railcontent_id,`;
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
392
|
+
const query = buildRawQuery(
|
|
393
|
+
`_type in ${typesString} && brand == '${brand}' && published_on > '${now}' && status == 'scheduled'`,
|
|
394
|
+
fields,
|
|
395
|
+
{
|
|
396
|
+
sortOrder: 'published_on asc',
|
|
397
|
+
start: start,
|
|
398
|
+
end: end,
|
|
399
|
+
},
|
|
400
|
+
);
|
|
401
|
+
return fetchSanity(query, true);
|
|
399
402
|
}
|
|
400
403
|
|
|
401
404
|
/**
|
|
@@ -412,16 +415,16 @@ export async function fetchUpcomingEvents(brand, { page = 1, limit = 10 } = {})
|
|
|
412
415
|
* .then(content => console.log(content))
|
|
413
416
|
* .catch(error => console.error(error));
|
|
414
417
|
*/
|
|
415
|
-
export async function fetchScheduledReleases(brand, {
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
418
|
+
export async function fetchScheduledReleases(brand, {page = 1, limit = 10}) {
|
|
419
|
+
const upcomingTypes = getUpcomingEventsTypes(brand);
|
|
420
|
+
const newTypes = getNewReleasesTypes(brand);
|
|
421
|
+
|
|
422
|
+
const scheduledTypes = merge(upcomingTypes, newTypes)
|
|
423
|
+
const typesString = arrayJoinWithQuotes(scheduledTypes);
|
|
424
|
+
const now = getSanityDate(new Date());
|
|
425
|
+
const start = (page - 1) * limit;
|
|
426
|
+
const end = start + limit;
|
|
427
|
+
const query = `*[_type in [${typesString}] && brand == '${brand}' && status in ['published','scheduled'] && published_on > '${now}']{
|
|
425
428
|
"id": railcontent_id,
|
|
426
429
|
title,
|
|
427
430
|
"image": thumbnail.asset->url,
|
|
@@ -435,21 +438,21 @@ export async function fetchScheduledReleases(brand, { page = 1, limit = 10 }) {
|
|
|
435
438
|
web_url_path,
|
|
436
439
|
"permission_id": permission[]->railcontent_id,
|
|
437
440
|
} | order(published_on asc)[${start}...${end}]`;
|
|
438
|
-
|
|
441
|
+
return fetchSanity(query, true);
|
|
439
442
|
}
|
|
440
443
|
|
|
441
444
|
/**
|
|
442
|
-
* Fetch content by a specific Railcontent ID.
|
|
443
|
-
*
|
|
444
|
-
* @param {string} id - The Railcontent ID of the content to fetch.
|
|
445
|
-
* @param {string} contentType - The document type of content to fetch
|
|
446
|
-
* @returns {Promise<Object|null>} - A promise that resolves to the content object or null if not found.
|
|
447
|
-
*
|
|
448
|
-
* @example
|
|
449
|
-
* fetchByRailContentId('abc123')
|
|
450
|
-
* .then(content => console.log(content))
|
|
451
|
-
* .catch(error => console.error(error));
|
|
452
|
-
*/
|
|
445
|
+
* Fetch content by a specific Railcontent ID.
|
|
446
|
+
*
|
|
447
|
+
* @param {string} id - The Railcontent ID of the content to fetch.
|
|
448
|
+
* @param {string} contentType - The document type of content to fetch
|
|
449
|
+
* @returns {Promise<Object|null>} - A promise that resolves to the content object or null if not found.
|
|
450
|
+
*
|
|
451
|
+
* @example
|
|
452
|
+
* fetchByRailContentId('abc123')
|
|
453
|
+
* .then(content => console.log(content))
|
|
454
|
+
* .catch(error => console.error(error));
|
|
455
|
+
*/
|
|
453
456
|
export async function fetchByRailContentId(id, contentType) {
|
|
454
457
|
|
|
455
458
|
const query = buildRawQuery(
|
|
@@ -464,24 +467,24 @@ export async function fetchByRailContentId(id, contentType) {
|
|
|
464
467
|
}
|
|
465
468
|
|
|
466
469
|
/**
|
|
467
|
-
* Fetch content by an array of Railcontent IDs.
|
|
468
|
-
*
|
|
469
|
-
* @param {Array<string>} ids - The array of Railcontent IDs of the content to fetch.
|
|
470
|
-
* @param {string} [contentType] - The content type the IDs to add needed fields to the response.
|
|
471
|
-
* @returns {Promise<Array<Object>|null>} - A promise that resolves to an array of content objects or null if not found.
|
|
472
|
-
*
|
|
473
|
-
* @example
|
|
474
|
-
* fetchByRailContentIds(['abc123', 'def456', 'ghi789'])
|
|
475
|
-
* .then(contents => console.log(contents))
|
|
476
|
-
* .catch(error => console.error(error));
|
|
477
|
-
*/
|
|
470
|
+
* Fetch content by an array of Railcontent IDs.
|
|
471
|
+
*
|
|
472
|
+
* @param {Array<string>} ids - The array of Railcontent IDs of the content to fetch.
|
|
473
|
+
* @param {string} [contentType] - The content type the IDs to add needed fields to the response.
|
|
474
|
+
* @returns {Promise<Array<Object>|null>} - A promise that resolves to an array of content objects or null if not found.
|
|
475
|
+
*
|
|
476
|
+
* @example
|
|
477
|
+
* fetchByRailContentIds(['abc123', 'def456', 'ghi789'])
|
|
478
|
+
* .then(contents => console.log(contents))
|
|
479
|
+
* .catch(error => console.error(error));
|
|
480
|
+
*/
|
|
478
481
|
export async function fetchByRailContentIds(ids, contentType = undefined) {
|
|
479
|
-
|
|
482
|
+
const idsString = ids.join(',');
|
|
480
483
|
|
|
481
|
-
|
|
484
|
+
const query = `*[railcontent_id in [${idsString}]]{
|
|
482
485
|
${getFieldsForContentType(contentType)}
|
|
483
486
|
}`
|
|
484
|
-
|
|
487
|
+
return fetchSanity(query, true);
|
|
485
488
|
}
|
|
486
489
|
|
|
487
490
|
/**
|
|
@@ -498,6 +501,7 @@ export async function fetchByRailContentIds(ids, contentType = undefined) {
|
|
|
498
501
|
* @param {Array<string>} [params.progressIds=undefined] - An array of railcontent IDs to filter the results by. Used for filtering by progress.
|
|
499
502
|
* @param {boolean} [params.useDefaultFields=true] - use the default sanity fields for content Type
|
|
500
503
|
* @param {Array<string>} [params.customFields=[]] - An array of sanity fields to include in the request
|
|
504
|
+
* @param {string} [params.progress="all"] - An string representing which progress filter to use ("all", "in progress", "complete", "not started").
|
|
501
505
|
* @returns {Promise<Object|null>} - The fetched content data or null if not found.
|
|
502
506
|
*
|
|
503
507
|
* @example
|
|
@@ -516,15 +520,16 @@ export async function fetchByRailContentIds(ids, contentType = undefined) {
|
|
|
516
520
|
* .catch(error => console.error(error));
|
|
517
521
|
*/
|
|
518
522
|
export async function fetchAll(brand, type, {
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
523
|
+
page = 1,
|
|
524
|
+
limit = 10,
|
|
525
|
+
searchTerm = "",
|
|
526
|
+
sort = "-published_on",
|
|
527
|
+
includedFields = [],
|
|
528
|
+
groupBy = "",
|
|
529
|
+
progressIds = undefined,
|
|
530
|
+
useDefaultFields = true,
|
|
531
|
+
customFields = [],
|
|
532
|
+
progress = "all"
|
|
528
533
|
} = {}) {
|
|
529
534
|
let config = contentTypeConfig[type] ?? {};
|
|
530
535
|
let additionalFields = config?.fields ?? [];
|
|
@@ -539,8 +544,8 @@ export async function fetchAll(brand, type, {
|
|
|
539
544
|
// Construct the search filter
|
|
540
545
|
const searchFilter = searchTerm
|
|
541
546
|
? groupBy !== "" ?
|
|
542
|
-
|
|
543
|
-
|
|
547
|
+
`&& (^.name match "${searchTerm}*" || title match "${searchTerm}*")`
|
|
548
|
+
: `&& (artist->name match "${searchTerm}*" || instructor[]->name match "${searchTerm}*" || title match "${searchTerm}*" || name match "${searchTerm}*")`
|
|
544
549
|
: "";
|
|
545
550
|
|
|
546
551
|
// Construct the included fields filter, replacing 'difficulty' with 'difficulty_string'
|
|
@@ -549,13 +554,12 @@ export async function fetchAll(brand, type, {
|
|
|
549
554
|
: "";
|
|
550
555
|
|
|
551
556
|
// limits the results to supplied progressIds for started & completed filters
|
|
552
|
-
const progressFilter =
|
|
553
|
-
`&& railcontent_id in [${progressIds.join(',')}]` : "";
|
|
557
|
+
const progressFilter = await getProgressFilter(progress, progressIds);
|
|
554
558
|
|
|
555
559
|
// Determine the sort order
|
|
556
560
|
const sortOrder = getSortOrder(sort);
|
|
557
561
|
|
|
558
|
-
let fields = useDefaultFields ?
|
|
562
|
+
let fields = useDefaultFields ? customFields.concat(DEFAULT_FIELDS, additionalFields) : customFields;
|
|
559
563
|
let fieldsString = fields.join(',');
|
|
560
564
|
|
|
561
565
|
// Determine the group by clause
|
|
@@ -579,7 +583,7 @@ export async function fetchAll(brand, type, {
|
|
|
579
583
|
`;
|
|
580
584
|
filter = `_type == '${groupBy}' && count(*[brand == '${brand}' && ^._id == ${groupBy}._ref ${typeFilter} ${searchFilter} ${includedFieldsFilter} ${progressFilter}]._id) > 0`;
|
|
581
585
|
} else if (groupBy !== "") {
|
|
582
|
-
const webUrlPath = (groupBy == 'genre')?'/genres':'';
|
|
586
|
+
const webUrlPath = (groupBy == 'genre') ? '/genres' : '';
|
|
583
587
|
const lessonsFilter = `brand == '${brand}' && ^._id in ${groupBy}[]._ref ${typeFilter} ${searchFilter} ${includedFieldsFilter} ${progressFilter}`;
|
|
584
588
|
entityFieldsString = `
|
|
585
589
|
'id': railcontent_id,
|
|
@@ -609,8 +613,29 @@ export async function fetchAll(brand, type, {
|
|
|
609
613
|
return fetchSanity(query, true);
|
|
610
614
|
}
|
|
611
615
|
|
|
612
|
-
|
|
613
|
-
{
|
|
616
|
+
async function getProgressFilter(progress, progressIds) {
|
|
617
|
+
switch (progress) {
|
|
618
|
+
case "all":
|
|
619
|
+
return progressIds !== undefined ?
|
|
620
|
+
`&& railcontent_id in [${progressIds.join(',')}]` : "";
|
|
621
|
+
case "in progress": {
|
|
622
|
+
const ids = await getAllStarted();
|
|
623
|
+
return `&& railcontent_id in [${ids.join(',')}]`;
|
|
624
|
+
}
|
|
625
|
+
case "completed": {
|
|
626
|
+
const ids = await getAllCompleted();
|
|
627
|
+
return `&& railcontent_id in [${ids.join(',')}]`;
|
|
628
|
+
}
|
|
629
|
+
case "not started": {
|
|
630
|
+
const ids = await getAllStartedOrCompleted();
|
|
631
|
+
return `&& !(railcontent_id in [${ids.join(',')}])`;
|
|
632
|
+
}
|
|
633
|
+
default:
|
|
634
|
+
throw new Error(`'${progress}' progress option not implemented`);
|
|
635
|
+
}
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
export function getSortOrder(sort = '-published_on', groupBy) {
|
|
614
639
|
// Determine the sort order
|
|
615
640
|
let sortOrder = '';
|
|
616
641
|
const isDesc = sort.startsWith('-');
|
|
@@ -633,69 +658,69 @@ export function getSortOrder(sort= '-published_on', groupBy)
|
|
|
633
658
|
}
|
|
634
659
|
|
|
635
660
|
/**
|
|
636
|
-
* Fetches all available filter options based on brand, filters, and various optional criteria.
|
|
637
|
-
*
|
|
638
|
-
* This function constructs a query to retrieve the total number of results and filter options such as difficulty, instrument type, and genre.
|
|
639
|
-
* The filter options are dynamically generated based on the provided filters, style, artist, and content type.
|
|
640
|
-
* If a coachId is provided, the content type must be 'coach-lessons'.
|
|
641
|
-
*
|
|
642
|
-
* @param {string} brand - Brand to filter.
|
|
643
|
-
* @param {string[]} filters - Key-value pairs to filter the query.
|
|
644
|
-
* @param {string} [style] - Optional style/genre filter.
|
|
645
|
-
* @param {string} [artist] - Optional artist name filter.
|
|
646
|
-
* @param {string} contentType - Content type (e.g., 'song', 'lesson').
|
|
647
|
-
* @param {string} [term] - Optional search term for title, album, artist, or genre.
|
|
648
|
-
* @param {Array<string>} [progressIds] - Optional array of progress IDs to filter by.
|
|
649
|
-
* @param {string} [coachId] - Optional coach ID (only valid if contentType is 'coach-lessons').
|
|
650
|
-
* @param {boolean} [includeTabs=false] - Whether to include tabs in the returned metadata.
|
|
651
|
-
* @returns {Promise<Object>} - The filter options and metadata.
|
|
652
|
-
* @throws {Error} If coachId is provided but contentType isn't 'coach-lessons'.
|
|
653
|
-
*
|
|
654
|
-
* @example
|
|
655
|
-
* // Fetch filter options for 'song' content type:
|
|
656
|
-
* fetchAllFilterOptions('myBrand', [], 'Rock', 'John Doe', 'song', 'Love')
|
|
657
|
-
* .then(options => console.log(options))
|
|
658
|
-
* .catch(error => console.error(error));
|
|
659
|
-
*
|
|
660
|
-
* @example
|
|
661
|
-
* // Fetch filter options for a coach's lessons with coachId:
|
|
662
|
-
* fetchAllFilterOptions('myBrand', [], 'Rock', 'John Doe', 'coach-lessons', 'Love', undefined, '123')
|
|
663
|
-
* .then(options => console.log(options))
|
|
664
|
-
* .catch(error => console.error(error));
|
|
665
|
-
*/
|
|
661
|
+
* Fetches all available filter options based on brand, filters, and various optional criteria.
|
|
662
|
+
*
|
|
663
|
+
* This function constructs a query to retrieve the total number of results and filter options such as difficulty, instrument type, and genre.
|
|
664
|
+
* The filter options are dynamically generated based on the provided filters, style, artist, and content type.
|
|
665
|
+
* If a coachId is provided, the content type must be 'coach-lessons'.
|
|
666
|
+
*
|
|
667
|
+
* @param {string} brand - Brand to filter.
|
|
668
|
+
* @param {string[]} filters - Key-value pairs to filter the query.
|
|
669
|
+
* @param {string} [style] - Optional style/genre filter.
|
|
670
|
+
* @param {string} [artist] - Optional artist name filter.
|
|
671
|
+
* @param {string} contentType - Content type (e.g., 'song', 'lesson').
|
|
672
|
+
* @param {string} [term] - Optional search term for title, album, artist, or genre.
|
|
673
|
+
* @param {Array<string>} [progressIds] - Optional array of progress IDs to filter by.
|
|
674
|
+
* @param {string} [coachId] - Optional coach ID (only valid if contentType is 'coach-lessons').
|
|
675
|
+
* @param {boolean} [includeTabs=false] - Whether to include tabs in the returned metadata.
|
|
676
|
+
* @returns {Promise<Object>} - The filter options and metadata.
|
|
677
|
+
* @throws {Error} If coachId is provided but contentType isn't 'coach-lessons'.
|
|
678
|
+
*
|
|
679
|
+
* @example
|
|
680
|
+
* // Fetch filter options for 'song' content type:
|
|
681
|
+
* fetchAllFilterOptions('myBrand', [], 'Rock', 'John Doe', 'song', 'Love')
|
|
682
|
+
* .then(options => console.log(options))
|
|
683
|
+
* .catch(error => console.error(error));
|
|
684
|
+
*
|
|
685
|
+
* @example
|
|
686
|
+
* // Fetch filter options for a coach's lessons with coachId:
|
|
687
|
+
* fetchAllFilterOptions('myBrand', [], 'Rock', 'John Doe', 'coach-lessons', 'Love', undefined, '123')
|
|
688
|
+
* .then(options => console.log(options))
|
|
689
|
+
* .catch(error => console.error(error));
|
|
690
|
+
*/
|
|
666
691
|
export async function fetchAllFilterOptions(
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
692
|
+
brand,
|
|
693
|
+
filters = [],
|
|
694
|
+
style,
|
|
695
|
+
artist,
|
|
696
|
+
contentType,
|
|
697
|
+
term,
|
|
698
|
+
progressIds,
|
|
699
|
+
coachId,
|
|
700
|
+
includeTabs = false,
|
|
676
701
|
) {
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
702
|
+
if (coachId && contentType !== 'coach-lessons') {
|
|
703
|
+
throw new Error(`Invalid contentType: '${contentType}' for coachId. It must be 'coach-lessons'.`);
|
|
704
|
+
}
|
|
680
705
|
|
|
681
|
-
|
|
682
|
-
|
|
706
|
+
const includedFieldsFilter = filters?.length ? filtersToGroq(filters) : undefined;
|
|
707
|
+
const progressFilter = progressIds ? `&& railcontent_id in [${progressIds.join(',')}]` : "";
|
|
683
708
|
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
709
|
+
const constructCommonFilter = (excludeFilter) => {
|
|
710
|
+
const filterWithoutOption = excludeFilter ? filtersToGroq(filters, excludeFilter) : includedFieldsFilter;
|
|
711
|
+
return coachId
|
|
712
|
+
? `brand == '${brand}' && references(*[_type=='instructor' && railcontent_id == ${coachId}]._id) ${filterWithoutOption || ''}`
|
|
713
|
+
: `_type == '${contentType}' && brand == "${brand}"${style && excludeFilter !== "style" ? ` && '${style}' in genre[]->name` : ''}${artist && excludeFilter !== "artist" ? ` && artist->name == '${artist}'` : ''} ${progressFilter} ${filterWithoutOption || ''}`;
|
|
714
|
+
};
|
|
690
715
|
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
716
|
+
const metaData = processMetadata(brand, contentType, true);
|
|
717
|
+
const allowableFilters = metaData?.allowableFilters || [];
|
|
718
|
+
const tabs = metaData?.tabs || [];
|
|
719
|
+
const catalogName = metaData?.shortname || metaData?.name;
|
|
695
720
|
|
|
696
|
-
|
|
721
|
+
const dynamicFilterOptions = allowableFilters.map(filter => getFilterOptions(filter, constructCommonFilter(filter), contentType, brand)).join(' ');
|
|
697
722
|
|
|
698
|
-
|
|
723
|
+
const query = `
|
|
699
724
|
{
|
|
700
725
|
"meta": {
|
|
701
726
|
"totalResults": count(*[${constructCommonFilter()}
|
|
@@ -706,28 +731,28 @@ export async function fetchAllFilterOptions(
|
|
|
706
731
|
}
|
|
707
732
|
}`;
|
|
708
733
|
|
|
709
|
-
|
|
734
|
+
const results = await fetchSanity(query, true, {processNeedAccess: false});
|
|
710
735
|
|
|
711
|
-
|
|
736
|
+
return includeTabs ? {...results, tabs, catalogName} : results;
|
|
712
737
|
}
|
|
713
738
|
|
|
714
739
|
|
|
715
740
|
/**
|
|
716
|
-
* Fetch children content by Railcontent ID.
|
|
717
|
-
* @param {string} railcontentId - The Railcontent ID of the parent content.
|
|
718
|
-
* @param {string} [contentType] - The content type the IDs to add needed fields to the response.
|
|
719
|
-
* @returns {Promise<Array<Object>|null>} - The fetched children content data or [] if not found.
|
|
720
|
-
*/
|
|
741
|
+
* Fetch children content by Railcontent ID.
|
|
742
|
+
* @param {string} railcontentId - The Railcontent ID of the parent content.
|
|
743
|
+
* @param {string} [contentType] - The content type the IDs to add needed fields to the response.
|
|
744
|
+
* @returns {Promise<Array<Object>|null>} - The fetched children content data or [] if not found.
|
|
745
|
+
*/
|
|
721
746
|
export async function fetchChildren(railcontentId, contentType) {
|
|
722
|
-
|
|
747
|
+
const query = `*[railcontent_id == ${railcontentId}]{
|
|
723
748
|
title,
|
|
724
749
|
|
|
725
750
|
'children': child[]->{
|
|
726
751
|
${getFieldsForContentType(contentType)}
|
|
727
752
|
},
|
|
728
753
|
}[0..1]`;
|
|
729
|
-
|
|
730
|
-
|
|
754
|
+
let parent = await fetchSanity(query, false);
|
|
755
|
+
return parent['children'] ?? [];
|
|
731
756
|
}
|
|
732
757
|
|
|
733
758
|
/**
|
|
@@ -748,44 +773,44 @@ export async function fetchParentByRailContentId(railcontentId) {
|
|
|
748
773
|
}
|
|
749
774
|
|
|
750
775
|
/**
|
|
751
|
-
* Fetch the Methods (learning-paths) for a specific brand.
|
|
752
|
-
* @param {string} brand - The brand for which to fetch methods.
|
|
753
|
-
* @returns {Promise<Object|null>} - The fetched methods data or null if not found.
|
|
754
|
-
*/
|
|
776
|
+
* Fetch the Methods (learning-paths) for a specific brand.
|
|
777
|
+
* @param {string} brand - The brand for which to fetch methods.
|
|
778
|
+
* @returns {Promise<Object|null>} - The fetched methods data or null if not found.
|
|
779
|
+
*/
|
|
755
780
|
export async function fetchMethods(brand) {
|
|
756
781
|
const query = `*[_type == 'learning-path' && brand == '${brand}'] {
|
|
757
|
-
${
|
|
782
|
+
${getFieldsForContentType()}
|
|
758
783
|
} | order(published_on asc)`
|
|
759
|
-
|
|
784
|
+
return fetchSanity(query, true);
|
|
760
785
|
}
|
|
761
786
|
|
|
762
787
|
/**
|
|
763
|
-
* Fetch the Foundations 2019.
|
|
764
|
-
* @param {string} slug - The slug of the method.
|
|
765
|
-
* @returns {Promise<Object|null>} - The fetched foundation data or null if not found.
|
|
766
|
-
*/
|
|
788
|
+
* Fetch the Foundations 2019.
|
|
789
|
+
* @param {string} slug - The slug of the method.
|
|
790
|
+
* @returns {Promise<Object|null>} - The fetched foundation data or null if not found.
|
|
791
|
+
*/
|
|
767
792
|
export async function fetchFoundation(slug) {
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
return fetchSanity(query, false);
|
|
793
|
+
const filterParams = {};
|
|
794
|
+
const query = await buildQuery(
|
|
795
|
+
`_type == 'foundation' && slug.current == "${slug}"`,
|
|
796
|
+
filterParams,
|
|
797
|
+
getFieldsForContentType('foundation'),
|
|
798
|
+
{
|
|
799
|
+
sortOrder: 'published_on asc',
|
|
800
|
+
isSingle: true,
|
|
801
|
+
}
|
|
802
|
+
);
|
|
803
|
+
return fetchSanity(query, false);
|
|
779
804
|
}
|
|
780
805
|
|
|
781
806
|
/**
|
|
782
|
-
* Fetch the Method (learning-paths) for a specific brand.
|
|
783
|
-
* @param {string} brand - The brand for which to fetch methods.
|
|
784
|
-
* @param {string} slug - The slug of the method.
|
|
785
|
-
* @returns {Promise<Object|null>} - The fetched methods data or null if not found.
|
|
786
|
-
*/
|
|
807
|
+
* Fetch the Method (learning-paths) for a specific brand.
|
|
808
|
+
* @param {string} brand - The brand for which to fetch methods.
|
|
809
|
+
* @param {string} slug - The slug of the method.
|
|
810
|
+
* @returns {Promise<Object|null>} - The fetched methods data or null if not found.
|
|
811
|
+
*/
|
|
787
812
|
export async function fetchMethod(brand, slug) {
|
|
788
|
-
|
|
813
|
+
const query = `*[_type == 'learning-path' && brand == "${brand}" && slug.current == "${slug}"] {
|
|
789
814
|
"description": ${descriptionField},
|
|
790
815
|
"instructors":instructor[]->name,
|
|
791
816
|
published_on,
|
|
@@ -815,16 +840,16 @@ export async function fetchMethod(brand, slug) {
|
|
|
815
840
|
xp,
|
|
816
841
|
}
|
|
817
842
|
} | order(published_on asc)`
|
|
818
|
-
return fetchSanity(query, false);
|
|
843
|
+
return fetchSanity(query, false);
|
|
819
844
|
}
|
|
820
845
|
|
|
821
846
|
/**
|
|
822
|
-
* Fetch the child courses for a specific method by Railcontent ID.
|
|
823
|
-
* @param {string} railcontentId - The Railcontent ID of the current lesson.
|
|
824
|
-
* @returns {Promise<Object|null>} - The fetched next lesson data or null if not found.
|
|
825
|
-
*/
|
|
847
|
+
* Fetch the child courses for a specific method by Railcontent ID.
|
|
848
|
+
* @param {string} railcontentId - The Railcontent ID of the current lesson.
|
|
849
|
+
* @returns {Promise<Object|null>} - The fetched next lesson data or null if not found.
|
|
850
|
+
*/
|
|
826
851
|
export async function fetchMethodChildren(railcontentId) {
|
|
827
|
-
|
|
852
|
+
const query = `*[railcontent_id == ${railcontentId}]{
|
|
828
853
|
child_count,
|
|
829
854
|
"id": railcontent_id,
|
|
830
855
|
"description": ${descriptionField},
|
|
@@ -835,20 +860,20 @@ export async function fetchMethodChildren(railcontentId) {
|
|
|
835
860
|
${getFieldsForContentType('method')}
|
|
836
861
|
},
|
|
837
862
|
}[0..1]`;
|
|
838
|
-
|
|
863
|
+
return fetchSanity(query, true);
|
|
839
864
|
}
|
|
840
865
|
|
|
841
866
|
/**
|
|
842
|
-
* Fetch the next lesson for a specific method by Railcontent ID.
|
|
843
|
-
* @param {string} railcontentId - The Railcontent ID of the current lesson.
|
|
867
|
+
* Fetch the next lesson for a specific method by Railcontent ID.
|
|
868
|
+
* @param {string} railcontentId - The Railcontent ID of the current lesson.
|
|
844
869
|
* @param {string} methodId - The RailcontentID of the method
|
|
845
|
-
* @returns {Promise<Object|null>} - The fetched next lesson data or null if not found.
|
|
846
|
-
*/
|
|
870
|
+
* @returns {Promise<Object|null>} - The fetched next lesson data or null if not found.
|
|
871
|
+
*/
|
|
847
872
|
export async function fetchMethodNextLesson(railcontentId, methodId) {
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
873
|
+
const sortedChildren = await fetchMethodChildrenIds(methodId);
|
|
874
|
+
const index = sortedChildren.indexOf(railcontentId);
|
|
875
|
+
const childIndex = sortedChildren[index + 1];
|
|
876
|
+
return childIndex ? await fetchByRailContentId(childIndex) : null;
|
|
852
877
|
}
|
|
853
878
|
|
|
854
879
|
/**
|
|
@@ -865,18 +890,22 @@ export async function fetchMethodPreviousNextLesson(railcontentId, methodId) {
|
|
|
865
890
|
const sortedChildren = await fetchMethodChildrenIds(methodId);
|
|
866
891
|
const index = sortedChildren.indexOf(Number(railcontentId));
|
|
867
892
|
let nextId = sortedChildren[index + 1];
|
|
868
|
-
let previousId = sortedChildren[index
|
|
893
|
+
let previousId = sortedChildren[index - 1];
|
|
869
894
|
let nextPrev = await fetchByRailContentIds([nextId, previousId]);
|
|
870
|
-
const nextLesson = nextPrev.find((elem) => {
|
|
871
|
-
|
|
895
|
+
const nextLesson = nextPrev.find((elem) => {
|
|
896
|
+
return elem['id'] === nextId
|
|
897
|
+
});
|
|
898
|
+
const prevLesson = nextPrev.find((elem) => {
|
|
899
|
+
return elem['id'] === previousId
|
|
900
|
+
});
|
|
872
901
|
return {nextLesson, prevLesson};
|
|
873
902
|
}
|
|
874
903
|
|
|
875
904
|
/**
|
|
876
|
-
* Fetch all children of a specific method by Railcontent ID.
|
|
877
|
-
* @param {string} railcontentId - The Railcontent ID of the method.
|
|
878
|
-
* @returns {Promise<Array<Object>|null>} - The fetched children data or null if not found.
|
|
879
|
-
*/
|
|
905
|
+
* Fetch all children of a specific method by Railcontent ID.
|
|
906
|
+
* @param {string} railcontentId - The Railcontent ID of the method.
|
|
907
|
+
* @returns {Promise<Array<Object>|null>} - The fetched children data or null if not found.
|
|
908
|
+
*/
|
|
880
909
|
export async function fetchMethodChildrenIds(railcontentId) {
|
|
881
910
|
const query = `*[ railcontent_id == ${railcontentId}]{
|
|
882
911
|
'children': child[]-> {
|
|
@@ -896,25 +925,24 @@ export async function fetchMethodChildrenIds(railcontentId) {
|
|
|
896
925
|
return getChildrenToDepth(allChildren, 4);
|
|
897
926
|
}
|
|
898
927
|
|
|
899
|
-
function getChildrenToDepth(parent, depth = 1)
|
|
900
|
-
{
|
|
928
|
+
function getChildrenToDepth(parent, depth = 1) {
|
|
901
929
|
let allChildrenIds = [];
|
|
902
930
|
if (parent && parent['children'] && depth > 0) {
|
|
903
931
|
parent['children'].forEach((child) => {
|
|
904
|
-
if(!child['children']) {
|
|
932
|
+
if (!child['children']) {
|
|
905
933
|
allChildrenIds.push(child['id']);
|
|
906
934
|
}
|
|
907
|
-
allChildrenIds = allChildrenIds.concat(getChildrenToDepth(child, depth-1));
|
|
935
|
+
allChildrenIds = allChildrenIds.concat(getChildrenToDepth(child, depth - 1));
|
|
908
936
|
})
|
|
909
937
|
}
|
|
910
938
|
return allChildrenIds;
|
|
911
939
|
}
|
|
912
940
|
|
|
913
941
|
/**
|
|
914
|
-
* Fetch the next and previous lessons for a specific lesson by Railcontent ID.
|
|
915
|
-
* @param {string} railcontentId - The Railcontent ID of the current lesson.
|
|
916
|
-
* @returns {Promise<Object|null>} - The fetched next and previous lesson data or null if found.
|
|
917
|
-
*/
|
|
942
|
+
* Fetch the next and previous lessons for a specific lesson by Railcontent ID.
|
|
943
|
+
* @param {string} railcontentId - The Railcontent ID of the current lesson.
|
|
944
|
+
* @returns {Promise<Object|null>} - The fetched next and previous lesson data or null if found.
|
|
945
|
+
*/
|
|
918
946
|
export async function fetchNextPreviousLesson(railcontentId) {
|
|
919
947
|
const document = await fetchLessonContent(railcontentId);
|
|
920
948
|
if (document.parent_content_data && document.parent_content_data.length > 0) {
|
|
@@ -997,7 +1025,7 @@ export async function fetchLessonContent(railContentId) {
|
|
|
997
1025
|
parent_content_data,
|
|
998
1026
|
sort,
|
|
999
1027
|
xp`;
|
|
1000
|
-
const query = buildQuery(
|
|
1028
|
+
const query = await buildQuery(
|
|
1001
1029
|
`railcontent_id == ${railContentId}`,
|
|
1002
1030
|
filterParams,
|
|
1003
1031
|
fields,
|
|
@@ -1005,15 +1033,15 @@ export async function fetchLessonContent(railContentId) {
|
|
|
1005
1033
|
isSingle: true,
|
|
1006
1034
|
}
|
|
1007
1035
|
);
|
|
1008
|
-
|
|
1036
|
+
return fetchSanity(query, false);
|
|
1009
1037
|
}
|
|
1010
1038
|
|
|
1011
1039
|
/**
|
|
1012
|
-
* Fetch related lessons for a specific lesson by RailContent ID and type.
|
|
1013
|
-
* @param {string} railContentId - The RailContent ID of the current lesson.
|
|
1014
|
-
* @param {string} brand - The current brand.
|
|
1015
|
-
* @returns {Promise<Array<Object>|null>} - The fetched related lessons data or null if not found.
|
|
1016
|
-
*/
|
|
1040
|
+
* Fetch related lessons for a specific lesson by RailContent ID and type.
|
|
1041
|
+
* @param {string} railContentId - The RailContent ID of the current lesson.
|
|
1042
|
+
* @param {string} brand - The current brand.
|
|
1043
|
+
* @returns {Promise<Array<Object>|null>} - The fetched related lessons data or null if not found.
|
|
1044
|
+
*/
|
|
1017
1045
|
export async function fetchRelatedLessons(railContentId, brand) {
|
|
1018
1046
|
const query = `*[railcontent_id == ${railContentId} && brand == "${brand}" && references(*[_type=='permission']._id)]{
|
|
1019
1047
|
_type, parent_type, railcontent_id,
|
|
@@ -1028,13 +1056,13 @@ export async function fetchRelatedLessons(railContentId, brand) {
|
|
|
1028
1056
|
}
|
|
1029
1057
|
|
|
1030
1058
|
/**
|
|
1031
|
-
* Fetch related method lessons for a specific lesson by RailContent ID and type.
|
|
1032
|
-
* @param {string} railContentId - The RailContent ID of the current lesson.
|
|
1033
|
-
* @param {string} brand - The current brand.
|
|
1034
|
-
* @returns {Promise<Array<Object>|null>} - The fetched related lessons
|
|
1035
|
-
*/
|
|
1059
|
+
* Fetch related method lessons for a specific lesson by RailContent ID and type.
|
|
1060
|
+
* @param {string} railContentId - The RailContent ID of the current lesson.
|
|
1061
|
+
* @param {string} brand - The current brand.
|
|
1062
|
+
* @returns {Promise<Array<Object>|null>} - The fetched related lessons
|
|
1063
|
+
*/
|
|
1036
1064
|
export async function fetchRelatedMethodLessons(railContentId, brand) {
|
|
1037
|
-
|
|
1065
|
+
const query = `*[railcontent_id == ${railContentId} && brand == "${brand}"]{
|
|
1038
1066
|
"id":_id,
|
|
1039
1067
|
"related_lessons": *[references(^._id)][0].child[]->{
|
|
1040
1068
|
"id": railcontent_id,
|
|
@@ -1048,57 +1076,57 @@ export async function fetchRelatedMethodLessons(railContentId, brand) {
|
|
|
1048
1076
|
}
|
|
1049
1077
|
}
|
|
1050
1078
|
}`
|
|
1051
|
-
|
|
1079
|
+
return fetchSanity(query, false);
|
|
1052
1080
|
}
|
|
1053
1081
|
|
|
1054
1082
|
/**
|
|
1055
|
-
* Fetch all packs.
|
|
1056
|
-
* @param {string} brand - The brand for which to fetch packs.
|
|
1057
|
-
* @param {string} [searchTerm=""] - The search term to filter packs.
|
|
1058
|
-
* @param {string} [sort="-published_on"] - The field to sort the packs by.
|
|
1059
|
-
* @param {number} [params.page=1] - The page number for pagination.
|
|
1060
|
-
* @param {number} [params.limit=10] - The number of items per page.
|
|
1061
|
-
* @returns {Promise<Array<Object>|null>} - The fetched pack content data or null if not found.
|
|
1062
|
-
*/
|
|
1083
|
+
* Fetch all packs.
|
|
1084
|
+
* @param {string} brand - The brand for which to fetch packs.
|
|
1085
|
+
* @param {string} [searchTerm=""] - The search term to filter packs.
|
|
1086
|
+
* @param {string} [sort="-published_on"] - The field to sort the packs by.
|
|
1087
|
+
* @param {number} [params.page=1] - The page number for pagination.
|
|
1088
|
+
* @param {number} [params.limit=10] - The number of items per page.
|
|
1089
|
+
* @returns {Promise<Array<Object>|null>} - The fetched pack content data or null if not found.
|
|
1090
|
+
*/
|
|
1063
1091
|
export async function fetchAllPacks(brand, sort = "-published_on", searchTerm = "", page = 1, limit = 10) {
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1092
|
+
const sortOrder = getSortOrder(sort);
|
|
1093
|
+
const filter = `_type == 'pack' && brand == '${brand}' && title match "${searchTerm}*"`
|
|
1094
|
+
const filterParams = {};
|
|
1095
|
+
const fields = getFieldsForContentType('pack');
|
|
1096
|
+
const start = (page - 1) * limit;
|
|
1097
|
+
const end = start + limit;
|
|
1098
|
+
|
|
1099
|
+
const query = await buildQuery(
|
|
1100
|
+
filter,
|
|
1101
|
+
filterParams,
|
|
1102
|
+
getFieldsForContentType('pack'),
|
|
1103
|
+
{
|
|
1104
|
+
logo_image_url: 'logo_image_url.asset->url',
|
|
1105
|
+
sortOrder: sortOrder,
|
|
1106
|
+
start,
|
|
1107
|
+
end
|
|
1108
|
+
}
|
|
1109
|
+
);
|
|
1110
|
+
return fetchSanity(query, true);
|
|
1083
1111
|
}
|
|
1084
1112
|
|
|
1085
1113
|
/**
|
|
1086
|
-
* Fetch all content for a specific pack by Railcontent ID.
|
|
1087
|
-
* @param {string} railcontentId - The Railcontent ID of the pack.
|
|
1088
|
-
* @returns {Promise<Array<Object>|null>} - The fetched pack content data or null if not found.
|
|
1089
|
-
*/
|
|
1114
|
+
* Fetch all content for a specific pack by Railcontent ID.
|
|
1115
|
+
* @param {string} railcontentId - The Railcontent ID of the pack.
|
|
1116
|
+
* @returns {Promise<Array<Object>|null>} - The fetched pack content data or null if not found.
|
|
1117
|
+
*/
|
|
1090
1118
|
export async function fetchPackAll(railcontentId) {
|
|
1091
|
-
|
|
1119
|
+
return fetchByRailContentId(railcontentId, 'pack');
|
|
1092
1120
|
}
|
|
1093
1121
|
|
|
1094
1122
|
export async function fetchLiveEvent(brand) {
|
|
1095
1123
|
//calendarIDs taken from addevent.php
|
|
1096
1124
|
// TODO import instructor calendars to Sanity
|
|
1097
1125
|
let defaultCalendarID = '';
|
|
1098
|
-
switch(brand) {
|
|
1126
|
+
switch (brand) {
|
|
1099
1127
|
case ('drumeo'):
|
|
1100
1128
|
defaultCalendarID = 'GP142387';
|
|
1101
|
-
|
|
1129
|
+
break;
|
|
1102
1130
|
case ('pianote'):
|
|
1103
1131
|
defaultCalendarID = 'be142408';
|
|
1104
1132
|
break;
|
|
@@ -1148,7 +1176,7 @@ export async function fetchLiveEvent(brand) {
|
|
|
1148
1176
|
* .catch(error => console.error(error));
|
|
1149
1177
|
*/
|
|
1150
1178
|
export async function fetchPackChildren(railcontentId) {
|
|
1151
|
-
|
|
1179
|
+
return fetchChildren(railcontentId, 'pack-children');
|
|
1152
1180
|
}
|
|
1153
1181
|
|
|
1154
1182
|
/**
|
|
@@ -1162,10 +1190,10 @@ export async function fetchPackChildren(railcontentId) {
|
|
|
1162
1190
|
* .catch(error => console.error(error));
|
|
1163
1191
|
*/
|
|
1164
1192
|
export async function fetchPackData(id) {
|
|
1165
|
-
|
|
1193
|
+
const query = `*[railcontent_id == ${id}]{
|
|
1166
1194
|
${getFieldsForContentType("pack")}
|
|
1167
1195
|
} [0...1]`;
|
|
1168
|
-
|
|
1196
|
+
return fetchSanity(query, false);
|
|
1169
1197
|
}
|
|
1170
1198
|
|
|
1171
1199
|
/**
|
|
@@ -1179,11 +1207,11 @@ export async function fetchPackData(id) {
|
|
|
1179
1207
|
* .catch(error => console.error(error));
|
|
1180
1208
|
*/
|
|
1181
1209
|
export async function fetchChallengeOverview(id) {
|
|
1182
|
-
|
|
1183
|
-
|
|
1210
|
+
// WIP
|
|
1211
|
+
const query = `*[railcontent_id == ${id}]{
|
|
1184
1212
|
${getFieldsForContentType("challenge")}
|
|
1185
1213
|
} [0...1]`;
|
|
1186
|
-
|
|
1214
|
+
return fetchSanity(query, false);
|
|
1187
1215
|
}
|
|
1188
1216
|
|
|
1189
1217
|
/**
|
|
@@ -1204,32 +1232,32 @@ export async function fetchChallengeOverview(id) {
|
|
|
1204
1232
|
* .catch(error => console.error(error));
|
|
1205
1233
|
*/
|
|
1206
1234
|
export async function fetchCoachLessons(brand, id, {
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1235
|
+
sortOrder = '-published_on',
|
|
1236
|
+
searchTerm = '',
|
|
1237
|
+
page = 1,
|
|
1238
|
+
limit = 20,
|
|
1239
|
+
includedFields = [],
|
|
1212
1240
|
} = {}) {
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1241
|
+
const fieldsString = getFieldsForContentType();
|
|
1242
|
+
const start = (page - 1) * limit;
|
|
1243
|
+
const end = start + limit;
|
|
1244
|
+
const searchFilter = searchTerm ? `&& title match "${searchTerm}*"` : ''
|
|
1245
|
+
const includedFieldsFilter = includedFields.length > 0
|
|
1218
1246
|
? filtersToGroq(includedFields)
|
|
1219
1247
|
: "";
|
|
1220
|
-
|
|
1248
|
+
const filter = `brand == '${brand}' ${searchFilter} ${includedFieldsFilter} && references(*[_type=='instructor' && railcontent_id == ${id}]._id)`;
|
|
1221
1249
|
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1250
|
+
sortOrder = getSortOrder(sortOrder);
|
|
1251
|
+
const query = buildEntityAndTotalQuery(
|
|
1252
|
+
filter,
|
|
1253
|
+
fieldsString,
|
|
1254
|
+
{
|
|
1255
|
+
sortOrder: sortOrder,
|
|
1256
|
+
start: start,
|
|
1257
|
+
end: end,
|
|
1258
|
+
},
|
|
1259
|
+
);
|
|
1260
|
+
return fetchSanity(query, true);
|
|
1233
1261
|
}
|
|
1234
1262
|
|
|
1235
1263
|
/**
|
|
@@ -1243,7 +1271,7 @@ export async function fetchCoachLessons(brand, id, {
|
|
|
1243
1271
|
* .catch(error => console.error(error));
|
|
1244
1272
|
*/
|
|
1245
1273
|
export async function fetchCourseOverview(id) {
|
|
1246
|
-
|
|
1274
|
+
return fetchByRailContentId(id, 'course');
|
|
1247
1275
|
}
|
|
1248
1276
|
|
|
1249
1277
|
/**
|
|
@@ -1257,21 +1285,21 @@ export async function fetchCourseOverview(id) {
|
|
|
1257
1285
|
* .catch(error => console.error(error));
|
|
1258
1286
|
*/
|
|
1259
1287
|
export async function fetchParentForDownload(id) {
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1288
|
+
const query = buildRawQuery(
|
|
1289
|
+
`railcontent_id == ${id}`,
|
|
1290
|
+
getFieldsForContentType('parent-download'),
|
|
1291
|
+
{
|
|
1292
|
+
isSingle: true,
|
|
1293
|
+
},
|
|
1294
|
+
);
|
|
1267
1295
|
|
|
1268
|
-
|
|
1296
|
+
return fetchSanity(query, false);
|
|
1269
1297
|
}
|
|
1270
1298
|
|
|
1271
1299
|
/**
|
|
1272
1300
|
* Fetch the data needed for the coach screen.
|
|
1273
1301
|
* @param {string} id - The Railcontent ID of the coach
|
|
1274
|
-
*
|
|
1302
|
+
*
|
|
1275
1303
|
* @returns {Promise<Object|null>} - The lessons for the instructor or null if not found.
|
|
1276
1304
|
*
|
|
1277
1305
|
* @example
|
|
@@ -1280,30 +1308,30 @@ export async function fetchParentForDownload(id) {
|
|
|
1280
1308
|
* .catch(error => console.error(error));
|
|
1281
1309
|
*/
|
|
1282
1310
|
export async function fetchByReference(brand, {
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1311
|
+
sortOrder = '-published_on',
|
|
1312
|
+
searchTerm = '',
|
|
1313
|
+
page = 1,
|
|
1314
|
+
limit = 20,
|
|
1315
|
+
includedFields = [],
|
|
1288
1316
|
} = {}) {
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1317
|
+
const fieldsString = getFieldsForContentType();
|
|
1318
|
+
const start = (page - 1) * limit;
|
|
1319
|
+
const end = start + limit;
|
|
1320
|
+
const searchFilter = searchTerm ? `&& title match "${searchTerm}*"` : '';
|
|
1321
|
+
const includedFieldsFilter = includedFields.length > 0
|
|
1294
1322
|
? includedFields.join(' && ')
|
|
1295
1323
|
: "";
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1324
|
+
const filter = `brand == '${brand}' ${searchFilter} && references(*[${includedFieldsFilter}]._id)`;
|
|
1325
|
+
const query = buildEntityAndTotalQuery(
|
|
1326
|
+
filter,
|
|
1327
|
+
fieldsString,
|
|
1328
|
+
{
|
|
1329
|
+
sortOrder: getSortOrder(sortOrder),
|
|
1330
|
+
start: start,
|
|
1331
|
+
end: end,
|
|
1332
|
+
},
|
|
1333
|
+
);
|
|
1334
|
+
return fetchSanity(query, true);
|
|
1307
1335
|
}
|
|
1308
1336
|
|
|
1309
1337
|
/**
|
|
@@ -1326,28 +1354,28 @@ export async function fetchByReference(brand, {
|
|
|
1326
1354
|
* .catch(error => console.error(error));
|
|
1327
1355
|
*/
|
|
1328
1356
|
export async function fetchArtistLessons(brand, name, contentType, {
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1357
|
+
sort = '-published_on',
|
|
1358
|
+
searchTerm = '',
|
|
1359
|
+
page = 1,
|
|
1360
|
+
limit = 10,
|
|
1361
|
+
includedFields = [],
|
|
1362
|
+
progressIds = undefined,
|
|
1335
1363
|
} = {}) {
|
|
1336
1364
|
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1365
|
+
const fieldsString = DEFAULT_FIELDS.join(',');
|
|
1366
|
+
const start = (page - 1) * limit;
|
|
1367
|
+
const end = start + limit;
|
|
1368
|
+
const searchFilter = searchTerm ? `&& title match "${searchTerm}*"` : ''
|
|
1369
|
+
const sortOrder = getSortOrder(sort);
|
|
1370
|
+
const addType = contentType && Array.isArray(contentType) ? `_type in ['${contentType.join("', '")}'] &&` : contentType ? `_type == '${contentType}' && ` : ''
|
|
1371
|
+
const includedFieldsFilter = includedFields.length > 0
|
|
1372
|
+
? filtersToGroq(includedFields)
|
|
1373
|
+
: "";
|
|
1346
1374
|
|
|
1347
|
-
|
|
1348
|
-
|
|
1375
|
+
// limits the results to supplied progressIds for started & completed filters
|
|
1376
|
+
const progressFilter = progressIds !== undefined ? `&& railcontent_id in [${progressIds.join(',')}]` : "";
|
|
1349
1377
|
|
|
1350
|
-
|
|
1378
|
+
const query = `{
|
|
1351
1379
|
"entity":
|
|
1352
1380
|
*[_type == 'artist' && name == '${name}']
|
|
1353
1381
|
{'type': _type, name, 'thumbnail_url':thumbnail_url.asset->url,
|
|
@@ -1356,7 +1384,7 @@ export async function fetchArtistLessons(brand, name, contentType, {
|
|
|
1356
1384
|
[${start}...${end}]}
|
|
1357
1385
|
|order(${sortOrder})
|
|
1358
1386
|
}`;
|
|
1359
|
-
|
|
1387
|
+
return fetchSanity(query, true);
|
|
1360
1388
|
}
|
|
1361
1389
|
|
|
1362
1390
|
/**
|
|
@@ -1378,26 +1406,26 @@ export async function fetchArtistLessons(brand, name, contentType, {
|
|
|
1378
1406
|
* .catch(error => console.error(error));
|
|
1379
1407
|
*/
|
|
1380
1408
|
export async function fetchGenreLessons(brand, name, contentType, {
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1409
|
+
sort = '-published_on',
|
|
1410
|
+
searchTerm = '',
|
|
1411
|
+
page = 1,
|
|
1412
|
+
limit = 10,
|
|
1413
|
+
includedFields = [],
|
|
1414
|
+
progressIds = undefined,
|
|
1387
1415
|
} = {}) {
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1416
|
+
const fieldsString = DEFAULT_FIELDS.join(',');
|
|
1417
|
+
const start = (page - 1) * limit;
|
|
1418
|
+
const end = start + limit;
|
|
1419
|
+
const searchFilter = searchTerm ? `&& title match "${searchTerm}*"` : ''
|
|
1420
|
+
const sortOrder = getSortOrder(sort);
|
|
1421
|
+
const addType = contentType ? `_type == '${contentType}' && ` : ''
|
|
1422
|
+
const includedFieldsFilter = includedFields.length > 0
|
|
1423
|
+
? filtersToGroq(includedFields)
|
|
1424
|
+
: "";
|
|
1425
|
+
// limits the results to supplied progressIds for started & completed filters
|
|
1426
|
+
const progressFilter = progressIds !== undefined ? `&& railcontent_id in [${progressIds.join(',')}]` : "";
|
|
1427
|
+
|
|
1428
|
+
const query = `{
|
|
1401
1429
|
"entity":
|
|
1402
1430
|
*[_type == 'genre' && name == '${name}']
|
|
1403
1431
|
{'type': _type, name, 'thumbnail_url':thumbnail_url.asset->url,
|
|
@@ -1406,7 +1434,7 @@ export async function fetchGenreLessons(brand, name, contentType, {
|
|
|
1406
1434
|
[${start}...${end}]}
|
|
1407
1435
|
|order(${sortOrder})
|
|
1408
1436
|
}`;
|
|
1409
|
-
|
|
1437
|
+
return fetchSanity(query, true);
|
|
1410
1438
|
}
|
|
1411
1439
|
|
|
1412
1440
|
export async function fetchTopLevelParentId(railcontentId) {
|
|
@@ -1442,18 +1470,22 @@ export async function fetchHierarchy(railcontentId) {
|
|
|
1442
1470
|
let topLevelId = await fetchTopLevelParentId(railcontentId);
|
|
1443
1471
|
const query = `*[railcontent_id == ${topLevelId}]{
|
|
1444
1472
|
railcontent_id,
|
|
1473
|
+
'assignments': assignment[]{railcontent_id},
|
|
1445
1474
|
'children': child[]->{
|
|
1446
1475
|
railcontent_id,
|
|
1476
|
+
'assignments': assignment[]{railcontent_id},
|
|
1447
1477
|
'children': child[]->{
|
|
1448
1478
|
railcontent_id,
|
|
1479
|
+
'assignments': assignment[]{railcontent_id},
|
|
1449
1480
|
'children': child[]->{
|
|
1450
1481
|
railcontent_id,
|
|
1482
|
+
'assignments': assignment[]{railcontent_id},
|
|
1451
1483
|
'children': child[]->{
|
|
1452
|
-
railcontent_id,
|
|
1484
|
+
railcontent_id,
|
|
1453
1485
|
}
|
|
1454
1486
|
}
|
|
1455
1487
|
}
|
|
1456
|
-
}
|
|
1488
|
+
},
|
|
1457
1489
|
}`;
|
|
1458
1490
|
let response = await fetchSanity(query, false, {processNeedAccess: false});
|
|
1459
1491
|
if (!response) return null;
|
|
@@ -1465,9 +1497,11 @@ export async function fetchHierarchy(railcontentId) {
|
|
|
1465
1497
|
return data;
|
|
1466
1498
|
}
|
|
1467
1499
|
|
|
1500
|
+
|
|
1468
1501
|
function populateHierarchyLookups(currentLevel, data, parentId) {
|
|
1469
1502
|
let contentId = currentLevel['railcontent_id'];
|
|
1470
1503
|
let children = currentLevel['children'];
|
|
1504
|
+
|
|
1471
1505
|
data.parents[contentId] = parentId;
|
|
1472
1506
|
if (children) {
|
|
1473
1507
|
data.children[contentId] = children.map(child => child['railcontent_id']);
|
|
@@ -1477,8 +1511,64 @@ function populateHierarchyLookups(currentLevel, data, parentId) {
|
|
|
1477
1511
|
} else {
|
|
1478
1512
|
data.children[contentId] = [];
|
|
1479
1513
|
}
|
|
1514
|
+
|
|
1515
|
+
let assignments = currentLevel['assignments'];
|
|
1516
|
+
if (assignments) {
|
|
1517
|
+
let assignmentIds = assignments.map(assignment => assignment['railcontent_id']);
|
|
1518
|
+
data.children[contentId] = (data.children[contentId] ?? []).concat(assignmentIds);
|
|
1519
|
+
assignmentIds.forEach(assignmentId => {
|
|
1520
|
+
data.parents[assignmentId] = contentId;
|
|
1521
|
+
});
|
|
1522
|
+
}
|
|
1523
|
+
|
|
1480
1524
|
}
|
|
1481
1525
|
|
|
1526
|
+
/**
|
|
1527
|
+
* Fetch assignments for content
|
|
1528
|
+
*
|
|
1529
|
+
* @param {integer} contentId - List of ids get data for
|
|
1530
|
+
* @returns {Promise<array|null>} - A promise that resolves to an array containing the data
|
|
1531
|
+
*/
|
|
1532
|
+
export async function fetchAssignments(contentId) {
|
|
1533
|
+
const fields = `"id": railcontent_id,"assignments":assignment[]{"id": railcontent_id}`;
|
|
1534
|
+
const query = await buildQuery(`railcontent_id == ${contentId}`,
|
|
1535
|
+
{bypassPermissions: true},
|
|
1536
|
+
fields,
|
|
1537
|
+
{end: 100});
|
|
1538
|
+
let data = await fetchSanity(query, false);
|
|
1539
|
+
let mapped = [];
|
|
1540
|
+
data.assignments.forEach(function (content) {
|
|
1541
|
+
mapped.push(content.id);
|
|
1542
|
+
});
|
|
1543
|
+
return mapped;
|
|
1544
|
+
}
|
|
1545
|
+
|
|
1546
|
+
/**
|
|
1547
|
+
* Fetch data for comment mod page
|
|
1548
|
+
*
|
|
1549
|
+
* @param {array} ids - List of ids get data for
|
|
1550
|
+
* @returns {Promise<Object|null>} - A promise that resolves to an object containing the data
|
|
1551
|
+
*/
|
|
1552
|
+
export async function fetchCommentModContentData(ids) {
|
|
1553
|
+
const idsString = ids.join(',');
|
|
1554
|
+
const fields = `"id": railcontent_id, "type": _type, title, "url": web_url_path, "parent": *[^._id in child[]._ref]{"id": railcontent_id, title}`;
|
|
1555
|
+
const query = await buildQuery(`railcontent_id in [${idsString}]`,
|
|
1556
|
+
{bypassPermissions: true},
|
|
1557
|
+
fields,
|
|
1558
|
+
{end: 50});
|
|
1559
|
+
let data = await fetchSanity(query, true);
|
|
1560
|
+
let mapped = {};
|
|
1561
|
+
data.forEach(function (content) {
|
|
1562
|
+
mapped[content.id] = {
|
|
1563
|
+
"id": content.id,
|
|
1564
|
+
"type": content.type,
|
|
1565
|
+
"title": content.title,
|
|
1566
|
+
"url": content.url,
|
|
1567
|
+
"parentTitle": content.parent[0]?.title ?? null
|
|
1568
|
+
};
|
|
1569
|
+
});
|
|
1570
|
+
return mapped;
|
|
1571
|
+
}
|
|
1482
1572
|
|
|
1483
1573
|
|
|
1484
1574
|
/**
|
|
@@ -1498,83 +1588,89 @@ function populateHierarchyLookups(currentLevel, data, parentId) {
|
|
|
1498
1588
|
|
|
1499
1589
|
export async function fetchSanity(query,
|
|
1500
1590
|
isList,
|
|
1501
|
-
{
|
|
1502
|
-
|
|
1591
|
+
{
|
|
1592
|
+
customPostProcess = null,
|
|
1593
|
+
processNeedAccess = true,
|
|
1594
|
+
} = {}
|
|
1503
1595
|
) {
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1596
|
+
// Check the config object before proceeding
|
|
1597
|
+
if (!checkSanityConfig(globalConfig)) {
|
|
1598
|
+
return null;
|
|
1599
|
+
}
|
|
1600
|
+
|
|
1601
|
+
if (globalConfig.sanityConfig.debug) {
|
|
1602
|
+
console.log("fetchSanity Query:", query);
|
|
1603
|
+
}
|
|
1604
|
+
const perspective = globalConfig.sanityConfig.perspective ?? 'published';
|
|
1605
|
+
const encodedQuery = encodeURIComponent(query);
|
|
1606
|
+
const api = globalConfig.sanityConfig.useCachedAPI ? 'apicdn' : 'api';
|
|
1607
|
+
const url = `https://${globalConfig.sanityConfig.projectId}.${api}.sanity.io/v${globalConfig.sanityConfig.version}/data/query/${globalConfig.sanityConfig.dataset}?perspective=${perspective}&query=${encodedQuery}`;
|
|
1608
|
+
const headers = {
|
|
1609
|
+
'Authorization': `Bearer ${globalConfig.sanityConfig.token}`,
|
|
1610
|
+
'Content-Type': 'application/json'
|
|
1611
|
+
};
|
|
1612
|
+
|
|
1613
|
+
try {
|
|
1614
|
+
let promisesResult = await Promise.all([
|
|
1615
|
+
fetch(url, {headers}),
|
|
1616
|
+
processNeedAccess ? fetchUserPermissions() : null
|
|
1617
|
+
]);
|
|
1618
|
+
const response = promisesResult[0];
|
|
1619
|
+
const userPermissions = promisesResult[1]?.permissions;
|
|
1620
|
+
|
|
1621
|
+
if (!response.ok) {
|
|
1622
|
+
throw new Error(`Sanity API error: ${response.status} - ${response.statusText}`);
|
|
1623
|
+
}
|
|
1624
|
+
const result = await response.json();
|
|
1625
|
+
if (result.result) {
|
|
1626
|
+
if (globalConfig.sanityConfig.debug) {
|
|
1627
|
+
console.log("fetchSanity Results:", result);
|
|
1628
|
+
}
|
|
1629
|
+
let results = isList ? result.result : result.result[0];
|
|
1630
|
+
results = processNeedAccess ? await needsAccessDecorator(results, userPermissions) : results;
|
|
1631
|
+
return customPostProcess ? customPostProcess(results) : results;
|
|
1632
|
+
} else {
|
|
1633
|
+
throw new Error('No results found');
|
|
1634
|
+
}
|
|
1635
|
+
} catch (error) {
|
|
1636
|
+
console.error('fetchSanity: Fetch error:', error);
|
|
1637
|
+
return null;
|
|
1638
|
+
}
|
|
1541
1639
|
}
|
|
1542
1640
|
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
}
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
return results;
|
|
1641
|
+
function needsAccessDecorator(results, userPermissions) {
|
|
1642
|
+
if (globalConfig.sanityConfig.useDummyRailContentMethods) return results;
|
|
1643
|
+
|
|
1644
|
+
userPermissions = new Set(userPermissions);
|
|
1645
|
+
|
|
1646
|
+
if (Array.isArray(results)) {
|
|
1647
|
+
results.forEach((result) => {
|
|
1648
|
+
result['need_access'] = doesUserNeedAccessToContent(result, userPermissions);
|
|
1649
|
+
});
|
|
1650
|
+
} else if (results.entity && Array.isArray(results.entity)) {
|
|
1651
|
+
// Group By
|
|
1652
|
+
results.entity.forEach((result) => {
|
|
1653
|
+
if (result.lessons) {
|
|
1654
|
+
result.lessons.forEach((lesson) => {
|
|
1655
|
+
lesson['need_access'] = doesUserNeedAccessToContent(lesson, userPermissions); // Updated to check lesson access
|
|
1656
|
+
});
|
|
1657
|
+
} else {
|
|
1658
|
+
result['need_access'] = doesUserNeedAccessToContent(result, userPermissions);
|
|
1659
|
+
}
|
|
1660
|
+
});
|
|
1661
|
+
} else if (results.related_lessons && Array.isArray(results.related_lessons)) {
|
|
1662
|
+
results.related_lessons.forEach((result) => {
|
|
1663
|
+
result['need_access'] = doesUserNeedAccessToContent(result, userPermissions);
|
|
1664
|
+
})
|
|
1665
|
+
} else {
|
|
1666
|
+
results['need_access'] = doesUserNeedAccessToContent(results, userPermissions);
|
|
1667
|
+
}
|
|
1668
|
+
|
|
1669
|
+
return results;
|
|
1573
1670
|
}
|
|
1574
1671
|
|
|
1575
|
-
function doesUserNeedAccessToContent(result, userPermissions)
|
|
1576
|
-
|
|
1577
|
-
const permissions = new Set(result?.permission_id ?? []);
|
|
1672
|
+
function doesUserNeedAccessToContent(result, userPermissions) {
|
|
1673
|
+
const permissions = new Set(result?.permission_id ?? []);
|
|
1578
1674
|
if (permissions.size === 0) {
|
|
1579
1675
|
return false;
|
|
1580
1676
|
}
|
|
@@ -1586,12 +1682,6 @@ function doesUserNeedAccessToContent(result, userPermissions)
|
|
|
1586
1682
|
return true;
|
|
1587
1683
|
}
|
|
1588
1684
|
|
|
1589
|
-
async function getUserPermissions()
|
|
1590
|
-
{
|
|
1591
|
-
return await fetchUserPermissions();
|
|
1592
|
-
}
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
1685
|
/**
|
|
1596
1686
|
* Fetch CatalogueMetadata from Sanity. This information may be duplicated in the contentTypeConfig.js.
|
|
1597
1687
|
* It's an ongoing discussion (Aug 2024), but it's been included here if necessary
|
|
@@ -1605,8 +1695,8 @@ async function getUserPermissions()
|
|
|
1605
1695
|
* .then(data => console.log(data))
|
|
1606
1696
|
* .catch(error => console.error(error));
|
|
1607
1697
|
*/
|
|
1608
|
-
export async function fetchCatalogMetadata(contentType)
|
|
1609
|
-
|
|
1698
|
+
export async function fetchCatalogMetadata(contentType) {
|
|
1699
|
+
const query = `*[_type == 'CatalogMetadata']{
|
|
1610
1700
|
catalog_type,
|
|
1611
1701
|
brand,
|
|
1612
1702
|
groq_results,
|
|
@@ -1615,7 +1705,7 @@ export async function fetchCatalogMetadata(contentType)
|
|
|
1615
1705
|
modal_text,
|
|
1616
1706
|
sort_by,
|
|
1617
1707
|
}`
|
|
1618
|
-
return fetchSanity(query, false, {processNeedAccess:false});
|
|
1708
|
+
return fetchSanity(query, false, {processNeedAccess: false});
|
|
1619
1709
|
}
|
|
1620
1710
|
|
|
1621
1711
|
/**
|
|
@@ -1663,43 +1753,43 @@ export async function fetchMetadata(brand, type) {
|
|
|
1663
1753
|
|
|
1664
1754
|
//Helper Functions
|
|
1665
1755
|
function arrayJoinWithQuotes(array, delimiter = ',') {
|
|
1666
|
-
|
|
1667
|
-
|
|
1756
|
+
const wrapped = array.map(value => `'${value}'`);
|
|
1757
|
+
return wrapped.join(delimiter)
|
|
1668
1758
|
}
|
|
1669
1759
|
|
|
1670
1760
|
function getSanityDate(date) {
|
|
1671
|
-
|
|
1761
|
+
return date.toISOString();
|
|
1672
1762
|
}
|
|
1673
1763
|
|
|
1674
1764
|
const merge = (a, b, predicate = (a, b) => a === b) => {
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1765
|
+
const c = [...a]; // copy to avoid side effects
|
|
1766
|
+
// add all items from B to copy C if they're not already present
|
|
1767
|
+
b.forEach((bItem) => (c.some((cItem) => predicate(bItem, cItem)) ? null : c.push(bItem)))
|
|
1768
|
+
return c;
|
|
1679
1769
|
}
|
|
1680
1770
|
|
|
1681
1771
|
function checkSanityConfig(config) {
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1772
|
+
if (!config.sanityConfig.token) {
|
|
1773
|
+
console.warn('fetchSanity: The "token" property is missing in the config object.');
|
|
1774
|
+
return false;
|
|
1775
|
+
}
|
|
1776
|
+
if (!config.sanityConfig.projectId) {
|
|
1777
|
+
console.warn('fetchSanity: The "projectId" property is missing in the config object.');
|
|
1778
|
+
return false;
|
|
1779
|
+
}
|
|
1780
|
+
if (!config.sanityConfig.dataset) {
|
|
1781
|
+
console.warn('fetchSanity: The "dataset" property is missing in the config object.');
|
|
1782
|
+
return false;
|
|
1783
|
+
}
|
|
1784
|
+
if (!config.sanityConfig.version) {
|
|
1785
|
+
console.warn('fetchSanity: The "version" property is missing in the config object.');
|
|
1786
|
+
return false;
|
|
1787
|
+
}
|
|
1788
|
+
return true;
|
|
1699
1789
|
}
|
|
1700
1790
|
|
|
1701
1791
|
|
|
1702
|
-
function
|
|
1792
|
+
function buildRawQuery(
|
|
1703
1793
|
filter = '',
|
|
1704
1794
|
fields = '...',
|
|
1705
1795
|
{
|
|
@@ -1718,7 +1808,7 @@ function buildRawQuery(
|
|
|
1718
1808
|
}
|
|
1719
1809
|
|
|
1720
1810
|
|
|
1721
|
-
function
|
|
1811
|
+
async function buildQuery(
|
|
1722
1812
|
baseFilter = '',
|
|
1723
1813
|
filterParams = {},
|
|
1724
1814
|
fields = '...',
|
|
@@ -1729,11 +1819,11 @@ function buildQuery(
|
|
|
1729
1819
|
isSingle = false,
|
|
1730
1820
|
},
|
|
1731
1821
|
) {
|
|
1732
|
-
const filter = new FilterBuilder(baseFilter, filterParams).buildFilter();
|
|
1822
|
+
const filter = await new FilterBuilder(baseFilter, filterParams).buildFilter();
|
|
1733
1823
|
return buildRawQuery(filter, fields, {sortOrder, start, end, isSingle});
|
|
1734
1824
|
}
|
|
1735
1825
|
|
|
1736
|
-
function
|
|
1826
|
+
function buildEntityAndTotalQuery(
|
|
1737
1827
|
filter = '',
|
|
1738
1828
|
fields = '...',
|
|
1739
1829
|
{
|
|
@@ -1756,9 +1846,9 @@ function buildEntityAndTotalQuery(
|
|
|
1756
1846
|
}
|
|
1757
1847
|
|
|
1758
1848
|
|
|
1759
|
-
function getFilterOptions(option, commonFilter,contentType, brand){
|
|
1849
|
+
function getFilterOptions(option, commonFilter, contentType, brand) {
|
|
1760
1850
|
let filterGroq = '';
|
|
1761
|
-
const types = Array.from(new Set([...coachLessonsTypes
|
|
1851
|
+
const types = Array.from(new Set([...coachLessonsTypes, ...showsTypes[brand]]));
|
|
1762
1852
|
|
|
1763
1853
|
switch (option) {
|
|
1764
1854
|
case "difficulty":
|
|
@@ -1864,7 +1954,7 @@ function cleanUpGroq(query) {
|
|
|
1864
1954
|
<br class="clear">
|
|
1865
1955
|
|
|
1866
1956
|
<footer>
|
|
1867
|
-
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.3</a> on
|
|
1957
|
+
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.3</a> on Thu Nov 14 2024 23:44:16 GMT+0000 (Coordinated Universal Time) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
|
|
1868
1958
|
</footer>
|
|
1869
1959
|
|
|
1870
1960
|
<script>prettyPrint();</script>
|