musora-content-services 1.0.60 → 1.0.62

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.
@@ -29,7 +29,7 @@
29
29
  <nav >
30
30
 
31
31
 
32
- <h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-Config.html">Config</a><ul class='methods'><li data-type='method'><a href="module-Config.html#~initializeService">initializeService</a></li></ul></li><li><a href="module-Railcontent-Services.html">Railcontent-Services</a><ul class='methods'><li data-type='method'><a href="module-Railcontent-Services.html#.fetchAllCompletedStates">fetchAllCompletedStates</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchContentInProgress">fetchContentInProgress</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchCurrentSongComplete">fetchCurrentSongComplete</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchSongsInProgress">fetchSongsInProgress</a></li></ul></li><li><a href="module-Sanity-Services.html">Sanity-Services</a><ul class='methods'><li data-type='method'><a href="module-Sanity-Services.html#.fetchAll">fetchAll</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchAllFilterOptions">fetchAllFilterOptions</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchAllSongs">fetchAllSongs</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchArtists">fetchArtists</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchByRailContentId">fetchByRailContentId</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchByRailContentIds">fetchByRailContentIds</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchChildren">fetchChildren</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchCourseOverview">fetchCourseOverview</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchLessonContent">fetchLessonContent</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchMethod">fetchMethod</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchMethodChildren">fetchMethodChildren</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchMethodNextLesson">fetchMethodNextLesson</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchMethods">fetchMethods</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchNewReleases">fetchNewReleases</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchNextPreviousLesson">fetchNextPreviousLesson</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchPackAll">fetchPackAll</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchPackChildren">fetchPackChildren</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchRelatedLessons">fetchRelatedLessons</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchRelatedSongs">fetchRelatedSongs</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchSanity">fetchSanity</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchSongArtistCount">fetchSongArtistCount</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchSongById">fetchSongById</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchSongCount">fetchSongCount</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchSongFilterOptions">fetchSongFilterOptions</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchUpcomingEvents">fetchUpcomingEvents</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchWorkouts">fetchWorkouts</a></li></ul></li></ul>
32
+ <h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-Config.html">Config</a><ul class='methods'><li data-type='method'><a href="module-Config.html#~initializeService">initializeService</a></li></ul></li><li><a href="module-Railcontent-Services.html">Railcontent-Services</a><ul class='methods'><li data-type='method'><a href="module-Railcontent-Services.html#.fetchAllCompletedStates">fetchAllCompletedStates</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchContentInProgress">fetchContentInProgress</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchCurrentSongComplete">fetchCurrentSongComplete</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchSongsInProgress">fetchSongsInProgress</a></li></ul></li><li><a href="module-Sanity-Services.html">Sanity-Services</a><ul class='methods'><li data-type='method'><a href="module-Sanity-Services.html#.fetchAll">fetchAll</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchAllFilterOptions">fetchAllFilterOptions</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchAllSongs">fetchAllSongs</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchArtists">fetchArtists</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchByRailContentId">fetchByRailContentId</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchByRailContentIds">fetchByRailContentIds</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchCatalogMetadata">fetchCatalogMetadata</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchChildren">fetchChildren</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchCourseOverview">fetchCourseOverview</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchLessonContent">fetchLessonContent</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchMethod">fetchMethod</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchMethodChildrenIds">fetchMethodChildrenIds</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchMethodNextLesson">fetchMethodNextLesson</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchMethodPreviousNextLesson">fetchMethodPreviousNextLesson</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchMethods">fetchMethods</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchNewReleases">fetchNewReleases</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchNextPreviousLesson">fetchNextPreviousLesson</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchPackAll">fetchPackAll</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchPackChildren">fetchPackChildren</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchParentByRailContentId">fetchParentByRailContentId</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchRelatedLessons">fetchRelatedLessons</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchRelatedSongs">fetchRelatedSongs</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchSanity">fetchSanity</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchSongArtistCount">fetchSongArtistCount</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchSongById">fetchSongById</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchSongCount">fetchSongCount</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchSongFilterOptions">fetchSongFilterOptions</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchUpcomingEvents">fetchUpcomingEvents</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchWorkouts">fetchWorkouts</a></li></ul></li></ul>
33
33
 
