musora-content-services 1.0.141 → 1.0.143
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 +4 -0
- package/docs/config.js.html +8 -4
- package/docs/index.html +2 -2
- package/docs/module-Config.html +30 -5
- package/docs/module-Railcontent-Services.html +2 -2
- package/docs/module-Sanity-Services.html +285 -46
- package/docs/railcontent.js.html +19 -2
- package/docs/sanity.js.html +79 -73
- package/link_mcs.sh +0 -0
- package/package.json +1 -1
- package/src/contentTypeConfig.js +43 -0
- package/src/index.d.ts +9 -1
- package/src/index.js +9 -1
- package/src/services/dataContext.js +3 -1
- package/src/services/railcontent.js +17 -0
- package/src/services/sanity.js +77 -71
package/src/services/sanity.js
CHANGED
|
@@ -586,101 +586,84 @@ export function getSortOrder(sort= '-published_on', groupBy)
|
|
|
586
586
|
}
|
|
587
587
|
|
|
588
588
|
/**
|
|
589
|
-
* Fetches all available filter options based on
|
|
589
|
+
* Fetches all available filter options based on brand, filters, and various optional criteria.
|
|
590
590
|
*
|
|
591
591
|
* This function constructs a query to retrieve the total number of results and filter options such as difficulty, instrument type, and genre.
|
|
592
592
|
* The filter options are dynamically generated based on the provided filters, style, artist, and content type.
|
|
593
593
|
* If a coachId is provided, the content type must be 'coach-lessons'.
|
|
594
594
|
*
|
|
595
|
-
* @param {string} brand -
|
|
596
|
-
* @param {string[]} filters -
|
|
597
|
-
* @param {string} [style] - Optional style
|
|
598
|
-
* @param {string} [artist] - Optional artist name
|
|
599
|
-
* @param {string} contentType -
|
|
600
|
-
* @param {string} [term] - Optional search term
|
|
601
|
-
* @param {Array<string>} [progressIds
|
|
602
|
-
* @param {string} [coachId
|
|
603
|
-
* @
|
|
595
|
+
* @param {string} brand - Brand to filter.
|
|
596
|
+
* @param {string[]} filters - Key-value pairs to filter the query.
|
|
597
|
+
* @param {string} [style] - Optional style/genre filter.
|
|
598
|
+
* @param {string} [artist] - Optional artist name filter.
|
|
599
|
+
* @param {string} contentType - Content type (e.g., 'song', 'lesson').
|
|
600
|
+
* @param {string} [term] - Optional search term for title, album, artist, or genre.
|
|
601
|
+
* @param {Array<string>} [progressIds] - Optional array of progress IDs to filter by.
|
|
602
|
+
* @param {string} [coachId] - Optional coach ID (only valid if contentType is 'coach-lessons').
|
|
603
|
+
* @param {boolean} [includeTabs=false] - Whether to include tabs in the returned metadata.
|
|
604
|
+
* @returns {Promise<Object>} - The filter options and metadata.
|
|
605
|
+
* @throws {Error} If coachId is provided but contentType isn't 'coach-lessons'.
|
|
604
606
|
*
|
|
605
|
-
* @throws {Error} Will throw an error if coachId is provided but contentType is not 'coach-lessons'.
|
|
606
|
-
*
|
|
607
607
|
* @example
|
|
608
|
-
* //
|
|
609
|
-
* fetchAllFilterOptions('myBrand',
|
|
608
|
+
* // Fetch filter options for 'song' content type:
|
|
609
|
+
* fetchAllFilterOptions('myBrand', [], 'Rock', 'John Doe', 'song', 'Love')
|
|
610
610
|
* .then(options => console.log(options))
|
|
611
611
|
* .catch(error => console.error(error));
|
|
612
612
|
*
|
|
613
613
|
* @example
|
|
614
|
-
* //
|
|
615
|
-
* fetchAllFilterOptions('myBrand',
|
|
614
|
+
* // Fetch filter options for a coach's lessons with coachId:
|
|
615
|
+
* fetchAllFilterOptions('myBrand', [], 'Rock', 'John Doe', 'coach-lessons', 'Love', undefined, '123')
|
|
616
616
|
* .then(options => console.log(options))
|
|
617
617
|
* .catch(error => console.error(error));
|
|
618
618
|
*/
|
|
619
619
|
export async function fetchAllFilterOptions(
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
620
|
+
brand,
|
|
621
|
+
filters = [],
|
|
622
|
+
style,
|
|
623
|
+
artist,
|
|
624
|
+
contentType,
|
|
625
|
+
term,
|
|
626
|
+
progressIds,
|
|
627
|
+
coachId,
|
|
628
|
+
includeTabs = false,
|
|
628
629
|
) {
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
}
|
|
633
|
-
|
|
634
|
-
filters = Array.isArray(filters) ? filters : [];
|
|
635
|
-
const includedFieldsFilter = filters?.length > 0 ? filtersToGroq(filters) : undefined;
|
|
636
|
-
|
|
637
|
-
const progressFilter = progressIds !== undefined ?
|
|
638
|
-
`&& railcontent_id in [${progressIds.join(',')}]` : "";
|
|
630
|
+
if (coachId && contentType !== 'coach-lessons') {
|
|
631
|
+
throw new Error(`Invalid contentType: '${contentType}' for coachId. It must be 'coach-lessons'.`);
|
|
632
|
+
}
|
|
639
633
|
|
|
640
|
-
|
|
641
|
-
|
|
634
|
+
const includedFieldsFilter = filters?.length ? filtersToGroq(filters) : undefined;
|
|
635
|
+
const progressFilter = progressIds ? `&& railcontent_id in [${progressIds.join(',')}]` : "";
|
|
642
636
|
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
}
|
|
637
|
+
const constructCommonFilter = (excludeFilter) => {
|
|
638
|
+
const filterWithoutOption = excludeFilter ? filtersToGroq(filters, excludeFilter) : includedFieldsFilter;
|
|
639
|
+
return coachId
|
|
640
|
+
? `brand == '${brand}' && references(*[_type=='instructor' && railcontent_id == ${coachId}]._id) ${filterWithoutOption || ''}`
|
|
641
|
+
: `_type == '${contentType}' && brand == "${brand}"${style && excludeFilter !== "style" ? ` && '${style}' in genre[]->name` : ''}${artist && excludeFilter !== "artist" ? ` && artist->name == '${artist}'` : ''} ${progressFilter} ${filterWithoutOption || ''}`;
|
|
642
|
+
};
|
|
650
643
|
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
644
|
+
const metaData = processMetadata(brand, contentType, true);
|
|
645
|
+
const allowableFilters = metaData?.allowableFilters || [];
|
|
646
|
+
const tabs = metaData?.tabs || [];
|
|
654
647
|
|
|
655
|
-
|
|
656
|
-
const dynamicFilterOptions = allowableFilters.map(filter => {
|
|
657
|
-
let includedFieldsFilterWithoutSelectedOption = filters?.length > 0 ? filtersToGroq(filters, filter) : undefined;
|
|
658
|
-
let commonFilterWithoutSelectedOption;
|
|
648
|
+
const dynamicFilterOptions = allowableFilters.map(filter => getFilterOptions(filter, constructCommonFilter(filter), contentType, brand)).join(' ');
|
|
659
649
|
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
650
|
+
const query = `
|
|
651
|
+
{
|
|
652
|
+
"meta": {
|
|
653
|
+
"totalResults": count(*[${constructCommonFilter()}
|
|
654
|
+
${term ? ` && (title match "${term}" || album match "${term}" || artist->name match "${term}" || genre[]->name match "${term}")` : ''}]),
|
|
655
|
+
"filterOptions": {
|
|
656
|
+
${dynamicFilterOptions}
|
|
657
|
+
}
|
|
658
|
+
}
|
|
659
|
+
}`;
|
|
666
660
|
|
|
667
|
-
|
|
668
|
-
return getFilterOptions(filter, commonFilterWithoutSelectedOption, contentType, brand);
|
|
669
|
-
}).join(' ');
|
|
661
|
+
const results = await fetchSanity(query, true, { processNeedAccess: false });
|
|
670
662
|
|
|
671
|
-
|
|
672
|
-
{
|
|
673
|
-
"meta": {
|
|
674
|
-
"totalResults": count(*[${commonFilter}
|
|
675
|
-
${term ? ` && (title match "${term}" || album match "${term}" || artist->name match "${term}" || genre[]->name match "${term}")` : ''}]),
|
|
676
|
-
"filterOptions": {
|
|
677
|
-
${dynamicFilterOptions}
|
|
678
|
-
}
|
|
679
|
-
}
|
|
680
|
-
}`;
|
|
681
|
-
return fetchSanity(query, true, {processNeedAccess:false});
|
|
663
|
+
return includeTabs ? { ...results, tabs } : results;
|
|
682
664
|
}
|
|
683
665
|
|
|
666
|
+
|
|
684
667
|
/**
|
|
685
668
|
* Fetch children content by Railcontent ID.
|
|
686
669
|
* @param {string} railcontentId - The Railcontent ID of the parent content.
|
|
@@ -961,7 +944,8 @@ export async function fetchLessonContent(railContentId) {
|
|
|
961
944
|
mp3_yes_drums_yes_click_url,
|
|
962
945
|
"permission_id": permission[]->railcontent_id,
|
|
963
946
|
parent_content_data,
|
|
964
|
-
sort
|
|
947
|
+
sort,
|
|
948
|
+
xp`;
|
|
965
949
|
const query = buildQuery(
|
|
966
950
|
`railcontent_id == ${railContentId}`,
|
|
967
951
|
filterParams,
|
|
@@ -1211,6 +1195,28 @@ export async function fetchCourseOverview(id) {
|
|
|
1211
1195
|
return fetchByRailContentId(id, 'course');
|
|
1212
1196
|
}
|
|
1213
1197
|
|
|
1198
|
+
/**
|
|
1199
|
+
* Fetch the data needed for the Course Overview screen.
|
|
1200
|
+
* @param {string} id - The Railcontent ID of the course
|
|
1201
|
+
* @returns {Promise<Object|null>} - The course information and lessons or null if not found.
|
|
1202
|
+
*
|
|
1203
|
+
* @example
|
|
1204
|
+
* fetchParentForDownload('course123')
|
|
1205
|
+
* .then(course => console.log(course))
|
|
1206
|
+
* .catch(error => console.error(error));
|
|
1207
|
+
*/
|
|
1208
|
+
export async function fetchParentForDownload(id) {
|
|
1209
|
+
const query = buildRawQuery(
|
|
1210
|
+
`railcontent_id == ${id}`,
|
|
1211
|
+
getFieldsForContentType('parent-download'),
|
|
1212
|
+
{
|
|
1213
|
+
isSingle: true,
|
|
1214
|
+
},
|
|
1215
|
+
);
|
|
1216
|
+
|
|
1217
|
+
return fetchSanity(query, false);
|
|
1218
|
+
}
|
|
1219
|
+
|
|
1214
1220
|
/**
|
|
1215
1221
|
* Fetch the data needed for the coach screen.
|
|
1216
1222
|
* @param {string} id - The Railcontent ID of the coach
|