musora-content-services 1.0.137 → 1.0.139

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. package/.github/workflows/node.js.yml +0 -0
  2. package/CHANGELOG.md +4 -0
  3. package/README.md +0 -0
  4. package/babel.config.js +0 -0
  5. package/docs/config.js.html +10 -3
  6. package/docs/fonts/Montserrat/Montserrat-Bold.eot +0 -0
  7. package/docs/fonts/Montserrat/Montserrat-Bold.ttf +0 -0
  8. package/docs/fonts/Montserrat/Montserrat-Bold.woff +0 -0
  9. package/docs/fonts/Montserrat/Montserrat-Bold.woff2 +0 -0
  10. package/docs/fonts/Montserrat/Montserrat-Regular.eot +0 -0
  11. package/docs/fonts/Montserrat/Montserrat-Regular.ttf +0 -0
  12. package/docs/fonts/Montserrat/Montserrat-Regular.woff +0 -0
  13. package/docs/fonts/Montserrat/Montserrat-Regular.woff2 +0 -0
  14. package/docs/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.eot +0 -0
  15. package/docs/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.svg +0 -0
  16. package/docs/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.ttf +0 -0
  17. package/docs/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.woff +0 -0
  18. package/docs/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.woff2 +0 -0
  19. package/docs/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.eot +0 -0
  20. package/docs/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.svg +0 -0
  21. package/docs/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.ttf +0 -0
  22. package/docs/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.woff +0 -0
  23. package/docs/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.woff2 +0 -0
  24. package/docs/index.html +8 -2
  25. package/docs/module-Config.html +85 -3
  26. package/docs/module-Railcontent-Services.html +90 -173
  27. package/docs/module-Sanity-Services.html +960 -72
  28. package/docs/railcontent.js.html +44 -42
  29. package/docs/sanity.js.html +99 -54
  30. package/docs/scripts/collapse.js +0 -0
  31. package/docs/scripts/commonNav.js +0 -0
  32. package/docs/scripts/linenumber.js +0 -0
  33. package/docs/scripts/nav.js +0 -0
  34. package/docs/scripts/polyfill.js +0 -0
  35. package/docs/scripts/prettify/Apache-License-2.0.txt +0 -0
  36. package/docs/scripts/prettify/lang-css.js +0 -0
  37. package/docs/scripts/prettify/prettify.js +0 -0
  38. package/docs/scripts/search.js +0 -0
  39. package/docs/styles/jsdoc.css +0 -0
  40. package/docs/styles/prettify.css +0 -0
  41. package/jest.config.js +0 -0
  42. package/jsdoc.json +0 -0
  43. package/package.json +1 -1
  44. package/src/contentMetaData.js +0 -0
  45. package/src/contentTypeConfig.js +11 -1
  46. package/src/filterBuilder.js +0 -0
  47. package/src/index.d.ts +2 -0
  48. package/src/index.js +2 -0
  49. package/src/services/config.js +0 -0
  50. package/src/services/contentLikes.js +0 -0
  51. package/src/services/dataContext.js +0 -0
  52. package/src/services/railcontent.js +0 -0
  53. package/src/services/sanity.js +62 -21
  54. package/test/contentLikes.test.js +0 -0
  55. package/test/localStorageMock.js +0 -0
  56. package/test/log.js +0 -0
  57. package/test/sanityQueryService.test.js +38 -1
  58. package/tools/generate-index.js +0 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "musora-content-services",
3
- "version": "1.0.137",
3
+ "version": "1.0.139",
4
4
  "description": "A package for Musoras content services ",
5
5
  "main": "src/index.js",
6
6
  "scripts": {
File without changes
@@ -213,7 +213,17 @@ let contentTypeConfig = {
213
213
  `"description": ${descriptionField}`,
214
214
  '"instructors": instructor[]->name',
215
215
  '"logo_image_url": logo_image_url.asset->url',
216
- 'total_xp'
216
+ 'total_xp',
217
+ `"children": child[]->{
218
+ "description": ${descriptionField},
219
+ "lesson_count": child_count,
220
+ ${getFieldsForContentType()}
221
+ }`,
222
+ '"resources": resource',
223
+ '"thumbnail": thumbnail.asset->url',
224
+ '"light_logo": light_mode_logo_url.asset->url',
225
+ '"dark_logo": dark_mode_logo_url.asset->url',
226
+ `"description": ${descriptionField}`,
217
227
  ],
218
228
  },
