musora-content-services 1.0.7 → 1.0.9
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/CHANGELOG.md +2 -0
- package/README.md +8 -1
- package/docs/global.html +1350 -972
- package/docs/index.html +8 -3
- package/docs/index.js.html +286 -93
- package/jest.config.js +198 -0
- package/package.json +4 -2
- package/src/index.js +190 -49
- package/test/sanityQueryService.test.js +88 -0
package/docs/index.js.html
CHANGED
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
<label for="nav-trigger" class="overlay"></label>
|
|
25
25
|
|
|
26
26
|
<nav>
|
|
27
|
-
<li class="nav-link nav-home-link"><a href="index.html">Home</a></li><li class="nav-heading"><a href="global.html">Globals</a></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#fetchAll">fetchAll</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#fetchAllSongs">fetchAllSongs</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#fetchArtists">fetchArtists</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#fetchByRailContentId">fetchByRailContentId</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#fetchByRailContentIds">fetchByRailContentIds</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#fetchChildren">fetchChildren</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#
|
|
27
|
+
<li class="nav-link nav-home-link"><a href="index.html">Home</a></li><li class="nav-heading"><a href="global.html">Globals</a></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#fetchAll">fetchAll</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#fetchAllFilterOptions">fetchAllFilterOptions</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#fetchAllSongs">fetchAllSongs</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#fetchArtists">fetchArtists</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#fetchByRailContentId">fetchByRailContentId</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#fetchByRailContentIds">fetchByRailContentIds</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#fetchChildren">fetchChildren</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#fetchLessonContent">fetchLessonContent</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#fetchMethodChildren">fetchMethodChildren</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#fetchMethodNextLesson">fetchMethodNextLesson</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#fetchNewReleases">fetchNewReleases</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#fetchNextPreviousLesson">fetchNextPreviousLesson</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#fetchPackAll">fetchPackAll</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#fetchPackChildren">fetchPackChildren</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#fetchRelatedLessons">fetchRelatedLessons</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#fetchRelatedSongs">fetchRelatedSongs</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#fetchSanity">fetchSanity</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#fetchSongArtistCount">fetchSongArtistCount</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#fetchSongById">fetchSongById</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#fetchSongCount">fetchSongCount</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#fetchSongFilterOptions">fetchSongFilterOptions</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#fetchUpcomingEvents">fetchUpcomingEvents</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#fetchWorkouts">fetchWorkouts</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#initializeSanityService">initializeSanityService</a></span></li>
|
|
28
28
|
</nav>
|
|
29
29
|
|
|
30
30
|
<div id="main">
|
|
@@ -39,15 +39,40 @@
|
|
|
39
39
|
|
|
40
40
|
<section>
|
|
41
41
|
<article>
|
|
42
|
-
<pre class="prettyprint source linenums"><code>
|
|
42
|
+
<pre class="prettyprint source linenums"><code>let globalConfig = {};
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Initializes the Sanity service with the given configuration.
|
|
46
|
+
* This function must be called before using any other functions in this library.
|
|
47
|
+
*
|
|
48
|
+
* @param {Object} config - Configuration object containing Sanity API settings.
|
|
49
|
+
* @param {string} config.token - The API token for authenticating with Sanity.
|
|
50
|
+
* @param {string} config.projectId - The project ID in Sanity.
|
|
51
|
+
* @param {string} config.dataset - The dataset name in Sanity.
|
|
52
|
+
* @param {string} config.version - The API version to use.
|
|
53
|
+
* @param {boolean} [config.debug=false] - Optional flag to enable debug mode, which logs the query and results.
|
|
54
|
+
* @param {boolean} [config.useCachedAPI=true] - Optional flag to disable cached API. *
|
|
55
|
+
* @example
|
|
56
|
+
* // Initialize the Sanity service in your app.js
|
|
57
|
+
* initializeSanityService({
|
|
58
|
+
* token: 'your-sanity-api-token',
|
|
59
|
+
* projectId: 'your-sanity-project-id',
|
|
60
|
+
* dataset: 'your-dataset-name',
|
|
61
|
+
* version: '2021-06-07',
|
|
62
|
+
* debug: true // Optional: Enable debug mode
|
|
63
|
+
* useCachedAPI: true // Optional: Use cached API
|
|
64
|
+
* });
|
|
65
|
+
*/
|
|
66
|
+
function initializeSanityService(config) {
|
|
67
|
+
globalConfig = config;
|
|
68
|
+
}
|
|
43
69
|
|
|
44
70
|
/**
|
|
45
71
|
* Fetch a song by its document ID from Sanity.
|
|
46
|
-
* @param {Object} config - Configuration object containing token, projectId, dataset, version, and debug.
|
|
47
72
|
* @param {string} documentId - The ID of the document to fetch.
|
|
48
73
|
* @returns {Promise<Object|null>} - The fetched song data or null if not found.
|
|
49
74
|
*/
|
|
50
|
-
|
|
75
|
+
async function fetchSongById(documentId) {
|
|
51
76
|
const fields = [
|
|
52
77
|
'title',
|
|
53
78
|
'"thumbnail_url": thumbnail.asset->url',
|
|
@@ -56,6 +81,7 @@ export async function fetchSongById(config, documentId) {
|
|
|
56
81
|
'album',
|
|
57
82
|
'instrumentless',
|
|
58
83
|
'soundslice',
|
|
84
|
+
'railcontent_id',
|
|
59
85
|
'"resources": resource[]{resource_url, resource_name}',
|
|
60
86
|
];
|
|
61
87
|
|
|
@@ -63,32 +89,40 @@ export async function fetchSongById(config, documentId) {
|
|
|
63
89
|
*[_type == "song" && railcontent_id == ${documentId}]{
|
|
64
90
|
${fields.join(', ')}
|
|
65
91
|
}`;
|
|
66
|
-
return fetchSanity(
|
|
92
|
+
return fetchSanity(query, false);
|
|
67
93
|
}
|
|
68
94
|
|
|
69
95
|
/**
|
|
70
96
|
* Fetch all artists with lessons available for a specific brand.
|
|
71
|
-
* @param {Object} config - Configuration object containing token, projectId, dataset, version, and debug.
|
|
72
97
|
* @param {string} brand - The brand for which to fetch artists.
|
|
73
98
|
* @returns {Promise<Object|null>} - The fetched artist data or null if not found.
|
|
74
99
|
*/
|
|
75
|
-
|
|
100
|
+
async function fetchArtists(brand) {
|
|
76
101
|
const query = `
|
|
77
102
|
*[_type == "artist"]{
|
|
78
103
|
name,
|
|
79
104
|
"lessonsCount": count(*[_type == "song" && brand == "${brand}" && references(^._id)])
|
|
80
105
|
}[lessonsCount > 0]`;
|
|
81
|
-
return fetchSanity(
|
|
106
|
+
return fetchSanity(query, true);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Fetch current number of artists for songs within a brand.
|
|
111
|
+
* @param {string} brand - The current brand.
|
|
112
|
+
* @returns {Promise<int|null>} - The fetched count of artists.
|
|
113
|
+
*/
|
|
114
|
+
async function fetchSongArtistCount(brand) {
|
|
115
|
+
const query = `count(*[_type == 'artist']{'lessonsCount': count(*[_type == 'song' && brand == '${brand}' && references(^._id)]._id)}[lessonsCount > 0])`;
|
|
116
|
+
return fetchSanity(query, false);
|
|
82
117
|
}
|
|
83
118
|
|
|
84
119
|
/**
|
|
85
120
|
* Fetch related songs for a specific brand and song ID.
|
|
86
|
-
* @param {Object} config - Configuration object containing token, projectId, dataset, version, and debug.
|
|
87
121
|
* @param {string} brand - The brand for which to fetch related songs.
|
|
88
122
|
* @param {string} songId - The ID of the song to find related songs for.
|
|
89
123
|
* @returns {Promise<Object|null>} - The fetched related songs data or null if not found.
|
|
90
124
|
*/
|
|
91
|
-
|
|
125
|
+
async function fetchRelatedSongs(brand, songId) {
|
|
92
126
|
const query = `
|
|
93
127
|
*[_type == "song" && railcontent_id == ${songId}]{
|
|
94
128
|
"data": array::unique([
|
|
@@ -153,12 +187,11 @@ export async function fetchRelatedSongs(config, brand, songId) {
|
|
|
153
187
|
])[0...10]
|
|
154
188
|
}`;
|
|
155
189
|
|
|
156
|
-
return fetchSanity(
|
|
190
|
+
return fetchSanity(query, true);
|
|
157
191
|
}
|
|
158
192
|
|
|
159
193
|
/**
|
|
160
194
|
* Fetch all songs for a specific brand with pagination and search options.
|
|
161
|
-
* @param {Object} config - Configuration object containing token, projectId, dataset, version, and debug.
|
|
162
195
|
* @param {string} brand - The brand for which to fetch songs.
|
|
163
196
|
* @param {Object} params - Parameters for pagination, filtering, and sorting.
|
|
164
197
|
* @param {number} [params.page=1] - The page number for pagination.
|
|
@@ -169,7 +202,14 @@ export async function fetchRelatedSongs(config, brand, songId) {
|
|
|
169
202
|
* @param {string} [params.groupBy=""] - The field to group the results by.
|
|
170
203
|
* @returns {Promise<Object|null>} - The fetched song data or null if not found.
|
|
171
204
|
*/
|
|
172
|
-
|
|
205
|
+
async function fetchAllSongs(brand, {
|
|
206
|
+
page = 1,
|
|
207
|
+
limit = 10,
|
|
208
|
+
searchTerm = "",
|
|
209
|
+
sort = "-published_on",
|
|
210
|
+
includedFields = [],
|
|
211
|
+
groupBy = ""
|
|
212
|
+
}) {
|
|
173
213
|
console.log('groupBy', groupBy)
|
|
174
214
|
const start = (page - 1) * limit;
|
|
175
215
|
const end = start + limit;
|
|
@@ -287,16 +327,15 @@ export async function fetchAllSongs(config, brand, { page = 1, limit = 10, searc
|
|
|
287
327
|
`;
|
|
288
328
|
}
|
|
289
329
|
|
|
290
|
-
return fetchSanity(
|
|
330
|
+
return fetchSanity(query, false);
|
|
291
331
|
}
|
|
292
332
|
|
|
293
333
|
/**
|
|
294
334
|
* Fetch filter options for a specific brand.
|
|
295
|
-
* @param {Object} config - Configuration object containing token, projectId, dataset, version, and debug.
|
|
296
335
|
* @param {string} brand - The brand for which to fetch filter options.
|
|
297
336
|
* @returns {Promise<Object|null>} - The fetched filter options or null if not found.
|
|
298
337
|
*/
|
|
299
|
-
|
|
338
|
+
async function fetchSongFilterOptions(brand) {
|
|
300
339
|
const query = `
|
|
301
340
|
{
|
|
302
341
|
"difficulty": [
|
|
@@ -317,27 +356,25 @@ export async function fetchFilterOptions(config, brand) {
|
|
|
317
356
|
}
|
|
318
357
|
`;
|
|
319
358
|
|
|
320
|
-
return fetchSanity(
|
|
359
|
+
return fetchSanity(query, false);
|
|
321
360
|
}
|
|
322
361
|
|
|
323
362
|
/**
|
|
324
363
|
* Fetch the total count of songs for a specific brand.
|
|
325
|
-
* @param {Object} config - Configuration object containing token, projectId, dataset, version, and debug.
|
|
326
364
|
* @param {string} brand - The brand for which to fetch the song count.
|
|
327
365
|
* @returns {Promise<number|null>} - The total count of songs or null if an error occurs.
|
|
328
366
|
*/
|
|
329
|
-
|
|
367
|
+
async function fetchSongCount(brand) {
|
|
330
368
|
const query = `count(*[_type == 'song' && brand == "${brand}"])`;
|
|
331
|
-
return fetchSanity(
|
|
369
|
+
return fetchSanity(query, false);
|
|
332
370
|
}
|
|
333
371
|
|
|
334
372
|
/**
|
|
335
373
|
* Fetch the latest workouts for the home page of a specific brand.
|
|
336
|
-
* @param {Object} config - Configuration object containing token, projectId, dataset, version, and debug.
|
|
337
374
|
* @param {string} brand - The brand for which to fetch workouts.
|
|
338
375
|
* @returns {Promise<Object|null>} - The fetched workout data or null if not found.
|
|
339
376
|
*/
|
|
340
|
-
|
|
377
|
+
async function fetchWorkouts(brand) {
|
|
341
378
|
const query = `*[_type == 'workout' && brand == '${brand}'] [0...5] {
|
|
342
379
|
railcontent_id,
|
|
343
380
|
title,
|
|
@@ -349,16 +386,15 @@ export async function fetchWorkouts(config, brand) {
|
|
|
349
386
|
web_url_path,
|
|
350
387
|
published_on
|
|
351
388
|
} | order(published_on desc)[0...5]`
|
|
352
|
-
return fetchSanity(
|
|
389
|
+
return fetchSanity(query, true);
|
|
353
390
|
}
|
|
354
391
|
|
|
355
392
|
/**
|
|
356
393
|
* Fetch the latest new releases for a specific brand.
|
|
357
|
-
* @param {Object} config - Configuration object containing token, projectId, dataset, version, and debug.
|
|
358
394
|
* @param {string} brand - The brand for which to fetch new releases.
|
|
359
395
|
* @returns {Promise<Object|null>} - The fetched new releases data or null if not found.
|
|
360
396
|
*/
|
|
361
|
-
|
|
397
|
+
async function fetchNewReleases(brand) {
|
|
362
398
|
const newTypes = {
|
|
363
399
|
'drumeo': ["drum-fest-international-2022", "spotlight", "the-history-of-electronic-drums", "backstage-secrets", "quick-tips", "question-and-answer", "student-collaborations", "live-streams", "live", "podcasts", "solos", "boot-camps", "gear-guides", "performances", "in-rhythm", "challenges", "on-the-road", "diy-drum-experiments", "rhythmic-adventures-of-captain-carson", "study-the-greats", "rhythms-from-another-planet", "tama-drums", "paiste-cymbals", "behind-the-scenes", "exploring-beats", "sonor-drums", "course", "play-along", "student-focus", "coach-stream", "learning-path-level", "unit", "quick-tips", "live", "question-and-answer", "student-review", "boot-camps", "song", "chords-and-scales", "pack", "podcasts", "workout", "challenge", "challenge-part"],
|
|
364
400
|
'pianote': ["student-review", "student-reviews", "question-and-answer", "course", "play-along", "student-focus", "coach-stream", "learning-path-level", "unit", "quick-tips", "live", "question-and-answer", "student-review", "boot-camps", "song", "chords-and-scales", "pack", "podcasts", "workout", "challenge", "challenge-part"],
|
|
@@ -378,16 +414,15 @@ export async function fetchNewReleases(config, brand) {
|
|
|
378
414
|
web_url_path,
|
|
379
415
|
published_on
|
|
380
416
|
} | order(published_on desc)[0...5]`
|
|
381
|
-
return fetchSanity(
|
|
417
|
+
return fetchSanity(query, true);
|
|
382
418
|
}
|
|
383
419
|
|
|
384
420
|
/**
|
|
385
421
|
* Fetch upcoming events for a specific brand.
|
|
386
|
-
* @param {Object} config - Configuration object containing token, projectId, dataset, version, and debug.
|
|
387
422
|
* @param {string} brand - The brand for which to fetch upcoming events.
|
|
388
423
|
* @returns {Promise<Object|null>} - The fetched upcoming events data or null if not found.
|
|
389
424
|
*/
|
|
390
|
-
|
|
425
|
+
async function fetchUpcomingEvents(brand) {
|
|
391
426
|
const liveTypes = {
|
|
392
427
|
'drumeo': ["drum-fest-international-2022", "spotlight", "the-history-of-electronic-drums", "backstage-secrets", "quick-tips", "question-and-answer", "student-collaborations", "live-streams", "live", "podcasts", "solos", "boot-camps", "gear-guides", "performances", "in-rhythm", "challenges", "on-the-road", "diy-drum-experiments", "rhythmic-adventures-of-captain-carson", "study-the-greats", "rhythms-from-another-planet", "tama-drums", "paiste-cymbals", "behind-the-scenes", "exploring-beats", "sonor-drums", "student-focus", "coach-stream", "live", "question-and-answer", "student-review", "boot-camps", "recording", "pack-bundle-lesson"],
|
|
393
428
|
'pianote': ["student-review", "student-reviews", "question-and-answer", "student-focus", "coach-stream", "live", "question-and-answer", "student-review", "boot-camps", "recording", "pack-bundle-lesson"],
|
|
@@ -409,17 +444,16 @@ export async function fetchUpcomingEvents(config, brand) {
|
|
|
409
444
|
web_url_path,
|
|
410
445
|
published_on
|
|
411
446
|
} | order(published_on asc)[0...5]`;
|
|
412
|
-
return fetchSanity(
|
|
447
|
+
return fetchSanity(query, true);
|
|
413
448
|
}
|
|
414
449
|
|
|
415
450
|
/**
|
|
416
451
|
* Fetch content by a specific Railcontent ID.
|
|
417
|
-
* @param {Object} config - Configuration object containing token, projectId, dataset, version, and debug.
|
|
418
452
|
* @param {string} id - The Railcontent ID of the content to fetch.
|
|
419
453
|
* @returns {Promise<Object|null>} - The fetched content data or null if not found.
|
|
420
454
|
*/
|
|
421
|
-
|
|
422
|
-
const query = `*[railcontent_id
|
|
455
|
+
async function fetchByRailContentId(id) {
|
|
456
|
+
const query = `*[railcontent_id == ${id}]{
|
|
423
457
|
railcontent_id,
|
|
424
458
|
title,
|
|
425
459
|
"image": thumbnail.asset->url,
|
|
@@ -430,16 +464,15 @@ export async function fetchByRailContentId(config, id) {
|
|
|
430
464
|
web_url_path,
|
|
431
465
|
published_on
|
|
432
466
|
}`
|
|
433
|
-
return fetchSanity(
|
|
467
|
+
return fetchSanity(query, false);
|
|
434
468
|
}
|
|
435
469
|
|
|
436
470
|
/**
|
|
437
471
|
* Fetch content by an array of Railcontent IDs.
|
|
438
|
-
* @param {Object} config - Configuration object containing token, projectId, dataset, version, and debug.
|
|
439
472
|
* @param {Array<string>} ids - The array of Railcontent IDs of the content to fetch.
|
|
440
473
|
* @returns {Promise<Array<Object>|null>} - The fetched content data or null if not found.
|
|
441
474
|
*/
|
|
442
|
-
|
|
475
|
+
async function fetchByRailContentIds(ids) {
|
|
443
476
|
const idsString = ids.join(',');
|
|
444
477
|
const query = `*[railcontent_id in [${idsString}]]{
|
|
445
478
|
railcontent_id,
|
|
@@ -452,12 +485,11 @@ export async function fetchByRailContentIds(config, ids) {
|
|
|
452
485
|
web_url_path,
|
|
453
486
|
published_on
|
|
454
487
|
}`
|
|
455
|
-
return fetchSanity(
|
|
488
|
+
return fetchSanity(query, true);
|
|
456
489
|
}
|
|
457
490
|
|
|
458
491
|
/**
|
|
459
492
|
* Fetch all content for a specific brand and type with pagination, search, and grouping options.
|
|
460
|
-
* @param {Object} config - Configuration object containing token, projectId, dataset, version, and debug.
|
|
461
493
|
* @param {string} brand - The brand for which to fetch content.
|
|
462
494
|
* @param {string} type - The content type to fetch (e.g., 'song', 'artist').
|
|
463
495
|
* @param {Object} params - Parameters for pagination, filtering, sorting, and grouping.
|
|
@@ -469,7 +501,14 @@ export async function fetchByRailContentIds(config, ids) {
|
|
|
469
501
|
* @param {string} [params.groupBy=""] - The field to group the results by (e.g., 'artist', 'genre').
|
|
470
502
|
* @returns {Promise<Object|null>} - The fetched content data or null if not found.
|
|
471
503
|
*/
|
|
472
|
-
|
|
504
|
+
async function fetchAll(brand, type, {
|
|
505
|
+
page = 1,
|
|
506
|
+
limit = 10,
|
|
507
|
+
searchTerm = "",
|
|
508
|
+
sort = "-published_on",
|
|
509
|
+
includedFields = [],
|
|
510
|
+
groupBy = ""
|
|
511
|
+
}) {
|
|
473
512
|
const start = (page - 1) * limit;
|
|
474
513
|
const end = start + limit;
|
|
475
514
|
|
|
@@ -514,7 +553,8 @@ export async function fetchAll(config, brand, type, { page = 1, limit = 10, sear
|
|
|
514
553
|
|
|
515
554
|
// Determine the group by clause
|
|
516
555
|
let query = "";
|
|
517
|
-
|
|
556
|
+
let manyReference = true; //TODO: define whether reference is one to one or one to many
|
|
557
|
+
if (groupBy !== "" && !manyReference) {
|
|
518
558
|
query = `
|
|
519
559
|
{
|
|
520
560
|
"total": count(*[_type == '${groupBy}' && count(*[_type == '${type}' && brand == '${brand}' && ^._id == ${groupBy}._ref ]._id) > 0]),
|
|
@@ -539,6 +579,31 @@ export async function fetchAll(config, brand, type, { page = 1, limit = 10, sear
|
|
|
539
579
|
|order(${sortOrder})
|
|
540
580
|
[${start}...${end}]
|
|
541
581
|
}`;
|
|
582
|
+
} else if (groupBy !== "" && manyReference) {
|
|
583
|
+
query = `
|
|
584
|
+
{
|
|
585
|
+
"total": count(*[_type == '${groupBy}' && count(*[_type == '${type}' && brand == '${brand}' && ^._id in ${groupBy}[]._ref]._id)>0]),
|
|
586
|
+
"entity": *[_type == '${groupBy}' && count(*[_type == '${type}' && brand == '${brand}' && ^._id in ${groupBy}[]._ref]._id) > 0]
|
|
587
|
+
{
|
|
588
|
+
'id': _id,
|
|
589
|
+
'type': _type,
|
|
590
|
+
name,
|
|
591
|
+
'head_shot_picture_url': thumbnail_url.asset->url,
|
|
592
|
+
'all_lessons_count': count(*[_type == '${type}' && brand == '${brand}' && ^._id in ${groupBy}[]._ref ]._id),
|
|
593
|
+
'lessons': *[_type == '${type}' && brand == '${brand}' && ^._id in ${groupBy}[]._ref ]{
|
|
594
|
+
railcontent_id,
|
|
595
|
+
title,
|
|
596
|
+
"image": thumbnail.asset->url,
|
|
597
|
+
difficulty,
|
|
598
|
+
difficulty_string,
|
|
599
|
+
web_url_path,
|
|
600
|
+
published_on,
|
|
601
|
+
${groupBy}
|
|
602
|
+
}[0...10]
|
|
603
|
+
}
|
|
604
|
+
|order(${sortOrder})
|
|
605
|
+
[${start}...${end}]
|
|
606
|
+
}`;
|
|
542
607
|
} else {
|
|
543
608
|
query = `
|
|
544
609
|
{
|
|
@@ -556,16 +621,73 @@ export async function fetchAll(config, brand, type, { page = 1, limit = 10, sear
|
|
|
556
621
|
`;
|
|
557
622
|
}
|
|
558
623
|
|
|
559
|
-
return fetchSanity(
|
|
624
|
+
return fetchSanity(query, false);
|
|
625
|
+
}
|
|
626
|
+
|
|
627
|
+
/**
|
|
628
|
+
* Fetches all available filter options based on various criteria such as brand, filters, style, artist, content type, and search term.
|
|
629
|
+
*
|
|
630
|
+
* This function constructs a query to retrieve the total number of results and filter options such as difficulty, instrument type, and genre.
|
|
631
|
+
* The filter options are dynamically generated based on the provided filters, style, artist, and content type.
|
|
632
|
+
*
|
|
633
|
+
* @param {string} brand - The brand for which to fetch the filter options.
|
|
634
|
+
* @param {string} filters - Additional filters to apply to the query, typically in the format of Sanity GROQ queries.
|
|
635
|
+
* @param {string} [style] - Optional style or genre to filter the results. If provided, the query will check if the style exists in the genre array.
|
|
636
|
+
* @param {string} [artist] - Optional artist name to filter the results. If provided, the query will check if the artist's name matches.
|
|
637
|
+
* @param {string} contentType - The content type to fetch (e.g., 'song', 'lesson').
|
|
638
|
+
* @param {string} [term] - Optional search term to match against various fields such as title, album, artist name, and genre.
|
|
639
|
+
*
|
|
640
|
+
* @returns {Promise<Object|null>} - A promise that resolves to an object containing the total results and filter options, or null if the query fails.
|
|
641
|
+
*
|
|
642
|
+
* @example
|
|
643
|
+
* // Example usage:
|
|
644
|
+
* fetchAllFilterOptions('myBrand', '', 'Rock', 'John Doe', 'song', 'Love')
|
|
645
|
+
* .then(options => console.log(options))
|
|
646
|
+
* .catch(error => console.error(error));
|
|
647
|
+
*/
|
|
648
|
+
async function fetchAllFilterOptions(
|
|
649
|
+
brand,
|
|
650
|
+
filters,
|
|
651
|
+
style,
|
|
652
|
+
artist,
|
|
653
|
+
contentType,
|
|
654
|
+
term
|
|
655
|
+
){
|
|
656
|
+
const query = `
|
|
657
|
+
{
|
|
658
|
+
"meta": {
|
|
659
|
+
"totalResults": count(*[_type == '${contentType}' && brand == "${brand}" && ${style ? `'${style}' in genre[]->name` : `artist->name == '${artist}'`} ${filters}
|
|
660
|
+
${term ? `&& (title match "${term}" || album match "${term}" || artist->name match "${term}" || genre[]->name match "${term}")` : ''}]),
|
|
661
|
+
"filterOptions": {
|
|
662
|
+
"difficulty": [
|
|
663
|
+
{"type": "Introductory", "count": count(*[_type == '${contentType}' && brand == '${brand}' && ${style ? `'${style}' in genre[]->name` : `artist->name == '${artist}'`} && difficulty_string == "Introductory" ${filters}])},
|
|
664
|
+
{"type": "Beginner", "count": count(*[_type == '${contentType}' && brand == '${brand}' && ${style ? `'${style}' in genre[]->name` : `artist->name == '${artist}'`} && difficulty_string == "Beginner" ${filters}])},
|
|
665
|
+
{"type": "Intermediate", "count": count(*[_type == '${contentType}' && brand == '${brand}' && ${style ? `'${style}' in genre[]->name` : `artist->name == '${artist}'`} && difficulty_string == "Intermediate" ${filters}])},
|
|
666
|
+
{"type": "Advanced", "count": count(*[_type == '${contentType}' && brand == '${brand}' && ${style ? `'${style}' in genre[]->name` : `artist->name == '${artist}'`} && difficulty_string == "Advanced" ${filters}])},
|
|
667
|
+
{"type": "Expert", "count": count(*[_type == '${contentType}' && brand == '${brand}' && ${style ? `'${style}' in genre[]->name` : `artist->name == '${artist}'`} && difficulty_string == "Expert" ${filters}])}
|
|
668
|
+
][count > 0],
|
|
669
|
+
"instrumentless": [
|
|
670
|
+
{"type": "Full Song Only", "count": count(*[_type == '${contentType}' && brand == '${brand}' && ${style ? `'${style}' in genre[]->name` : `artist->name == '${artist}'`} && instrumentless == false ${filters}])},
|
|
671
|
+
{"type": "Instrument Removed", "count": count(*[_type == '${contentType}' && brand == '${brand}' && ${style ? `'${style}' in genre[]->name` : `artist->name == '${artist}'`} && instrumentless == true ${filters}])}
|
|
672
|
+
][count > 0],
|
|
673
|
+
"genre": *[_type == 'genre' && '${contentType}' in filter_types] {
|
|
674
|
+
"type": name,
|
|
675
|
+
"count": count(*[_type == '${contentType}' && brand == "${brand}" && ${style ? `'${style}' in genre[]->name` : `artist->name == '${artist}'`} && references(^._id)])
|
|
676
|
+
}[count > 0]
|
|
677
|
+
}
|
|
678
|
+
}
|
|
679
|
+
}
|
|
680
|
+
`;
|
|
681
|
+
|
|
682
|
+
return fetchSanity(query, false);
|
|
560
683
|
}
|
|
561
684
|
|
|
562
685
|
/**
|
|
563
686
|
* Fetch children content by Railcontent ID.
|
|
564
|
-
* @param {Object} config - Configuration object containing token, projectId, dataset, version, and debug.
|
|
565
687
|
* @param {string} railcontentId - The Railcontent ID of the parent content.
|
|
566
688
|
* @returns {Promise<Array<Object>|null>} - The fetched children content data or null if not found.
|
|
567
689
|
*/
|
|
568
|
-
|
|
690
|
+
async function fetchChildren(railcontentId) {
|
|
569
691
|
//TODO: Implement getByParentId include sum XP
|
|
570
692
|
const query = `*[_railcontent_id == ${railcontentId}]{
|
|
571
693
|
railcontent_id,
|
|
@@ -578,16 +700,15 @@ export async function fetchChildren(config, railcontentId) {
|
|
|
578
700
|
web_url_path,
|
|
579
701
|
published_on
|
|
580
702
|
} | order(published_on asc)`
|
|
581
|
-
return fetchSanity(
|
|
703
|
+
return fetchSanity(query, true);
|
|
582
704
|
}
|
|
583
705
|
|
|
584
706
|
/**
|
|
585
707
|
* Fetch the next lesson for a specific method by Railcontent ID.
|
|
586
|
-
* @param {Object} config - Configuration object containing token, projectId, dataset, version, and debug.
|
|
587
708
|
* @param {string} railcontentId - The Railcontent ID of the current lesson.
|
|
588
709
|
* @returns {Promise<Object|null>} - The fetched next lesson data or null if not found.
|
|
589
710
|
*/
|
|
590
|
-
|
|
711
|
+
async function fetchMethodNextLesson(railcontentId) {
|
|
591
712
|
//TODO: Implement getNextContentForParentContentForUser
|
|
592
713
|
const query = `*[_railcontent_id == ${railcontentId}]{
|
|
593
714
|
railcontent_id,
|
|
@@ -600,27 +721,25 @@ export async function fetchMethodNextLesson(config, railcontentId) {
|
|
|
600
721
|
web_url_path,
|
|
601
722
|
published_on
|
|
602
723
|
}`
|
|
603
|
-
return fetchSanity(
|
|
724
|
+
return fetchSanity(query, false);
|
|
604
725
|
}
|
|
605
726
|
|
|
606
727
|
/**
|
|
607
728
|
* Fetch all children of a specific method by Railcontent ID.
|
|
608
|
-
* @param {Object} config - Configuration object containing token, projectId, dataset, version, and debug.
|
|
609
729
|
* @param {string} railcontentId - The Railcontent ID of the method.
|
|
610
730
|
* @returns {Promise<Array<Object>|null>} - The fetched children data or null if not found.
|
|
611
731
|
*/
|
|
612
|
-
|
|
732
|
+
async function fetchMethodChildren(railcontentId) {
|
|
613
733
|
//TODO: Implement getByParentId include sum XP
|
|
614
734
|
return fetchChildren(railcontentId);
|
|
615
735
|
}
|
|
616
736
|
|
|
617
737
|
/**
|
|
618
738
|
* Fetch the next and previous lessons for a specific lesson by Railcontent ID.
|
|
619
|
-
* @param {Object} config - Configuration object containing token, projectId, dataset, version, and debug.
|
|
620
739
|
* @param {string} railcontentId - The Railcontent ID of the current lesson.
|
|
621
740
|
* @returns {Promise<Object|null>} - The fetched next and previous lesson data or null if found.
|
|
622
741
|
*/
|
|
623
|
-
|
|
742
|
+
async function fetchNextPreviousLesson(railcontentId) {
|
|
624
743
|
//TODO: Implement getTypeNeighbouringSiblings/getNextAndPreviousLessons
|
|
625
744
|
const query = `*[_railcontent_id == ${railcontentId}]{
|
|
626
745
|
railcontent_id,
|
|
@@ -633,45 +752,69 @@ export async function fetchNextPreviousLesson(config, railcontentId) {
|
|
|
633
752
|
web_url_path,
|
|
634
753
|
published_on
|
|
635
754
|
}`
|
|
636
|
-
return fetchSanity(
|
|
755
|
+
return fetchSanity(query, false);
|
|
637
756
|
}
|
|
638
757
|
|
|
639
758
|
/**
|
|
640
|
-
* Fetch
|
|
641
|
-
* @param {
|
|
642
|
-
* @
|
|
643
|
-
|
|
759
|
+
* Fetch the page data for a specific lesson by Railcontent ID.
|
|
760
|
+
* @param {string} railContentId - The Railcontent ID of the current lesson.
|
|
761
|
+
* @returns {Promise<Object|null>} - The fetched page data or null if found.
|
|
762
|
+
*/
|
|
763
|
+
async function fetchLessonContent(railContentId) {
|
|
764
|
+
const query = `*[railcontent_id == ${railContentId} ]
|
|
765
|
+
{title, published_on,"type":_type, "resources": resource, difficulty, difficulty_string, brand, soundslice, instrumentless, railcontent_id, "id":railcontent_id, slug, artist->,"thumbnail_url":thumbnail.asset->url, "url": web_url_path, soundslice_slug,description,
|
|
766
|
+
"chapters": chapter[]{
|
|
767
|
+
chapter_description,
|
|
768
|
+
chapter_timecode,
|
|
769
|
+
"chapter_thumbnail_url": chapter_thumbnail_url.asset->url
|
|
770
|
+
},
|
|
771
|
+
"coaches": instructor[]-> {
|
|
772
|
+
name,
|
|
773
|
+
"id":_id,
|
|
774
|
+
"coach_profile_image":thumbnail_url.asset->url
|
|
775
|
+
},
|
|
776
|
+
"instructors":instructor[]->name,
|
|
777
|
+
instructor[]->,
|
|
778
|
+
"assignments":assignment[]{
|
|
779
|
+
"id": railcontent_id,
|
|
780
|
+
"soundslice_slug": assignment_soundslice,
|
|
781
|
+
"title": assignment_title,
|
|
782
|
+
"sheet_music_image_url": assignment_sheet_music_image,
|
|
783
|
+
"timecode": assignment_timecode,
|
|
784
|
+
"description": assignment_description
|
|
785
|
+
},
|
|
786
|
+
video}`
|
|
787
|
+
return fetchSanity(query, false);
|
|
788
|
+
}
|
|
789
|
+
|
|
790
|
+
/**
|
|
791
|
+
* Fetch related lessons for a specific lesson by RailContent ID and type.
|
|
792
|
+
* @param {string} railContentId - The RailContent ID of the current lesson.
|
|
793
|
+
* @param {string} brand - The current brand.
|
|
644
794
|
* @returns {Promise<Array<Object>|null>} - The fetched related lessons data or null if not found.
|
|
645
795
|
*/
|
|
646
|
-
|
|
647
|
-
let sort = 'published_on'
|
|
648
|
-
if (type == 'rhythmic-adventures-of-captain-carson' ||
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
}
|
|
796
|
+
async function fetchRelatedLessons(railContentId, brand) {
|
|
797
|
+
// let sort = 'published_on'
|
|
798
|
+
// if (type == 'rhythmic-adventures-of-captain-carson' ||
|
|
799
|
+
// type == 'diy-drum-experiments' ||
|
|
800
|
+
// type == 'in-rhythm') {
|
|
801
|
+
// sort = 'sort';
|
|
802
|
+
// }
|
|
653
803
|
//TODO: Implement $this->contentService->getFiltered
|
|
654
|
-
const query = `*[
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
difficulty,
|
|
661
|
-
difficulty_string,
|
|
662
|
-
web_url_path,
|
|
663
|
-
published_on
|
|
664
|
-
} | order(published_on asc)[0...5]`
|
|
665
|
-
return fetchSanity(config, query);
|
|
804
|
+
const query = `*[railcontent_id == ${railContentId} && brand == "${brand}" && references(*[_type=='permission']._id)]{
|
|
805
|
+
"related_lessons" : array::unique([
|
|
806
|
+
...(*[_type=="song" && brand == "${brand}" && references(^.artist->_id)]{_id, "id":railcontent_id, published_on, title, "thumbnail_url":thumbnail.asset->url, difficulty_string, railcontent_id, artist->}[0...11]),
|
|
807
|
+
...(*[_type=="song" && brand == "${brand}" && references(^.genre[]->_id)]{_id, "id":railcontent_id, published_on, title, "thumbnail_url":thumbnail.asset->url, difficulty_string, railcontent_id, artist->}[0...11])
|
|
808
|
+
])|order(published_on, railcontent_id)[0...11]}`;
|
|
809
|
+
return fetchSanity(query, false);
|
|
666
810
|
}
|
|
667
811
|
|
|
668
812
|
/**
|
|
669
813
|
* Fetch all content for a specific pack by Railcontent ID.
|
|
670
|
-
* @param {Object} config - Configuration object containing token, projectId, dataset, version, and debug.
|
|
671
814
|
* @param {string} railcontentId - The Railcontent ID of the pack.
|
|
672
815
|
* @returns {Promise<Array<Object>|null>} - The fetched pack content data or null if not found.
|
|
673
816
|
*/
|
|
674
|
-
|
|
817
|
+
async function fetchPackAll(railcontentId) {
|
|
675
818
|
//TODO: Implement getPacks
|
|
676
819
|
const query = `*[_railcontent_id == ${railcontentId}]{
|
|
677
820
|
railcontent_id,
|
|
@@ -684,38 +827,39 @@ export async function fetchPackAll(config, railcontentId) {
|
|
|
684
827
|
web_url_path,
|
|
685
828
|
published_on
|
|
686
829
|
} | order(published_on asc)[0...5]`
|
|
687
|
-
return fetchSanity(
|
|
830
|
+
return fetchSanity(query, true);
|
|
688
831
|
}
|
|
689
832
|
|
|
690
833
|
/**
|
|
691
834
|
* Fetch all children of a specific pack by Railcontent ID.
|
|
692
|
-
* @param {Object} config - Configuration object containing token, projectId, dataset, version, and debug.
|
|
693
835
|
* @param {string} railcontentId - The Railcontent ID of the pack.
|
|
694
836
|
* @returns {Promise<Array<Object>|null>} - The fetched pack children data or null if not found.
|
|
695
837
|
*/
|
|
696
|
-
|
|
838
|
+
async function fetchPackChildren(railcontentId) {
|
|
697
839
|
return fetchChildren(railcontentId, 'pack');
|
|
698
840
|
}
|
|
699
841
|
|
|
700
842
|
/**
|
|
701
843
|
* Fetch data from the Sanity API based on a provided query.
|
|
702
|
-
* @param {Object} config - Configuration object containing the Sanity API settings.
|
|
703
|
-
* @param {string} config.token - The API token for authenticating with Sanity.
|
|
704
|
-
* @param {string} config.projectId - The project ID in Sanity.
|
|
705
|
-
* @param {string} config.dataset - The dataset name in Sanity.
|
|
706
|
-
* @param {string} config.version - The API version to use.
|
|
707
|
-
* @param {boolean} [config.debug=false] - Flag to enable debug mode, which logs the query and results.
|
|
708
844
|
* @param {string} query - The GROQ query to execute against the Sanity API.
|
|
845
|
+
* @param {boolean} isList - Whether to return an array or single result
|
|
709
846
|
* @returns {Promise<Object|null>} - The first result from the query, or null if an error occurs or no results are found.
|
|
710
847
|
*/
|
|
711
|
-
async function fetchSanity(
|
|
712
|
-
|
|
848
|
+
async function fetchSanity(query, isList) {
|
|
849
|
+
// Check the config object before proceeding
|
|
850
|
+
if (!checkConfig(globalConfig)) {
|
|
851
|
+
return null;
|
|
852
|
+
}
|
|
853
|
+
|
|
854
|
+
if (globalConfig.debug) {
|
|
713
855
|
console.log("fetchSanity Query:", query);
|
|
714
856
|
}
|
|
857
|
+
|
|
715
858
|
const encodedQuery = encodeURIComponent(query);
|
|
716
|
-
const
|
|
859
|
+
const api = globalConfig.useCachedAPI ? 'apicdn' : 'api'
|
|
860
|
+
const url = `https://${globalConfig.projectId}.${api}.sanity.io/v${globalConfig.version}/data/query/${globalConfig.dataset}?query=${encodedQuery}`;
|
|
717
861
|
const headers = {
|
|
718
|
-
'Authorization': `Bearer ${token}`,
|
|
862
|
+
'Authorization': `Bearer ${globalConfig.token}`,
|
|
719
863
|
'Content-Type': 'application/json'
|
|
720
864
|
};
|
|
721
865
|
|
|
@@ -723,19 +867,21 @@ async function fetchSanity({ token, projectId, dataset, version, debug = false }
|
|
|
723
867
|
const response = await fetch(url, {headers});
|
|
724
868
|
const result = await response.json();
|
|
725
869
|
if (result.result) {
|
|
726
|
-
if (debug) {
|
|
727
|
-
console.log("fetchSanity Results:", result
|
|
870
|
+
if (globalConfig.debug) {
|
|
871
|
+
console.log("fetchSanity Results:", result);
|
|
728
872
|
}
|
|
729
873
|
return isList ? result.result : result.result[0];
|
|
730
874
|
} else {
|
|
731
875
|
throw new Error('No results found');
|
|
732
876
|
}
|
|
733
877
|
} catch (error) {
|
|
734
|
-
console.error('
|
|
878
|
+
console.error('fetchSanity: Fetch error:', error);
|
|
735
879
|
return null;
|
|
736
880
|
}
|
|
737
881
|
}
|
|
738
882
|
|
|
883
|
+
|
|
884
|
+
//Helper Functions
|
|
739
885
|
function arrayJoinWithQuotes(array, delimiter = ',') {
|
|
740
886
|
const wrapped = array.map(value => `'${value}'`);
|
|
741
887
|
return wrapped.join(delimiter)
|
|
@@ -745,6 +891,53 @@ function getSanityDate(date) {
|
|
|
745
891
|
return date.toISOString();
|
|
746
892
|
}
|
|
747
893
|
|
|
894
|
+
function checkConfig(config) {
|
|
895
|
+
if (!config.token) {
|
|
896
|
+
console.warn('fetchSanity: The "token" property is missing in the config object.');
|
|
897
|
+
return false;
|
|
898
|
+
}
|
|
899
|
+
if (!config.projectId) {
|
|
900
|
+
console.warn('fetchSanity: The "projectId" property is missing in the config object.');
|
|
901
|
+
return false;
|
|
902
|
+
}
|
|
903
|
+
if (!config.dataset) {
|
|
904
|
+
console.warn('fetchSanity: The "dataset" property is missing in the config object.');
|
|
905
|
+
return false;
|
|
906
|
+
}
|
|
907
|
+
if (!config.version) {
|
|
908
|
+
console.warn('fetchSanity: The "version" property is missing in the config object.');
|
|
909
|
+
return false;
|
|
910
|
+
}
|
|
911
|
+
return true;
|
|
912
|
+
}
|
|
913
|
+
|
|
914
|
+
|
|
915
|
+
//Main
|
|
916
|
+
module.exports = {
|
|
917
|
+
initializeSanityService,
|
|
918
|
+
fetchSongById,
|
|
919
|
+
fetchArtists,
|
|
920
|
+
fetchSongArtistCount,
|
|
921
|
+
fetchRelatedSongs,
|
|
922
|
+
fetchAllSongs,
|
|
923
|
+
fetchSongFilterOptions,
|
|
924
|
+
fetchSongCount,
|
|
925
|
+
fetchWorkouts,
|
|
926
|
+
fetchNewReleases,
|
|
927
|
+
fetchUpcomingEvents,
|
|
928
|
+
fetchByRailContentId,
|
|
929
|
+
fetchByRailContentIds,
|
|
930
|
+
fetchAll,
|
|
931
|
+
fetchAllFilterOptions,
|
|
932
|
+
fetchMethodNextLesson,
|
|
933
|
+
fetchMethodChildren,
|
|
934
|
+
fetchNextPreviousLesson,
|
|
935
|
+
fetchRelatedLessons,
|
|
936
|
+
fetchPackAll,
|
|
937
|
+
fetchPackChildren,
|
|
938
|
+
fetchLessonContent
|
|
939
|
+
};
|
|
940
|
+
|
|
748
941
|
</code></pre>
|
|
749
942
|
</article>
|
|
750
943
|
</section>
|
|
@@ -757,7 +950,7 @@ function getSanityDate(date) {
|
|
|
757
950
|
<br class="clear">
|
|
758
951
|
|
|
759
952
|
<footer>
|
|
760
|
-
Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.3</a> on
|
|
953
|
+
Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.3</a> on Mon Aug 12 2024 13:37:15 GMT+0000 (Coordinated Universal Time) using the Minami theme.
|
|
761
954
|
</footer>
|
|
762
955
|
|
|
763
956
|
<script>prettyPrint();</script>
|