34
34
  </nav>
35
35
 
@@ -201,7 +201,7 @@ export async function fetchContentInProgress(type="all", brand) {
201
201
  <br class="clear">
202
202
 
203
203
  <footer>
204
- Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.3</a> on Mon Aug 26 2024 19:46:17 GMT+0000 (Coordinated Universal Time) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
204
+ Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.3</a> on Mon Aug 26 2024 20:15:19 GMT+0000 (Coordinated Universal Time) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
205
205
  </footer>
206
206
 
207
207
  <script>prettyPrint();</script>
@@ -29,7 +29,7 @@
29
29
  <nav >
30
30
 
31
31
 
32
- <h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-Config.html">Config</a><ul class='methods'><li data-type='method'><a href="module-Config.html#~initializeService">initializeService</a></li></ul></li><li><a href="module-Railcontent-Services.html">Railcontent-Services</a><ul class='methods'><li data-type='method'><a href="module-Railcontent-Services.html#.fetchAllCompletedStates">fetchAllCompletedStates</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchContentInProgress">fetchContentInProgress</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchCurrentSongComplete">fetchCurrentSongComplete</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchSongsInProgress">fetchSongsInProgress</a></li></ul></li><li><a href="module-Sanity-Services.html">Sanity-Services</a><ul class='methods'><li data-type='method'><a href="module-Sanity-Services.html#.fetchAll">fetchAll</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchAllFilterOptions">fetchAllFilterOptions</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchAllSongs">fetchAllSongs</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchArtists">fetchArtists</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchByRailContentId">fetchByRailContentId</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchByRailContentIds">fetchByRailContentIds</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchChildren">fetchChildren</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchCourseOverview">fetchCourseOverview</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchLessonContent">fetchLessonContent</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchMethod">fetchMethod</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchMethodChildren">fetchMethodChildren</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchMethodNextLesson">fetchMethodNextLesson</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchMethods">fetchMethods</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchNewReleases">fetchNewReleases</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchNextPreviousLesson">fetchNextPreviousLesson</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchPackAll">fetchPackAll</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchPackChildren">fetchPackChildren</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchRelatedLessons">fetchRelatedLessons</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchRelatedSongs">fetchRelatedSongs</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchSanity">fetchSanity</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchSongArtistCount">fetchSongArtistCount</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchSongById">fetchSongById</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchSongCount">fetchSongCount</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchSongFilterOptions">fetchSongFilterOptions</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchUpcomingEvents">fetchUpcomingEvents</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchWorkouts">fetchWorkouts</a></li></ul></li></ul>
32
+ <h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-Config.html">Config</a><ul class='methods'><li data-type='method'><a href="module-Config.html#~initializeService">initializeService</a></li></ul></li><li><a href="module-Railcontent-Services.html">Railcontent-Services</a><ul class='methods'><li data-type='method'><a href="module-Railcontent-Services.html#.fetchAllCompletedStates">fetchAllCompletedStates</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchContentInProgress">fetchContentInProgress</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchCurrentSongComplete">fetchCurrentSongComplete</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchSongsInProgress">fetchSongsInProgress</a></li></ul></li><li><a href="module-Sanity-Services.html">Sanity-Services</a><ul class='methods'><li data-type='method'><a href="module-Sanity-Services.html#.fetchAll">fetchAll</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchAllFilterOptions">fetchAllFilterOptions</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchAllSongs">fetchAllSongs</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchArtists">fetchArtists</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchByRailContentId">fetchByRailContentId</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchByRailContentIds">fetchByRailContentIds</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchCatalogMetadata">fetchCatalogMetadata</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchChildren">fetchChildren</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchCourseOverview">fetchCourseOverview</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchLessonContent">fetchLessonContent</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchMethod">fetchMethod</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchMethodChildrenIds">fetchMethodChildrenIds</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchMethodNextLesson">fetchMethodNextLesson</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchMethodPreviousNextLesson">fetchMethodPreviousNextLesson</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchMethods">fetchMethods</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchNewReleases">fetchNewReleases</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchNextPreviousLesson">fetchNextPreviousLesson</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchPackAll">fetchPackAll</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchPackChildren">fetchPackChildren</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchParentByRailContentId">fetchParentByRailContentId</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchRelatedLessons">fetchRelatedLessons</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchRelatedSongs">fetchRelatedSongs</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchSanity">fetchSanity</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchSongArtistCount">fetchSongArtistCount</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchSongById">fetchSongById</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchSongCount">fetchSongCount</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchSongFilterOptions">fetchSongFilterOptions</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchUpcomingEvents">fetchUpcomingEvents</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchWorkouts">fetchWorkouts</a></li></ul></li></ul>
33
33
 
34
34
  </nav>
35
35
 
@@ -48,23 +48,11 @@
48
48
  <pre class="prettyprint source linenums"><code>/**
49
49
  * @module Sanity-Services
50
50
  */
51
- import {contentTypeConfig} from "../contentTypeConfig";
51
+ import {assignmentsField, contentTypeConfig, DEFAULT_FIELDS, getFieldsForContentType} from "../contentTypeConfig";
52
52
  import {globalConfig} from "./config";
53
53
 
54
54
  import { fetchAllCompletedStates, fetchCurrentSongComplete } from './railcontent.js';
55
55
 
56
- const DEFAULT_FIELDS = [
57
- '"id": railcontent_id',
58
- 'railcontent_id',
59
- '"type": _type',
60
- 'title',
61
- '"image": thumbnail.asset->url',
62
- 'difficulty',
63
- 'difficulty_string',
64
- 'web_url_path',
65
- 'published_on'
66
- ];
67
-
68
56
  /**
69
57
  * Fetch a song by its document ID from Sanity.
70
58
  *
@@ -77,25 +65,10 @@ const DEFAULT_FIELDS = [
77
65
  * .catch(error => console.error(error));
78
66
  */
79
67
  export async function fetchSongById(documentId) {
80
- const fields = [
81
- '"id": railcontent_id',
82
- 'railcontent_id',
83
- '"type": _type',
84
- 'description',
85
- 'title',
86
- '"thumbnail_url": thumbnail.asset->url',
87
- '"style": genre[0]->name',
88
- '"artist": artist->name',
89
- 'album',
90
- 'instrumentless',
91
- 'soundslice',
92
- '"resources": resource[]{resource_url, resource_name}',
93
- '"url": web_url_path',
94
- ];
95
68
 
96
69
  const query = `
97
70
  *[_type == "song" &amp;&amp; railcontent_id == ${documentId}]{
98
- ${fields.join(', ')}
71
+ ${getFieldsForContentType('song', true)}
99
72
  }`;
100
73
 
101
74
  return fetchSanity(query, false);
@@ -296,10 +269,10 @@ export async function fetchSongCount(brand) {
296
269
  * Fetch the latest workouts for a specific brand, including completion status and progress.
297
270
  * This function retrieves up to five of the latest workout content for a given brand, sorted in descending order by their publication date.
298
271
  * It also includes completion status and progress percentage for each workout by fetching additional data about user progress.
299
- *
272
+ *
300
273
  * @param {string} brand - The brand for which to fetch workouts (e.g., 'drumeo', 'pianote').
301
274
  * @returns {Promise&lt;Array&lt;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.
302
- *
275
+ *
303
276
  * @example
304
277
  * fetchWorkouts('drumeo')
305
278
  * .then(workouts => console.log(workouts))
@@ -310,12 +283,12 @@ export async function fetchWorkouts(brand) {
310
283
  "id": railcontent_id,
311
284
  title,
312
285
  "image": thumbnail.asset->url,
313
- "artist_name": instructor[0]->name,
314
- "artists": instructor[]->name,
286
+ ${artistOrInstructor()},
287
+ ${artistOrInstructorAsArray()},
315
288
  difficulty,
316
289
  difficulty_string,
317
290
  length_in_seconds,
318
- published_on,
291
+ published_on,;
319
292
  "type": _type,
320
293
  web_url_path,
321
294
  } | order(published_on desc)[0...5]`
@@ -403,17 +376,9 @@ export async function fetchUpcomingEvents(brand) {
403
376
  * .then(content => console.log(content))
404
377
  * .catch(error => console.error(error));
405
378
  */
406
- export async function fetchByRailContentId(id) {
379
+ export async function fetchByRailContentId(id, contentType) {
407
380
  const query = `*[railcontent_id == ${id}]{
408
- railcontent_id,
409
- title,
410
- "image": thumbnail.asset->url,
411
- "artist_name": artist->name,
412
- artist,
413
- difficulty,
414
- difficulty_string,
415
- web_url_path,
416
- published_on
381
+ ${getFieldsForContentType(contentType)}
417
382
  }`
418
383
  return fetchSanity(query, false);
419
384
  }
@@ -431,10 +396,9 @@ export async function fetchByRailContentId(id) {
431
396
  * .catch(error => console.error(error));
432
397
  */
433
398
  export async function fetchByRailContentIds(ids, contentType = undefined) {
434
- const fields = contentType ? DEFAULT_FIELDS.concat(contentTypeConfig?.[contentType]?.fields ?? []) : DEFAULT_FIELDS;
435
399
  const idsString = ids.join(',');
436
400
  const query = `*[railcontent_id in [${idsString}]]{
437
- ${fields.join(', ')}
401
+ ${getFieldsForContentType(contentType)}
438
402
  }`
439
403
  return fetchSanity(query, true);
440
404
  }
@@ -495,37 +459,7 @@ export async function fetchAll(brand, type, {
495
459
  : "";
496
460
 
497
461
  // Determine the sort order
498
- let sortOrder;
499
- switch (sort) {
500
- case "slug":
501
- if(groupBy){
502
- sortOrder = "name asc";
503
- } else {
504
- sortOrder = "title asc";
505
- }
506
-
507
- break;
508
- case "published_on":
509
- sortOrder = "published_on asc";
510
- break;
511
- case "-published_on":
512
- sortOrder = "published_on desc";
513
- break;
514
- case "-slug":
515
- if(groupBy){
516
- sortOrder = "name desc";
517
- } else {
518
- sortOrder = "title desc";
519
- }
520
-
521
- break;
522
- case "-popularity":
523
- sortOrder = "popularity desc";
524
- break;
525
- default:
526
- sortOrder = "published_on asc";
527
- break;
528
- }
462
+ const sortOrder = getSortOrder(sort);
529
463
 
530
464
  let fields = DEFAULT_FIELDS.concat(additionalFields);
531
465
  let fieldsString = fields.join(',');
@@ -584,6 +518,28 @@ export async function fetchAll(brand, type, {
584
518
  return fetchSanity(query, true);
585
519
  }
586
520
 
521
+ export function getSortOrder(sort= '-published_on', groupBy)
522
+ {
523
+ // Determine the sort order
524
+ let sortOrder = '';
525
+ const isDesc = sort.startsWith('-');
526
+ sort = isDesc ? sort.substring(1) : sort;
527
+ switch (sort) {
528
+ case "slug":
529
+ sortOrder = groupBy ? 'name' : "title";
530
+ break;
531
+ case "popularity":
532
+ sortOrder = "popularity";
533
+ break;
534
+ case "published_on":
535
+ default:
536
+ sortOrder = "published_on";
537
+ break;
538
+ }
539
+ sortOrder += isDesc ? ' desc' : ' asc';
540
+ return sortOrder;
541
+ }
542
+
587
543
  /**
588
544
  * Fetches all available filter options based on various criteria such as brand, filters, style, artist, content type, and search term.
589
545
  *
@@ -621,10 +577,10 @@ export async function fetchAllFilterOptions(
621
577
  return `&amp;&amp; ${key} == "${value}"`;
622
578
  }).join(' ')
623
579
  : undefined;
624
-
580
+
625
581
  const commonFilter = `_type == '${contentType}' &amp;&amp; brand == "${brand}"${style ? ` &amp;&amp; '${style}' in genre[]->name` : ''}${artist ? ` &amp;&amp; artist->name == '${artist}'` : ''} ${filtersToGroq ? filtersToGroq : ''}`;
626
582
  const query = `
627
- {
583
+ {
628
584
  "meta": {
629
585
  "totalResults": count(*[${commonFilter}
630
586
  ${term ? ` &amp;&amp; (title match "${term}" || album match "${term}" || artist->name match "${term}" || genre[]->name match "${term}")` : ''}]),
@@ -653,22 +609,33 @@ export async function fetchAllFilterOptions(
653
609
  /**
654
610
  * Fetch children content by Railcontent ID.
655
611
  * @param {string} railcontentId - The Railcontent ID of the parent content.
656
- * @returns {Promise&lt;Array&lt;Object>|null>} - The fetched children content data or null if not found.
612
+ * @returns {Promise&lt;Array&lt;Object>|null>} - The fetched children content data or [] if not found.
657
613
  */
658
614
  export async function fetchChildren(railcontentId) {
659
- //TODO: Implement getByParentId include sum XP
660
- const query = `*[_railcontent_id == ${railcontentId}]{
661
- railcontent_id,
662
- title,
663
- "image": thumbnail.asset->url,
664
- "artist_name": artist->name,
665
- artist,
666
- difficulty,
667
- difficulty_string,
668
- web_url_path,
669
- published_on
670
- } | order(published_on asc)`
671
- return fetchSanity(query, true);
615
+ const query = `*[railcontent_id == ${railcontentId}]{
616
+ 'children': child[]->{
617
+ ${getFieldsForContentType()}
618
+ },
619
+ }[0..1]`;
620
+ let parent = await fetchSanity(query, true);
621
+ return parent[0]['children'] ?? [];
622
+ }
623
+
624
+ /**
625
+ *
626
+ * @param railcontentId - railcontent id of the child
627
+ * @returns {Promise&lt;Array&lt;string>|null>} - The fetched parent content data or [] if not found
628
+ */
629
+ export async function fetchParentByRailContentId(railcontentId) {
630
+ const query = `*[railcontent_id == ${railcontentId}]{
631
+ 'parents': array::unique([
632
+ ...(*[references(^._id)]{
633
+ ${getFieldsForContentType()}
634
+ })
635
+ ])
636
+ }[0...1]`;
637
+ let child = await fetchSanity(query, true);
638
+ return child[0]['parents'][0] ?? [];
672
639
  }
673
640
 
674
641
  /**
@@ -677,31 +644,11 @@ export async function fetchChildren(railcontentId) {
677
644
  * @returns {Promise&lt;Object|null>} - The fetched methods data or null if not found.
678
645
  */
679
646
  export async function fetchMethods(brand) {
680
- const query = `*[_type == 'learning-path' &amp;&amp; brand == "${brand}"] {
681
- child_count,
682
- difficulty,
683
- difficulty_string,
684
- "description": description[0].children[0].text,
685
- hide_from_recsys,
686
- "image": thumbnail.asset->url,
687
- "instructors":instructor[]->name,
688
- "lesson_count": child_count,
689
- length_in_seconds,
690
- permission,
691
- popularity,
647
+ //TODOS
648
+ //ADD INSTRUCTORS AND POSITION
649
+ const query = `*[_type == 'learning-path' &amp;&amp; brand == '${brand}'] {
650
+ ${getFieldsForContentType('method')}
692
651
  "position": count(*[_type == 'learning-path' &amp;&amp; brand == '${brand}' &amp;&amp; (published_on &lt; ^.published_on || (published_on == ^.published_on &amp;&amp; _id &lt; ^._id))]) + 1,
693
- published_on,
694
- railcontent_id,
695
- "slug": slug.current,
696
- status,
697
- "thumbnail": thumbnail.asset->url,
698
- "thumbnail_logo": logo_image_url.asset->url,
699
- title,
700
- total_xp,
701
- "type": _type,
702
- web_url_path,
703
- "url": web_url_path,
704
- xp,
705
652
  } | order(published_on asc)`
706
653
  return fetchSanity(query, true);
707
654
  }
@@ -740,22 +687,36 @@ return fetchSanity(query, false);
740
687
  /**
741
688
  * Fetch the next lesson for a specific method by Railcontent ID.
742
689
  * @param {string} railcontentId - The Railcontent ID of the current lesson.
690
+ * @param {string} methodId - The RailcontentID of the method
743
691
  * @returns {Promise&lt;Object|null>} - The fetched next lesson data or null if not found.
744
692
  */
745
- export async function fetchMethodNextLesson(railcontentId) {
746
- //TODO: Implement getNextContentForParentContentForUser
747
- const query = `*[_railcontent_id == ${railcontentId}]{
748
- railcontent_id,
749
- title,
750
- "image": thumbnail.asset->url,
751
- "artist_name": artist->name,
752
- artist,
753
- difficulty,
754
- difficulty_string,
755
- web_url_path,
756
- published_on
757
- }`
758
- return fetchSanity(query, false);
693
+ export async function fetchMethodNextLesson(railcontentId, methodId) {
694
+ const sortedChildren = await fetchMethodChildrenIds(methodId);
695
+ const index = sortedChildren.indexOf(railcontentId);
696
+ const childIndex = sortedChildren[index + 1];
697
+ return childIndex ? await fetchByRailContentId(childIndex) : null;
698
+ }
699
+
700
+
701
+ /**
702
+ * Fetch the next lesson for a specific method by Railcontent ID.
703
+ * @param {string} railcontentId - The Railcontent ID of the current lesson.
704
+ * @param {string} methodId - The RailcontentID of the method
705
+ * @returns {Promise&lt;Object|null>} - object with `nextLesson` and `previousLesson` attributes
706
+ * @example
707
+ * fetchMethodPreviousNextLesson(241284, 241247)
708
+ * .then(data => { console.log('nextLesson', data.nextLesson); console.log('prevlesson', data.prevLesson);})
709
+ * .catch(error => console.error(error));
710
+ */
711
+ export async function fetchMethodPreviousNextLesson(railcontentId, methodId) {
712
+ const sortedChildren = await fetchMethodChildrenIds(methodId);
713
+ const index = sortedChildren.indexOf(railcontentId);
714
+ let nextId = sortedChildren[index + 1];
715
+ let previousId = sortedChildren[index -1];
716
+ let nextPrev = await fetchByRailContentIds([nextId, previousId]);
717
+ const nextLesson = nextPrev.find((elem) => {return elem['id'] === nextId});
718
+ const prevLesson = nextPrev.find((elem) => {return elem['id'] === previousId});
719
+ return {nextLesson, prevLesson};
759
720
  }
760
721
 
761
722
  /**
@@ -763,11 +724,37 @@ export async function fetchMethodNextLesson(railcontentId) {
763
724
  * @param {string} railcontentId - The Railcontent ID of the method.
764
725
  * @returns {Promise&lt;Array&lt;Object>|null>} - The fetched children data or null if not found.
765
726
  */
766
- export async function fetchMethodChildren(railcontentId) {
727
+ export async function fetchMethodChildrenIds(railcontentId) {
767
728
  //TODO: Implement getByParentId include sum XP
768
- return fetchChildren(railcontentId);
729
+ const query = `*[_type == 'learning-path' &amp;&amp; railcontent_id == ${railcontentId}]{
730
+ 'children': child[]-> {
731
+ 'id': railcontent_id,
732
+ 'children': child[]-> {
733
+ 'id': railcontent_id,
734
+ 'children': child[]-> {
735
+ 'id': railcontent_id,
736
+ }
737
+ }
738
+ }
739
+ }`;
740
+ let allChildren = await fetchSanity(query, false);
741
+ return getChildrenToDepth(allChildren, 4);;
769
742
  }
770
743
 
744
+ function getChildrenToDepth(parent, depth = 1)
745
+ {
746
+ let allChildrenIds = [];
747
+ if (parent['children']) {
748
+ parent['children'].forEach((child) => {
749
+ allChildrenIds.push(child['id']);
750
+ allChildrenIds = allChildrenIds.concat(getChildrenToDepth(child, depth-1));
751
+ })
752
+ }
753
+ return allChildrenIds;
754
+ }
755
+
756
+
757
+
771
758
  /**
772
759
  * Fetch the next and previous lessons for a specific lesson by Railcontent ID.
773
760
  * @param {string} railcontentId - The Railcontent ID of the current lesson.
@@ -806,22 +793,15 @@ export async function fetchLessonContent(railContentId) {
806
793
  chapter_description,
807
794
  chapter_timecode,
808
795
  "chapter_thumbnail_url": chapter_thumbnail_url.asset->url
809
- },
796
+ },
810
797
  "coaches": instructor[]-> {
811
- name,
798
+ name,
812
799
  "id":_id,
813
800
  "coach_profile_image":thumbnail_url.asset->url
814
801
  },
815
802
  "instructors":instructor[]->name,
816
803
  instructor[]->,
817
- "assignments":assignment[]{
818
- "id": railcontent_id,
819
- "soundslice_slug": assignment_soundslice,
820
- "title": assignment_title,
821
- "sheet_music_image_url": assignment_sheet_music_image,
822
- "timecode": assignment_timecode,
823
- "description": assignment_description
824
- },
804
+ ${assignmentsField}
825
805
  video}`
826
806
  return fetchSanity(query, false);
827
807
  }
@@ -887,7 +867,7 @@ export async function fetchPackChildren(railcontentId) {
887
867
  * Fetch the data needed for the Course Overview screen.
888
868
  * @param {string} id - The Railcontent ID of the course
889
869
  * @returns {Promise&lt;Object|null>} - The course information and lessons or null if not found.
890
- *
870
+ *
891
871
  * @example
892
872
  * fetchCourseOverview('course123')
893
873
  * .then(course => console.log(course))
@@ -972,6 +952,32 @@ export async function fetchSanity(query, isList) {
972
952
  }
973
953
  }
974
954
 
955
+ /**
956
+ * Fetch CatalogueMetadata from Sanity. This information may be duplicated in the contentTypeConfig.js.
957
+ * It's an ongoing discussion (Aug 2024), but it's been included here if necessary
958
+ *
959
+ * @param {string} contentType - name of the contentype to pull
960
+ * @returns {Promise&lt;Object|null>} - A promise that resolves to the fetched data or null if an error occurs or no results are found.
961
+ *
962
+ * @example
963
+ *
964
+ * fetchCatalogMetadata('song')
965
+ * .then(data => console.log(data))
966
+ * .catch(error => console.error(error));
967
+ */
968
+ export async function fetchCatalogMetadata(contentType)
969
+ { const query = `*[_type == 'CatalogMetadata']{
970
+ catalog_type,
971
+ brand,
972
+ groq_results,
973
+ groq_search_fields,
974
+ meta_data_groq,
975
+ modal_text,
976
+ sort_by,
977
+ }`
978
+ return fetchSanity(query, false);
979
+ }
980
+
975
981
 
976
982
  //Helper Functions
977
983
  function arrayJoinWithQuotes(array, delimiter = ',') {
@@ -1002,6 +1008,8 @@ function checkSanityConfig(config) {
1002
1008
  }
1003
1009
  return true;
1004
1010
  }
1011
+
1012
+
1005
1013
  </code></pre>
1006
1014
  </article>
1007
1015
  </section>
@@ -1016,7 +1024,7 @@ function checkSanityConfig(config) {
1016
1024
  <br class="clear">
1017
1025
 
1018
1026
  <footer>
1019
- Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.3</a> on Mon Aug 26 2024 19:46:17 GMT+0000 (Coordinated Universal Time) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
1027
+ Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.3</a> on Mon Aug 26 2024 20:15:19 GMT+0000 (Coordinated Universal Time) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
1020
1028
  </footer>
1021
1029
 
1022
1030
  <script>prettyPrint();</script>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "musora-content-services",
3
- "version": "1.0.60",
3
+ "version": "1.0.62",
4
4
  "description": "A package for Musoras content services ",
5
5
  "main": "src/index.js",
6
6
  "scripts": {
@@ -1,11 +1,41 @@
1
+ const DEFAULT_FIELDS = [
2
+ "'sanity_id' : _id",
3
+ "'id': railcontent_id",
4
+ 'railcontent_id',
5
+ artistOrInstructorName(),
6
+ "artist",
7
+ "title",
8
+ "'image': thumbnail.asset->url",
9
+ "'thumbnail': thumbnail.asset->url",
10
+ "difficulty",
11
+ "difficulty_string",
12
+ "web_url_path",
13
+ "published_on",
14
+ "'type': _type",
15
+ "progress_percent",
16
+ "'length_in_seconds' : coalesce(length_in_seconds, soundslice[0].soundslice_length_in_second)",
17
+ "brand",
18
+ "'genre': genre[]->name",
19
+ 'status',
20
+ "'slug' : slug.current",
21
+ ];
22
+
23
+ const descriptionField = 'description[0].children[0].text';
24
+
25
+ const assignmentsField = `"assignments":assignment[]{
26
+ "id": railcontent_id,
27
+ "soundslice_slug": assignment_soundslice,
28
+ "title": assignment_title,
29
+ "sheet_music_image_url": assignment_sheet_music_image,
30
+ "timecode": assignment_timecode,
31
+ "description": assignment_description
32
+ },`
33
+
1
34
  let contentTypeConfig = {
2
35
  'song': {
3
36
  'fields': [
4
- '"artist_name": artist->name',
5
37
  'soundslice',
6
38
  'instrumentless',
7
- '"id": railcontent_id',
8
- '"type": _type',
9
39
  ],
10
40
  'relationships': {
11
41
  'artist': {
@@ -35,9 +65,46 @@ let contentTypeConfig = {
35
65
  '"instructors": instructor[]->name',
36
66
  ]
37
67
  },
68
+ 'method': {
69
+ 'fields': [
70
+ `"description": ${descriptionField}`,
71
+ 'hide_from_recsys',
72
+ '"image": thumbnail.asset->url',
73
+ '"instructors":instructor[]->name',
74
+ '"lesson_count": child_count',
75
+ 'length_in_seconds',
76
+ 'permission',
77
+ 'popularity',
78
+ 'published_on',
79
+ 'railcontent_id',
80
+ '"thumbnail_logo": logo_image_url.asset->url',
81
+ 'title',
82
+ 'total_xp',
83
+ '"type": _type',
84
+ '"url": web_url_path',
85
+ 'xp',
86
+ ]
87
+ }
88
+ }
89
+
90
+ function artistOrInstructorName(key='artist_name') {
91
+ return `'${key}': coalesce(artist->name, instructor[0]->name)`;
38
92
  }
39
93
 
94
+ function artistOrInstructorNameAsArray(key='artists') {
95
+ return `'${key}': select(artist->name != null => [artist->name], instructor[]->name)`;
96
+ }
97
+
98
+ function getFieldsForContentType(contentType, asQueryString=true) {
99
+ const fields = contentType ? DEFAULT_FIELDS.concat(contentTypeConfig?.[contentType]?.fields ?? []) : DEFAULT_FIELDS;
100
+ return asQueryString ? fields.toString() + ',' : fields;
101
+ }
40
102
 
41
103
  module.exports = {
42
- contentTypeConfig
104
+ contentTypeConfig,
105
+ artistOrInstructorName,
106
+ artistOrInstructorNameAsArray,
107
+ getFieldsForContentType,
108
+ DEFAULT_FIELDS,
109
+ assignmentsField
43
110
  }
package/src/index.d.ts CHANGED
@@ -17,7 +17,7 @@ import {
17
17
  fetchMethods,
18
18
  fetchMethod,
19
19
  fetchMethodNextLesson,
20
- fetchMethodChildren,
20
+ fetchMethodChildrenIds,
21
21
  fetchNextPreviousLesson,
22
22
  fetchRelatedLessons,
23
23
  fetchPackAll,
@@ -48,7 +48,7 @@ declare module 'musora-content-services' {
48
48
  fetchMethods,
49
49
  fetchMethod,
50
50
  fetchMethodNextLesson,
51
- fetchMethodChildren,
51
+ fetchMethodChildrenIds,
52
52
  fetchNextPreviousLesson,
53
53
  fetchRelatedLessons,
54
54
  fetchPackAll,