musora-content-services 1.0.60 → 1.0.63
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 +6 -0
- package/docs/config.js.html +2 -2
- package/docs/index.html +2 -2
- package/docs/module-Config.html +2 -2
- package/docs/module-Railcontent-Services.html +2 -2
- package/docs/module-Sanity-Services.html +559 -31
- package/docs/railcontent.js.html +2 -2
- package/docs/sanity.js.html +154 -146
- package/package.json +1 -1
- package/src/contentTypeConfig.js +71 -4
- package/src/index.d.ts +2 -2
- package/src/index.js +9 -3
- package/src/services/sanity.js +153 -144
- package/test/sanityQueryService.test.js +61 -12
package/src/index.js
CHANGED
|
@@ -16,15 +16,18 @@ import {
|
|
|
16
16
|
fetchAll,
|
|
17
17
|
fetchAllFilterOptions,
|
|
18
18
|
fetchMethodNextLesson,
|
|
19
|
-
fetchMethods,
|
|
20
19
|
fetchMethod,
|
|
21
|
-
|
|
20
|
+
fetchMethods,
|
|
21
|
+
fetchMethodChildrenIds,
|
|
22
22
|
fetchNextPreviousLesson,
|
|
23
23
|
fetchRelatedLessons,
|
|
24
24
|
fetchPackAll,
|
|
25
25
|
fetchPackChildren,
|
|
26
26
|
fetchLessonContent,
|
|
27
27
|
fetchCourseOverview,
|
|
28
|
+
fetchChildren,
|
|
29
|
+
fetchParentByRailContentId,
|
|
30
|
+
fetchMethodPreviousNextLesson,
|
|
28
31
|
} from './services/sanity.js';
|
|
29
32
|
|
|
30
33
|
import {
|
|
@@ -53,7 +56,7 @@ export {
|
|
|
53
56
|
fetchMethods,
|
|
54
57
|
fetchMethod,
|
|
55
58
|
fetchMethodNextLesson,
|
|
56
|
-
|
|
59
|
+
fetchMethodChildrenIds,
|
|
57
60
|
fetchNextPreviousLesson,
|
|
58
61
|
fetchRelatedLessons,
|
|
59
62
|
fetchPackAll,
|
|
@@ -63,4 +66,7 @@ export {
|
|
|
63
66
|
fetchAllCompletedStates,
|
|
64
67
|
fetchContentInProgress,
|
|
65
68
|
fetchCourseOverview,
|
|
69
|
+
fetchChildren,
|
|
70
|
+
fetchParentByRailContentId,
|
|
71
|
+
fetchMethodPreviousNextLesson,
|
|
66
72
|
}
|
package/src/services/sanity.js
CHANGED
|
@@ -1,23 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @module Sanity-Services
|
|
3
3
|
*/
|
|
4
|
-
import {contentTypeConfig} from "../contentTypeConfig";
|
|
4
|
+
import {assignmentsField, contentTypeConfig, DEFAULT_FIELDS, getFieldsForContentType} from "../contentTypeConfig";
|
|
5
5
|
import {globalConfig} from "./config";
|
|
6
6
|
|
|
7
7
|
import { fetchAllCompletedStates, fetchCurrentSongComplete } from './railcontent.js';
|
|
8
8
|
|
|
9
|
-
const DEFAULT_FIELDS = [
|
|
10
|
-
'"id": railcontent_id',
|
|
11
|
-
'railcontent_id',
|
|
12
|
-
'"type": _type',
|
|
13
|
-
'title',
|
|
14
|
-
'"image": thumbnail.asset->url',
|
|
15
|
-
'difficulty',
|
|
16
|
-
'difficulty_string',
|
|
17
|
-
'web_url_path',
|
|
18
|
-
'published_on'
|
|
19
|
-
];
|
|
20
|
-
|
|
21
9
|
/**
|
|
22
10
|
* Fetch a song by its document ID from Sanity.
|
|
23
11
|
*
|
|
@@ -30,25 +18,10 @@ const DEFAULT_FIELDS = [
|
|
|
30
18
|
* .catch(error => console.error(error));
|
|
31
19
|
*/
|
|
32
20
|
export async function fetchSongById(documentId) {
|
|
33
|
-
const fields = [
|
|
34
|
-
'"id": railcontent_id',
|
|
35
|
-
'railcontent_id',
|
|
36
|
-
'"type": _type',
|
|
37
|
-
'description',
|
|
38
|
-
'title',
|
|
39
|
-
'"thumbnail_url": thumbnail.asset->url',
|
|
40
|
-
'"style": genre[0]->name',
|
|
41
|
-
'"artist": artist->name',
|
|
42
|
-
'album',
|
|
43
|
-
'instrumentless',
|
|
44
|
-
'soundslice',
|
|
45
|
-
'"resources": resource[]{resource_url, resource_name}',
|
|
46
|
-
'"url": web_url_path',
|
|
47
|
-
];
|
|
48
21
|
|
|
49
22
|
const query = `
|
|
50
23
|
*[_type == "song" && railcontent_id == ${documentId}]{
|
|
51
|
-
${
|
|
24
|
+
${getFieldsForContentType('song', true)}
|
|
52
25
|
}`;
|
|
53
26
|
|
|
54
27
|
return fetchSanity(query, false);
|
|
@@ -249,10 +222,10 @@ export async function fetchSongCount(brand) {
|
|
|
249
222
|
* Fetch the latest workouts for a specific brand, including completion status and progress.
|
|
250
223
|
* This function retrieves up to five of the latest workout content for a given brand, sorted in descending order by their publication date.
|
|
251
224
|
* It also includes completion status and progress percentage for each workout by fetching additional data about user progress.
|
|
252
|
-
*
|
|
225
|
+
*
|
|
253
226
|
* @param {string} brand - The brand for which to fetch workouts (e.g., 'drumeo', 'pianote').
|
|
254
227
|
* @returns {Promise<Array<Object>|null>} - A promise that resolves to an array of workout data objects with additional properties for completion status and progress percentage, or null if no workouts are found.
|
|
255
|
-
*
|
|
228
|
+
*
|
|
256
229
|
* @example
|
|
257
230
|
* fetchWorkouts('drumeo')
|
|
258
231
|
* .then(workouts => console.log(workouts))
|
|
@@ -263,12 +236,12 @@ export async function fetchWorkouts(brand) {
|
|
|
263
236
|
"id": railcontent_id,
|
|
264
237
|
title,
|
|
265
238
|
"image": thumbnail.asset->url,
|
|
266
|
-
|
|
267
|
-
|
|
239
|
+
${artistOrInstructor()},
|
|
240
|
+
${artistOrInstructorAsArray()},
|
|
268
241
|
difficulty,
|
|
269
242
|
difficulty_string,
|
|
270
243
|
length_in_seconds,
|
|
271
|
-
published_on
|
|
244
|
+
published_on,;
|
|
272
245
|
"type": _type,
|
|
273
246
|
web_url_path,
|
|
274
247
|
} | order(published_on desc)[0...5]`
|
|
@@ -356,17 +329,9 @@ export async function fetchUpcomingEvents(brand) {
|
|
|
356
329
|
* .then(content => console.log(content))
|
|
357
330
|
* .catch(error => console.error(error));
|
|
358
331
|
*/
|
|
359
|
-
export async function fetchByRailContentId(id) {
|
|
332
|
+
export async function fetchByRailContentId(id, contentType) {
|
|
360
333
|
const query = `*[railcontent_id == ${id}]{
|
|
361
|
-
|
|
362
|
-
title,
|
|
363
|
-
"image": thumbnail.asset->url,
|
|
364
|
-
"artist_name": artist->name,
|
|
365
|
-
artist,
|
|
366
|
-
difficulty,
|
|
367
|
-
difficulty_string,
|
|
368
|
-
web_url_path,
|
|
369
|
-
published_on
|
|
334
|
+
${getFieldsForContentType(contentType)}
|
|
370
335
|
}`
|
|
371
336
|
return fetchSanity(query, false);
|
|
372
337
|
}
|
|
@@ -384,10 +349,9 @@ export async function fetchByRailContentId(id) {
|
|
|
384
349
|
* .catch(error => console.error(error));
|
|
385
350
|
*/
|
|
386
351
|
export async function fetchByRailContentIds(ids, contentType = undefined) {
|
|
387
|
-
const fields = contentType ? DEFAULT_FIELDS.concat(contentTypeConfig?.[contentType]?.fields ?? []) : DEFAULT_FIELDS;
|
|
388
352
|
const idsString = ids.join(',');
|
|
389
353
|
const query = `*[railcontent_id in [${idsString}]]{
|
|
390
|
-
${
|
|
354
|
+
${getFieldsForContentType(contentType)}
|
|
391
355
|
}`
|
|
392
356
|
return fetchSanity(query, true);
|
|
393
357
|
}
|
|
@@ -448,37 +412,7 @@ export async function fetchAll(brand, type, {
|
|
|
448
412
|
: "";
|
|
449
413
|
|
|
450
414
|
// Determine the sort order
|
|
451
|
-
|
|
452
|
-
switch (sort) {
|
|
453
|
-
case "slug":
|
|
454
|
-
if(groupBy){
|
|
455
|
-
sortOrder = "name asc";
|
|
456
|
-
} else {
|
|
457
|
-
sortOrder = "title asc";
|
|
458
|
-
}
|
|
459
|
-
|
|
460
|
-
break;
|
|
461
|
-
case "published_on":
|
|
462
|
-
sortOrder = "published_on asc";
|
|
463
|
-
break;
|
|
464
|
-
case "-published_on":
|
|
465
|
-
sortOrder = "published_on desc";
|
|
466
|
-
break;
|
|
467
|
-
case "-slug":
|
|
468
|
-
if(groupBy){
|
|
469
|
-
sortOrder = "name desc";
|
|
470
|
-
} else {
|
|
471
|
-
sortOrder = "title desc";
|
|
472
|
-
}
|
|
473
|
-
|
|
474
|
-
break;
|
|
475
|
-
case "-popularity":
|
|
476
|
-
sortOrder = "popularity desc";
|
|
477
|
-
break;
|
|
478
|
-
default:
|
|
479
|
-
sortOrder = "published_on asc";
|
|
480
|
-
break;
|
|
481
|
-
}
|
|
415
|
+
const sortOrder = getSortOrder(sort);
|
|
482
416
|
|
|
483
417
|
let fields = DEFAULT_FIELDS.concat(additionalFields);
|
|
484
418
|
let fieldsString = fields.join(',');
|
|
@@ -537,6 +471,28 @@ export async function fetchAll(brand, type, {
|
|
|
537
471
|
return fetchSanity(query, true);
|
|
538
472
|
}
|
|
539
473
|
|
|
474
|
+
export function getSortOrder(sort= '-published_on', groupBy)
|
|
475
|
+
{
|
|
476
|
+
// Determine the sort order
|
|
477
|
+
let sortOrder = '';
|
|
478
|
+
const isDesc = sort.startsWith('-');
|
|
479
|
+
sort = isDesc ? sort.substring(1) : sort;
|
|
480
|
+
switch (sort) {
|
|
481
|
+
case "slug":
|
|
482
|
+
sortOrder = groupBy ? 'name' : "title";
|
|
483
|
+
break;
|
|
484
|
+
case "popularity":
|
|
485
|
+
sortOrder = "popularity";
|
|
486
|
+
break;
|
|
487
|
+
case "published_on":
|
|
488
|
+
default:
|
|
489
|
+
sortOrder = "published_on";
|
|
490
|
+
break;
|
|
491
|
+
}
|
|
492
|
+
sortOrder += isDesc ? ' desc' : ' asc';
|
|
493
|
+
return sortOrder;
|
|
494
|
+
}
|
|
495
|
+
|
|
540
496
|
/**
|
|
541
497
|
* Fetches all available filter options based on various criteria such as brand, filters, style, artist, content type, and search term.
|
|
542
498
|
*
|
|
@@ -574,10 +530,10 @@ export async function fetchAllFilterOptions(
|
|
|
574
530
|
return `&& ${key} == "${value}"`;
|
|
575
531
|
}).join(' ')
|
|
576
532
|
: undefined;
|
|
577
|
-
|
|
533
|
+
|
|
578
534
|
const commonFilter = `_type == '${contentType}' && brand == "${brand}"${style ? ` && '${style}' in genre[]->name` : ''}${artist ? ` && artist->name == '${artist}'` : ''} ${filtersToGroq ? filtersToGroq : ''}`;
|
|
579
535
|
const query = `
|
|
580
|
-
{
|
|
536
|
+
{
|
|
581
537
|
"meta": {
|
|
582
538
|
"totalResults": count(*[${commonFilter}
|
|
583
539
|
${term ? ` && (title match "${term}" || album match "${term}" || artist->name match "${term}" || genre[]->name match "${term}")` : ''}]),
|
|
@@ -606,22 +562,33 @@ export async function fetchAllFilterOptions(
|
|
|
606
562
|
/**
|
|
607
563
|
* Fetch children content by Railcontent ID.
|
|
608
564
|
* @param {string} railcontentId - The Railcontent ID of the parent content.
|
|
609
|
-
* @returns {Promise<Array<Object>|null>} - The fetched children content data or
|
|
565
|
+
* @returns {Promise<Array<Object>|null>} - The fetched children content data or [] if not found.
|
|
610
566
|
*/
|
|
611
567
|
export async function fetchChildren(railcontentId) {
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
568
|
+
const query = `*[railcontent_id == ${railcontentId}]{
|
|
569
|
+
'children': child[]->{
|
|
570
|
+
${getFieldsForContentType()}
|
|
571
|
+
},
|
|
572
|
+
}[0..1]`;
|
|
573
|
+
let parent = await fetchSanity(query, true);
|
|
574
|
+
return parent[0]['children'] ?? [];
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
/**
|
|
578
|
+
*
|
|
579
|
+
* @param railcontentId - railcontent id of the child
|
|
580
|
+
* @returns {Promise<Array<string>|null>} - The fetched parent content data or [] if not found
|
|
581
|
+
*/
|
|
582
|
+
export async function fetchParentByRailContentId(railcontentId) {
|
|
583
|
+
const query = `*[railcontent_id == ${railcontentId}]{
|
|
584
|
+
'parents': array::unique([
|
|
585
|
+
...(*[references(^._id)]{
|
|
586
|
+
${getFieldsForContentType()}
|
|
587
|
+
})
|
|
588
|
+
])
|
|
589
|
+
}[0...1]`;
|
|
590
|
+
let child = await fetchSanity(query, true);
|
|
591
|
+
return child[0]['parents'][0] ?? [];
|
|
625
592
|
}
|
|
626
593
|
|
|
627
594
|
/**
|
|
@@ -630,31 +597,11 @@ export async function fetchChildren(railcontentId) {
|
|
|
630
597
|
* @returns {Promise<Object|null>} - The fetched methods data or null if not found.
|
|
631
598
|
*/
|
|
632
599
|
export async function fetchMethods(brand) {
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
"description": description[0].children[0].text,
|
|
638
|
-
hide_from_recsys,
|
|
639
|
-
"image": thumbnail.asset->url,
|
|
640
|
-
"instructors":instructor[]->name,
|
|
641
|
-
"lesson_count": child_count,
|
|
642
|
-
length_in_seconds,
|
|
643
|
-
permission,
|
|
644
|
-
popularity,
|
|
600
|
+
//TODOS
|
|
601
|
+
//ADD INSTRUCTORS AND POSITION
|
|
602
|
+
const query = `*[_type == 'learning-path' && brand == '${brand}'] {
|
|
603
|
+
${getFieldsForContentType('method')}
|
|
645
604
|
"position": count(*[_type == 'learning-path' && brand == '${brand}' && (published_on < ^.published_on || (published_on == ^.published_on && _id < ^._id))]) + 1,
|
|
646
|
-
published_on,
|
|
647
|
-
railcontent_id,
|
|
648
|
-
"slug": slug.current,
|
|
649
|
-
status,
|
|
650
|
-
"thumbnail": thumbnail.asset->url,
|
|
651
|
-
"thumbnail_logo": logo_image_url.asset->url,
|
|
652
|
-
title,
|
|
653
|
-
total_xp,
|
|
654
|
-
"type": _type,
|
|
655
|
-
web_url_path,
|
|
656
|
-
"url": web_url_path,
|
|
657
|
-
xp,
|
|
658
605
|
} | order(published_on asc)`
|
|
659
606
|
return fetchSanity(query, true);
|
|
660
607
|
}
|
|
@@ -684,6 +631,7 @@ export async function fetchMethod(brand, slug) {
|
|
|
684
631
|
"thumbnail_url": thumbnail.asset->url,
|
|
685
632
|
"instructor": instructor[]->{name},
|
|
686
633
|
title,
|
|
634
|
+
"type": _type,
|
|
687
635
|
"description": description[0].children[0].text,
|
|
688
636
|
}
|
|
689
637
|
} | order(published_on asc)`
|
|
@@ -693,22 +641,36 @@ return fetchSanity(query, false);
|
|
|
693
641
|
/**
|
|
694
642
|
* Fetch the next lesson for a specific method by Railcontent ID.
|
|
695
643
|
* @param {string} railcontentId - The Railcontent ID of the current lesson.
|
|
644
|
+
* @param {string} methodId - The RailcontentID of the method
|
|
696
645
|
* @returns {Promise<Object|null>} - The fetched next lesson data or null if not found.
|
|
697
646
|
*/
|
|
698
|
-
export async function fetchMethodNextLesson(railcontentId) {
|
|
699
|
-
|
|
700
|
-
const
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
647
|
+
export async function fetchMethodNextLesson(railcontentId, methodId) {
|
|
648
|
+
const sortedChildren = await fetchMethodChildrenIds(methodId);
|
|
649
|
+
const index = sortedChildren.indexOf(railcontentId);
|
|
650
|
+
const childIndex = sortedChildren[index + 1];
|
|
651
|
+
return childIndex ? await fetchByRailContentId(childIndex) : null;
|
|
652
|
+
}
|
|
653
|
+
|
|
654
|
+
|
|
655
|
+
/**
|
|
656
|
+
* Fetch the next lesson for a specific method by Railcontent ID.
|
|
657
|
+
* @param {string} railcontentId - The Railcontent ID of the current lesson.
|
|
658
|
+
* @param {string} methodId - The RailcontentID of the method
|
|
659
|
+
* @returns {Promise<Object|null>} - object with `nextLesson` and `previousLesson` attributes
|
|
660
|
+
* @example
|
|
661
|
+
* fetchMethodPreviousNextLesson(241284, 241247)
|
|
662
|
+
* .then(data => { console.log('nextLesson', data.nextLesson); console.log('prevlesson', data.prevLesson);})
|
|
663
|
+
* .catch(error => console.error(error));
|
|
664
|
+
*/
|
|
665
|
+
export async function fetchMethodPreviousNextLesson(railcontentId, methodId) {
|
|
666
|
+
const sortedChildren = await fetchMethodChildrenIds(methodId);
|
|
667
|
+
const index = sortedChildren.indexOf(railcontentId);
|
|
668
|
+
let nextId = sortedChildren[index + 1];
|
|
669
|
+
let previousId = sortedChildren[index -1];
|
|
670
|
+
let nextPrev = await fetchByRailContentIds([nextId, previousId]);
|
|
671
|
+
const nextLesson = nextPrev.find((elem) => {return elem['id'] === nextId});
|
|
672
|
+
const prevLesson = nextPrev.find((elem) => {return elem['id'] === previousId});
|
|
673
|
+
return {nextLesson, prevLesson};
|
|
712
674
|
}
|
|
713
675
|
|
|
714
676
|
/**
|
|
@@ -716,11 +678,37 @@ export async function fetchMethodNextLesson(railcontentId) {
|
|
|
716
678
|
* @param {string} railcontentId - The Railcontent ID of the method.
|
|
717
679
|
* @returns {Promise<Array<Object>|null>} - The fetched children data or null if not found.
|
|
718
680
|
*/
|
|
719
|
-
export async function
|
|
681
|
+
export async function fetchMethodChildrenIds(railcontentId) {
|
|
720
682
|
//TODO: Implement getByParentId include sum XP
|
|
721
|
-
|
|
683
|
+
const query = `*[_type == 'learning-path' && railcontent_id == ${railcontentId}]{
|
|
684
|
+
'children': child[]-> {
|
|
685
|
+
'id': railcontent_id,
|
|
686
|
+
'children': child[]-> {
|
|
687
|
+
'id': railcontent_id,
|
|
688
|
+
'children': child[]-> {
|
|
689
|
+
'id': railcontent_id,
|
|
690
|
+
}
|
|
691
|
+
}
|
|
692
|
+
}
|
|
693
|
+
}`;
|
|
694
|
+
let allChildren = await fetchSanity(query, false);
|
|
695
|
+
return getChildrenToDepth(allChildren, 4);;
|
|
722
696
|
}
|
|
723
697
|
|
|
698
|
+
function getChildrenToDepth(parent, depth = 1)
|
|
699
|
+
{
|
|
700
|
+
let allChildrenIds = [];
|
|
701
|
+
if (parent['children']) {
|
|
702
|
+
parent['children'].forEach((child) => {
|
|
703
|
+
allChildrenIds.push(child['id']);
|
|
704
|
+
allChildrenIds = allChildrenIds.concat(getChildrenToDepth(child, depth-1));
|
|
705
|
+
})
|
|
706
|
+
}
|
|
707
|
+
return allChildrenIds;
|
|
708
|
+
}
|
|
709
|
+
|
|
710
|
+
|
|
711
|
+
|
|
724
712
|
/**
|
|
725
713
|
* Fetch the next and previous lessons for a specific lesson by Railcontent ID.
|
|
726
714
|
* @param {string} railcontentId - The Railcontent ID of the current lesson.
|
|
@@ -759,22 +747,15 @@ export async function fetchLessonContent(railContentId) {
|
|
|
759
747
|
chapter_description,
|
|
760
748
|
chapter_timecode,
|
|
761
749
|
"chapter_thumbnail_url": chapter_thumbnail_url.asset->url
|
|
762
|
-
},
|
|
750
|
+
},
|
|
763
751
|
"coaches": instructor[]-> {
|
|
764
|
-
name,
|
|
752
|
+
name,
|
|
765
753
|
"id":_id,
|
|
766
754
|
"coach_profile_image":thumbnail_url.asset->url
|
|
767
755
|
},
|
|
768
756
|
"instructors":instructor[]->name,
|
|
769
757
|
instructor[]->,
|
|
770
|
-
|
|
771
|
-
"id": railcontent_id,
|
|
772
|
-
"soundslice_slug": assignment_soundslice,
|
|
773
|
-
"title": assignment_title,
|
|
774
|
-
"sheet_music_image_url": assignment_sheet_music_image,
|
|
775
|
-
"timecode": assignment_timecode,
|
|
776
|
-
"description": assignment_description
|
|
777
|
-
},
|
|
758
|
+
${assignmentsField}
|
|
778
759
|
video}`
|
|
779
760
|
return fetchSanity(query, false);
|
|
780
761
|
}
|
|
@@ -840,7 +821,7 @@ export async function fetchPackChildren(railcontentId) {
|
|
|
840
821
|
* Fetch the data needed for the Course Overview screen.
|
|
841
822
|
* @param {string} id - The Railcontent ID of the course
|
|
842
823
|
* @returns {Promise<Object|null>} - The course information and lessons or null if not found.
|
|
843
|
-
*
|
|
824
|
+
*
|
|
844
825
|
* @example
|
|
845
826
|
* fetchCourseOverview('course123')
|
|
846
827
|
* .then(course => console.log(course))
|
|
@@ -925,6 +906,32 @@ export async function fetchSanity(query, isList) {
|
|
|
925
906
|
}
|
|
926
907
|
}
|
|
927
908
|
|
|
909
|
+
/**
|
|
910
|
+
* Fetch CatalogueMetadata from Sanity. This information may be duplicated in the contentTypeConfig.js.
|
|
911
|
+
* It's an ongoing discussion (Aug 2024), but it's been included here if necessary
|
|
912
|
+
*
|
|
913
|
+
* @param {string} contentType - name of the contentype to pull
|
|
914
|
+
* @returns {Promise<Object|null>} - A promise that resolves to the fetched data or null if an error occurs or no results are found.
|
|
915
|
+
*
|
|
916
|
+
* @example
|
|
917
|
+
*
|
|
918
|
+
* fetchCatalogMetadata('song')
|
|
919
|
+
* .then(data => console.log(data))
|
|
920
|
+
* .catch(error => console.error(error));
|
|
921
|
+
*/
|
|
922
|
+
export async function fetchCatalogMetadata(contentType)
|
|
923
|
+
{ const query = `*[_type == 'CatalogMetadata']{
|
|
924
|
+
catalog_type,
|
|
925
|
+
brand,
|
|
926
|
+
groq_results,
|
|
927
|
+
groq_search_fields,
|
|
928
|
+
meta_data_groq,
|
|
929
|
+
modal_text,
|
|
930
|
+
sort_by,
|
|
931
|
+
}`
|
|
932
|
+
return fetchSanity(query, false);
|
|
933
|
+
}
|
|
934
|
+
|
|
928
935
|
|
|
929
936
|
//Helper Functions
|
|
930
937
|
function arrayJoinWithQuotes(array, delimiter = ',') {
|
|
@@ -955,3 +962,5 @@ function checkSanityConfig(config) {
|
|
|
955
962
|
}
|
|
956
963
|
return true;
|
|
957
964
|
}
|
|
965
|
+
|
|
966
|
+
|
|
@@ -16,12 +16,15 @@ const {
|
|
|
16
16
|
fetchAll,
|
|
17
17
|
fetchAllFilterOptions,
|
|
18
18
|
fetchMethodNextLesson,
|
|
19
|
-
|
|
19
|
+
fetchMethodChildrenIds,
|
|
20
20
|
fetchNextPreviousLesson,
|
|
21
21
|
fetchRelatedLessons,
|
|
22
22
|
fetchPackAll,
|
|
23
23
|
fetchPackChildren,
|
|
24
24
|
fetchLessonContent,
|
|
25
|
+
getSortOrder,
|
|
26
|
+
fetchParentByRailContentId,
|
|
27
|
+
fetchChildren,
|
|
25
28
|
fetchMethod,
|
|
26
29
|
fetchMethods,
|
|
27
30
|
} = require('../src/services/sanity.js');
|
|
@@ -44,7 +47,7 @@ describe('Sanity Queries', function () {
|
|
|
44
47
|
test('fetchSongById', async () => {
|
|
45
48
|
const id = 380094;
|
|
46
49
|
const response = await fetchSongById(id);
|
|
47
|
-
expect(response.
|
|
50
|
+
expect(response.id).toBe(id);
|
|
48
51
|
|
|
49
52
|
});
|
|
50
53
|
|
|
@@ -64,14 +67,14 @@ describe('Sanity Queries', function () {
|
|
|
64
67
|
test('fetchByRailContentId', async () => {
|
|
65
68
|
const id = 380094;
|
|
66
69
|
const response = await fetchByRailContentId(id);
|
|
67
|
-
expect(response.
|
|
70
|
+
expect(response.id).toBe(id);
|
|
68
71
|
});
|
|
69
72
|
|
|
70
73
|
test('fetchByRailContentIds', async () => {
|
|
71
74
|
const id = 380094;
|
|
72
75
|
const id2 = 402204;
|
|
73
76
|
const response = await fetchByRailContentIds([id, id2]);
|
|
74
|
-
const returnedIds = response.map((x) => x.
|
|
77
|
+
const returnedIds = response.map((x) => x.id);
|
|
75
78
|
expect(returnedIds).toContain(id);
|
|
76
79
|
expect(returnedIds).toContain(id2);
|
|
77
80
|
expect(returnedIds.length).toBe(2);
|
|
@@ -81,7 +84,7 @@ describe('Sanity Queries', function () {
|
|
|
81
84
|
test('fetchLessonContent', async () => {
|
|
82
85
|
const id = 380094;
|
|
83
86
|
const response = await fetchLessonContent(id);
|
|
84
|
-
expect(response.
|
|
87
|
+
expect(response.id).toBe(id);
|
|
85
88
|
});
|
|
86
89
|
|
|
87
90
|
test('fetchAllSongs', async () => {
|
|
@@ -103,7 +106,7 @@ describe('Sanity Queries', function () {
|
|
|
103
106
|
test('fetchAllWorkouts', async () => {
|
|
104
107
|
const response = await fetchAll('drumeo', 'workout',{});
|
|
105
108
|
console.log(response);
|
|
106
|
-
expect(response.entity[0].
|
|
109
|
+
expect(response.entity[0].id).toBeDefined();
|
|
107
110
|
});
|
|
108
111
|
|
|
109
112
|
test('fetchAllChallenges', async () => {
|
|
@@ -120,6 +123,58 @@ describe('Sanity Queries', function () {
|
|
|
120
123
|
|
|
121
124
|
});
|
|
122
125
|
|
|
126
|
+
test('fetchRelatedLessons', async () => {
|
|
127
|
+
const id = 380094;
|
|
128
|
+
const document = await fetchByRailContentId(id);
|
|
129
|
+
let artist = document.artist.name;
|
|
130
|
+
const response = await fetchRelatedLessons(id, 'singeo', 'song');
|
|
131
|
+
let relatedDoc = await fetchByRailContentId(response.related_lessons[0].id);
|
|
132
|
+
// match on artist or any genre
|
|
133
|
+
let isMatch = artist === relatedDoc.artist.name;
|
|
134
|
+
isMatch = isMatch || document.genre.some((genre) => {
|
|
135
|
+
return relatedDoc.genre.some((relatedGenre) => {
|
|
136
|
+
return genre._ref === relatedGenre._ref;
|
|
137
|
+
});
|
|
138
|
+
});
|
|
139
|
+
expect(isMatch).toBeTruthy();
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
test('fetchChildren', async () => {
|
|
143
|
+
// complement test to fetchParentByRailContentId
|
|
144
|
+
const id = 191338; ////https://web-staging-one.musora.com/admin/studio/publishing/structure/play-along;play-along_191338
|
|
145
|
+
const expectedChildID = 191492;
|
|
146
|
+
const response = await fetchChildren(id);
|
|
147
|
+
console.log('num children', response.length);
|
|
148
|
+
console.log(response);
|
|
149
|
+
|
|
150
|
+
expect(response.length > 0).toBeTruthy();
|
|
151
|
+
const foundExpectedChild = response.some((child) => {
|
|
152
|
+
return child['id'] = expectedChildID;
|
|
153
|
+
});
|
|
154
|
+
expect(foundExpectedChild).toBeTruthy();
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
test('fetchParentByRailContentId', async () => {
|
|
158
|
+
// complement test to fetchChildren
|
|
159
|
+
const childId = 191492; // child of https://web-staging-one.musora.com/admin/studio/publishing/structure/play-along;play-along_191338
|
|
160
|
+
const expectedParent = 191338;
|
|
161
|
+
const response = await fetchParentByRailContentId(childId);
|
|
162
|
+
expect(response['id']).toBe(expectedParent);
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
test('getSortOrder', () => {
|
|
166
|
+
let sort = getSortOrder()
|
|
167
|
+
expect(sort).toBe('published_on desc');
|
|
168
|
+
sort = getSortOrder('slug')
|
|
169
|
+
expect(sort).toBe('title asc');
|
|
170
|
+
sort = getSortOrder('-slug')
|
|
171
|
+
expect(sort).toBe('title desc');
|
|
172
|
+
sort = getSortOrder('-slug', true)
|
|
173
|
+
expect(sort).toBe('name desc');
|
|
174
|
+
sort = getSortOrder('published-on')
|
|
175
|
+
expect(sort).toBe('published_on asc');
|
|
176
|
+
});
|
|
177
|
+
|
|
123
178
|
test('fetchMethod', async () => {
|
|
124
179
|
const response = await fetchMethod('drumeo', 'drumeo-method');
|
|
125
180
|
//console.log(response);
|
|
@@ -133,10 +188,4 @@ describe('Sanity Queries', function () {
|
|
|
133
188
|
expect(response.length).toBeGreaterThan(0);
|
|
134
189
|
expect(response[0].type).toBe('learning-path');
|
|
135
190
|
});
|
|
136
|
-
// test('fetchRelatedLessons', async () => {
|
|
137
|
-
// const id = 380094;
|
|
138
|
-
// const response = await fetchRelatedLessons(id, 'singeo', 'song');
|
|
139
|
-
// console.log(response.related_lessons[0]);
|
|
140
|
-
// expect(response.related_lessons[0]).toBe(id);
|
|
141
|
-
// });
|
|
142
191
|
});
|