219
229
  'rudiment': {
File without changes
package/src/index.d.ts CHANGED
@@ -59,6 +59,7 @@ import {
59
59
  fetchNextPreviousLesson,
60
60
  fetchPackAll,
61
61
  fetchPackChildren,
62
+ fetchPackData,
62
63
  fetchParentByRailContentId,
63
64
  fetchRelatedLessons,
64
65
  fetchRelatedMethodLessons,
@@ -113,6 +114,7 @@ declare module 'musora-content-services' {
113
114
  fetchNextPreviousLesson,
114
115
  fetchPackAll,
115
116
  fetchPackChildren,
117
+ fetchPackData,
116
118
  fetchParentByRailContentId,
117
119
  fetchRelatedLessons,
118
120
  fetchRelatedMethodLessons,
package/src/index.js CHANGED
@@ -59,6 +59,7 @@ import {
59
59
  fetchNextPreviousLesson,
60
60
  fetchPackAll,
61
61
  fetchPackChildren,
62
+ fetchPackData,
62
63
  fetchParentByRailContentId,
63
64
  fetchRelatedLessons,
64
65
  fetchRelatedMethodLessons,
@@ -112,6 +113,7 @@ export {
112
113
  fetchNextPreviousLesson,
113
114
  fetchPackAll,
114
115
  fetchPackChildren,
116
+ fetchPackData,
115
117
  fetchParentByRailContentId,
116
118
  fetchRelatedLessons,
117
119
  fetchRelatedMethodLessons,
File without changes
File without changes
File without changes
File without changes
@@ -299,6 +299,7 @@ export async function fetchNewReleases(brand, { page = 1, limit = 20, sort="-pub
299
299
  fields,
300
300
  {
301
301
  sortOrder: sortOrder,
302
+ start,
302
303
  end: end,
303
304
  });
304
305
  return fetchSanity(query, true);
@@ -831,7 +832,7 @@ export async function fetchMethodNextLesson(railcontentId, methodId) {
831
832
  */
832
833
  export async function fetchMethodPreviousNextLesson(railcontentId, methodId) {
833
834
  const sortedChildren = await fetchMethodChildrenIds(methodId);
834
- const index = sortedChildren.indexOf(railcontentId);
835
+ const index = sortedChildren.indexOf(Number(railcontentId));
835
836
  let nextId = sortedChildren[index + 1];
836
837
  let previousId = sortedChildren[index -1];
837
838
  let nextPrev = await fetchByRailContentIds([nextId, previousId]);
@@ -846,13 +847,16 @@ export async function fetchMethodPreviousNextLesson(railcontentId, methodId) {
846
847
  * @returns {Promise<Array<Object>|null>} - The fetched children data or null if not found.
847
848
  */
848
849
  export async function fetchMethodChildrenIds(railcontentId) {
849
- const query = `*[_type == 'learning-path' && railcontent_id == ${railcontentId}]{
850
+ const query = `*[ railcontent_id == ${railcontentId}]{
850
851
  'children': child[]-> {
851
852
  'id': railcontent_id,
853
+ 'type' : _type,
852
854
  'children': child[]-> {
853
- 'id': railcontent_id,
854
- 'children': child[]-> {
855
855
  'id': railcontent_id,
856
+ 'type' : _type,
857
+ 'children': child[]-> {
858
+ 'id': railcontent_id,
859
+ 'type' : _type,
856
860
  }
857
861
  }
858
862
  }
@@ -864,9 +868,11 @@ export async function fetchMethodChildrenIds(railcontentId) {
864
868
  function getChildrenToDepth(parent, depth = 1)
865
869
  {
866
870
  let allChildrenIds = [];
867
- if (parent['children']) {
871
+ if (parent && parent['children'] && depth > 0) {
868
872
  parent['children'].forEach((child) => {
869
- allChildrenIds.push(child['id']);
873
+ if(!child['children']) {
874
+ allChildrenIds.push(child['id']);
875
+ }
870
876
  allChildrenIds = allChildrenIds.concat(getChildrenToDepth(child, depth-1));
871
877
  })
872
878
  }
@@ -879,19 +885,27 @@ function getChildrenToDepth(parent, depth = 1)
879
885
  * @returns {Promise<Object|null>} - The fetched next and previous lesson data or null if found.
880
886
  */
881
887
  export async function fetchNextPreviousLesson(railcontentId) {
882
- //TODO: Implement getTypeNeighbouringSiblings/getNextAndPreviousLessons
883
- const query = `*[_railcontent_id == ${railcontentId}]{
884
- railcontent_id,
885
- title,
886
- "image": thumbnail.asset->url,
887
- "artist_name": artist->name,
888
- artist,
889
- difficulty,
890
- difficulty_string,
891
- web_url_path,
892
- published_on
893
- }`
894
- return fetchSanity(query, false);
888
+ const document = await fetchLessonContent(railcontentId);
889
+ if (document.parent_content_data && document.parent_content_data.length > 0) {
890
+ const lastElement = document.parent_content_data[document.parent_content_data.length - 1];
891
+ const results = await fetchMethodPreviousNextLesson(railcontentId, lastElement.id);
892
+ return results;
893
+ }
894
+ const processedData = processMetadata(document.brand, document.type, true);
895
+ let sortBy = processedData?.sortBy ?? 'published_on';
896
+ const isDesc = sortBy.startsWith('-');
897
+ sortBy = isDesc ? sortBy.substring(1) : sortBy;
898
+ const sortValue = document[sortBy];
899
+ const isNumeric = !isNaN(sortValue);
900
+ let prevComparison = isNumeric ? `${sortBy} <= ${sortValue}` : `${sortBy} <= "${sortValue}"`;
901
+ let nextComparison = isNumeric ? `${sortBy} >= ${sortValue}` : `${sortBy} >= "${sortValue}"`;
902
+ const fields = getFieldsForContentType(document.type);
903
+ const query = `{
904
+ "prevLesson": *[brand == "${document.brand}" && status == "${document.status}" && _type == "${document.type}" && ${prevComparison} && railcontent_id != ${railcontentId}] | order(${sortBy} desc){${fields}}[0...1][0],
905
+ "nextLesson": *[brand == "${document.brand}" && status == "${document.status}" && _type == "${document.type}" && ${nextComparison} && railcontent_id != ${railcontentId}] | order(${sortBy} asc){${fields}}[0...1][0]
906
+ }`;
907
+
908
+ return await fetchSanity(query, true);
895
909
  }
896
910
 
897
911
  /**
@@ -913,6 +927,7 @@ export async function fetchLessonContent(railContentId) {
913
927
  difficulty,
914
928
  difficulty_string,
915
929
  brand,
930
+ status,
916
931
  soundslice,
917
932
  instrumentless,
918
933
  railcontent_id,
@@ -944,7 +959,9 @@ export async function fetchLessonContent(railContentId) {
944
959
  mp3_no_drums_yes_click_url,
945
960
  mp3_yes_drums_no_click_url,
946
961
  mp3_yes_drums_yes_click_url,
947
- "permission_id": permission[]->railcontent_id,`;
962
+ "permission_id": permission[]->railcontent_id,
963
+ parent_content_data,
964
+ sort`;
948
965
  const query = buildQuery(
949
966
  `railcontent_id == ${railContentId}`,
950
967
  filterParams,
@@ -1004,13 +1021,18 @@ export async function fetchRelatedMethodLessons(railContentId, brand) {
1004
1021
  * @param {string} brand - The brand for which to fetch packs.
1005
1022
  * @param {string} [searchTerm=""] - The search term to filter packs.
1006
1023
  * @param {string} [sort="-published_on"] - The field to sort the packs by.
1024
+ * @param {number} [params.page=1] - The page number for pagination.
1025
+ * @param {number} [params.limit=10] - The number of items per page.
1007
1026
  * @returns {Promise<Array<Object>|null>} - The fetched pack content data or null if not found.
1008
1027
  */
1009
- export async function fetchAllPacks(brand, sort = "-published_on", searchTerm = "") {
1028
+ export async function fetchAllPacks(brand, sort = "-published_on", searchTerm = "", page = 1, limit = 10) {
1010
1029
  const sortOrder = getSortOrder(sort);
1011
1030
  const filter = `_type == 'pack' && brand == '${brand}' && title match "${searchTerm}*"`
1012
1031
  const filterParams = {};
1013
1032
  const fields = getFieldsForContentType('pack');
1033
+ const start = (page - 1) * limit;
1034
+ const end = start + limit;
1035
+
1014
1036
  const query = buildQuery(
1015
1037
  filter,
1016
1038
  filterParams,
@@ -1018,6 +1040,8 @@ export async function fetchAllPacks(brand, sort = "-published_on", searchTerm =
1018
1040
  {
1019
1041
  logo_image_url: 'logo_image_url.asset->url',
1020
1042
  sortOrder: sortOrder,
1043
+ start,
1044
+ end
1021
1045
  }
1022
1046
  );
1023
1047
  return fetchSanity(query, true);
@@ -1092,6 +1116,23 @@ export async function fetchPackChildren(railcontentId) {
1092
1116
  return fetchChildren(railcontentId, 'pack-children');
1093
1117
  }
1094
1118
 
1119
+ /**
1120
+ * Fetch the data needed for the Pack Overview screen.
1121
+ * @param {number} id - The Railcontent ID of the pack
1122
+ * @returns {Promise<Object|null>} - The pack information and lessons or null if not found.
1123
+ *
1124
+ * @example
1125
+ * fetchPackData(404048)
1126
+ * .then(challenge => console.log(challenge))
1127
+ * .catch(error => console.error(error));
1128
+ */
1129
+ export async function fetchPackData(id) {
1130
+ const query = `*[railcontent_id == ${id}]{
1131
+ ${getFieldsForContentType("pack")}
1132
+ } [0...1]`;
1133
+ return fetchSanity(query, false);
1134
+ }
1135
+
1095
1136
  /**
1096
1137
  * Fetch the data needed for the Challenge Overview screen.
1097
1138
  * @param {string} id - The Railcontent ID of the course
File without changes
File without changes
package/test/log.js CHANGED
File without changes
@@ -35,7 +35,8 @@ const {
35
35
  fetchScheduledReleases,
36
36
  getSortOrder,
37
37
  fetchShowsData,
38
- fetchMetadata
38
+ fetchMetadata,
39
+ fetchNextPreviousLesson
39
40
  } = require('../src/services/sanity.js');
40
41
 
41
42
  const {
@@ -520,6 +521,42 @@ describe('Sanity Queries', function () {
520
521
  expect(response).toBeDefined();
521
522
  });
522
523
 
524
+ test('fetchNextPreviousLesson-Show-With-Episodes', async () => {
525
+ const id = 227136;
526
+ const document = await fetchByRailContentId(id, 'behind-the-scenes');
527
+ const response = await fetchNextPreviousLesson(id);
528
+ log(response);
529
+ expect(response.prevLesson).toBeDefined();
530
+ expect(response.prevLesson.sort).toBeLessThanOrEqual(document.sort);
531
+ expect(response.nextLesson).toBeDefined();
532
+ expect(response.nextLesson.sort).toBeGreaterThanOrEqual(document.sort);
533
+ });
534
+
535
+ test('fetchNextPreviousLesson-Method-Lesson', async () => {
536
+ const id = 241265;
537
+ const response = await fetchNextPreviousLesson(id);
538
+ log(response);
539
+ expect(response.prevLesson).toBeDefined();
540
+ expect(response.prevLesson.id).toBe(241264);
541
+ expect(response.prevLesson.type).toBe('learning-path-lesson');
542
+ expect(response.nextLesson).toBeDefined();
543
+ expect(response.nextLesson.id).toBe(241267);
544
+ expect(response.nextLesson.type).toBe('learning-path-lesson');
545
+ });
546
+
547
+ test('fetchNextPreviousLesson-Quick-Tips', async () => {
548
+ const id = 412277;
549
+ const response = await fetchNextPreviousLesson(id);
550
+ const document = await fetchByRailContentId(id, 'quick-tips');
551
+ const documentPublishedOn = new Date(document.published_on);
552
+ const prevDocumentPublishedOn = new Date(response.prevLesson.published_on);
553
+ const nextDocumentPublishedOn = new Date(response.nextLesson.published_on);
554
+ expect(response.prevLesson).toBeDefined();
555
+ expect(prevDocumentPublishedOn.getTime()).toBeLessThan(documentPublishedOn.getTime());
556
+ expect(response.nextLesson).toBeDefined();
557
+ expect(documentPublishedOn.getTime()).toBeLessThan(nextDocumentPublishedOn.getTime());
558
+ });
559
+
523
560
  });
524
561
 
525
562
  describe('Filter Builder', function () {
File without changes