musora-content-services 2.11.0 → 2.11.1

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 (116) hide show
  1. package/.coderabbit.yaml +0 -0
  2. package/.editorconfig +0 -0
  3. package/.github/pull_request_template.md +0 -0
  4. package/.github/workflows/node.js.yml +0 -0
  5. package/.prettierignore +0 -0
  6. package/.prettierrc +0 -0
  7. package/CHANGELOG.md +2 -0
  8. package/README.md +1 -2
  9. package/babel.config.cjs +0 -0
  10. package/docs/Content-Organization.html +0 -0
  11. package/docs/UserManagement.html +0 -0
  12. package/docs/fonts/Montserrat/Montserrat-Bold.eot +0 -0
  13. package/docs/fonts/Montserrat/Montserrat-Bold.ttf +0 -0
  14. package/docs/fonts/Montserrat/Montserrat-Bold.woff +0 -0
  15. package/docs/fonts/Montserrat/Montserrat-Bold.woff2 +0 -0
  16. package/docs/fonts/Montserrat/Montserrat-Regular.eot +0 -0
  17. package/docs/fonts/Montserrat/Montserrat-Regular.ttf +0 -0
  18. package/docs/fonts/Montserrat/Montserrat-Regular.woff +0 -0
  19. package/docs/fonts/Montserrat/Montserrat-Regular.woff2 +0 -0
  20. package/docs/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.eot +0 -0
  21. package/docs/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.svg +0 -0
  22. package/docs/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.ttf +0 -0
  23. package/docs/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.woff +0 -0
  24. package/docs/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.woff2 +0 -0
  25. package/docs/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.eot +0 -0
  26. package/docs/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.svg +0 -0
  27. package/docs/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.ttf +0 -0
  28. package/docs/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.woff +0 -0
  29. package/docs/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.woff2 +0 -0
  30. package/docs/global.html#User +0 -0
  31. package/docs/module-Notifications.html +0 -0
  32. package/docs/module-Session-Management.html +0 -0
  33. package/docs/module-User-Activity.html +0 -0
  34. package/docs/module-User-Management.html +0 -0
  35. package/docs/module-User-Permissions.html +0 -0
  36. package/docs/scripts/collapse.js +0 -0
  37. package/docs/scripts/commonNav.js +0 -0
  38. package/docs/scripts/linenumber.js +0 -0
  39. package/docs/scripts/nav.js +0 -0
  40. package/docs/scripts/polyfill.js +0 -0
  41. package/docs/scripts/prettify/Apache-License-2.0.txt +0 -0
  42. package/docs/scripts/prettify/lang-css.js +0 -0
  43. package/docs/scripts/prettify/prettify.js +0 -0
  44. package/docs/scripts/search.js +0 -0
  45. package/docs/styles/jsdoc.css +0 -0
  46. package/docs/styles/prettify.css +0 -0
  47. package/docs/types.js.html +0 -0
  48. package/docs/user_user-management.js.html +0 -0
  49. package/jest.config.js +0 -0
  50. package/jsdoc.json +0 -0
  51. package/link_mcs.sh +0 -0
  52. package/package.json +1 -1
  53. package/src/contentMetaData.js +0 -0
  54. package/src/filterBuilder.js +0 -0
  55. package/src/infrastructure/http/HttpClient.ts +0 -0
  56. package/src/infrastructure/http/executors/FetchRequestExecutor.ts +0 -0
  57. package/src/infrastructure/http/index.ts +0 -0
  58. package/src/infrastructure/http/interfaces/HeaderProvider.ts +0 -0
  59. package/src/infrastructure/http/interfaces/HttpError.ts +0 -0
  60. package/src/infrastructure/http/interfaces/NetworkError.ts +0 -0
  61. package/src/infrastructure/http/interfaces/RequestExecutor.ts +0 -0
  62. package/src/infrastructure/http/interfaces/RequestOptions.ts +0 -0
  63. package/src/infrastructure/http/providers/DefaultHeaderProvider.ts +0 -0
  64. package/src/lib/httpHelper.js +0 -0
  65. package/src/lib/lastUpdated.js +0 -0
  66. package/src/services/api/types.js +0 -0
  67. package/src/services/config.js +0 -0
  68. package/src/services/content-org/content-org.js +0 -0
  69. package/src/services/content-org/playlists-types.js +0 -0
  70. package/src/services/content-org/playlists.js +0 -0
  71. package/src/services/content.js +0 -0
  72. package/src/services/contentAggregator.js +0 -0
  73. package/src/services/contentLikes.js +0 -0
  74. package/src/services/dataContext.js +0 -0
  75. package/src/services/dateUtils.js +0 -0
  76. package/src/services/forum.js +0 -0
  77. package/src/services/gamification/awards.js +0 -0
  78. package/src/services/gamification/gamification.js +0 -0
  79. package/src/services/gamification/types.js +0 -0
  80. package/src/services/imageSRCVerify.js +0 -0
  81. package/src/services/recommendations.js +0 -0
  82. package/src/services/sanity.js +30 -22
  83. package/src/services/types.js +0 -0
  84. package/src/services/user/chat.js +0 -0
  85. package/src/services/user/interests.js +0 -0
  86. package/src/services/user/management.js +0 -0
  87. package/src/services/user/permissions.js +0 -0
  88. package/src/services/user/profile.js +0 -0
  89. package/src/services/user/sessions.js +0 -0
  90. package/src/services/user/types.js +0 -0
  91. package/src/services/user/user-management-system.js +0 -0
  92. package/test/HttpClient.test.js +0 -0
  93. package/test/content.test.js +0 -0
  94. package/test/contentLikes.test.js +0 -0
  95. package/test/contentProgress.test.js +0 -0
  96. package/test/dataContext.test.js +0 -0
  97. package/test/forum.test.js +0 -0
  98. package/test/imageSRCBuilder.test.js +0 -0
  99. package/test/imageSRCVerify.test.js +0 -0
  100. package/test/initializeTests.js +0 -0
  101. package/test/lib/lastUpdated.test.js +0 -0
  102. package/test/live/contentProgressLive.test.js +0 -0
  103. package/test/live/railcontentLive.test.js +0 -0
  104. package/test/localStorageMock.js +0 -0
  105. package/test/log.js +0 -0
  106. package/test/mockData/mockData_fetchByRailContentIds_one_content.json +0 -0
  107. package/test/mockData/mockData_progress_content.json +0 -0
  108. package/test/mockData/mockData_sanity_progress_content.json +0 -0
  109. package/test/mockData/mockData_user_practices.json +0 -0
  110. package/test/progressRows.test.js +0 -0
  111. package/test/sanityQueryService.test.js +0 -0
  112. package/test/streakMessage.test.js +0 -0
  113. package/test/user/permissions.test.js +0 -0
  114. package/test/userActivity.test.js +0 -0
  115. package/tools/generate-index.cjs +0 -0
  116. package/.yarnrc.yml +0 -1
package/.coderabbit.yaml CHANGED
File without changes
package/.editorconfig CHANGED
File without changes
File without changes
File without changes
package/.prettierignore CHANGED
File without changes
package/.prettierrc CHANGED
File without changes
package/CHANGELOG.md CHANGED
@@ -2,6 +2,8 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
4
4
 
5
+ ### [2.11.1](https://github.com/railroadmedia/musora-content-services/compare/v2.11.0...v2.11.1) (2025-06-24)
6
+
5
7
  ## [2.11.0](https://github.com/railroadmedia/musora-content-services/compare/v2.10.0...v2.11.0) (2025-06-24)
6
8
 
7
9
 
package/README.md CHANGED
@@ -6,7 +6,6 @@ allowing you to easily retrieve, filter, and manipulate content for use in vario
6
6
 
7
7
  ## Setup
8
8
  To set up the Musora Content Services project for local development, follow these steps:
9
- - Pull the latest railenvironment `php-8-3-upgrade` branch changes
10
9
  - In the railenvironment directory, start up the container with the `./rrr.sh` command
11
10
  - Run `r setup musora-content-services`
12
11
  - Run `npm install --save-dev jest`
@@ -94,4 +93,4 @@ and having jest installed (`npm install --save-dev jest`). To run the full test
94
93
  npm test
95
94
  ```
96
95
  You can also filter down to specific tests with the `-- -t="..."` option. e.g. you can run the userContext test suite
97
- with `npm test -- -t="userContext"` or just the contentLiked test with `npm test -- -t="contentLiked"`
96
+ with `npm test -- -t="userContext"` or just the contentLiked test with `npm test -- -t="contentLiked"`
package/babel.config.cjs CHANGED
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
package/jest.config.js CHANGED
File without changes
package/jsdoc.json CHANGED
File without changes
package/link_mcs.sh CHANGED
File without changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "musora-content-services",
3
- "version": "2.11.0",
3
+ "version": "2.11.1",
4
4
  "description": "A package for Musoras content services ",
5
5
  "main": "src/index.js",
6
6
  "type": "module",
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
@@ -512,7 +512,7 @@ export async function fetchByRailContentId(id, contentType) {
512
512
  * .then(contents => console.log(contents))
513
513
  * .catch(error => console.error(error));
514
514
  */
515
- export async function fetchByRailContentIds(ids, contentType = undefined, brand= undefined) {
515
+ export async function fetchByRailContentIds(ids, contentType = undefined, brand = undefined) {
516
516
  if (!ids) {
517
517
  return []
518
518
  }
@@ -1320,7 +1320,7 @@ export async function fetchLessonContent(railContentId) {
1320
1320
  })
1321
1321
  const chapterProcess = (result) => {
1322
1322
  const now = getSanityDate(new Date(), false)
1323
- if(result.live_event_start_time && result.live_event_start_time){
1323
+ if (result.live_event_start_time && result.live_event_end_time) {
1324
1324
  result.isLive = result.live_event_start_time <= now && result.live_event_end_time >= now
1325
1325
  }
1326
1326
  const chapters = result.chapters ?? []
@@ -1336,15 +1336,23 @@ export async function fetchLessonContent(railContentId) {
1336
1336
  }
1337
1337
 
1338
1338
  /**
1339
+ * Returns a list of recommended content based on the provided railContentId.
1340
+ * If no recommendations found in recsys, falls back to fetching related lessons.
1339
1341
  *
1340
1342
  * @param railContentId
1341
1343
  * @param brand
1342
1344
  * @param count
1343
- * @returns {Promise<Array<Object>|null>}
1345
+ * @returns {Promise<Array<Object>>}
1344
1346
  */
1345
1347
  export async function fetchRelatedRecommendedContent(railContentId, brand, count = 10) {
1346
1348
  const recommendedItems = await fetchSimilarItems(railContentId, brand, count)
1347
- return fetchByRailContentIds(recommendedItems)
1349
+ if (recommendedItems && recommendedItems.length > 0) {
1350
+ return fetchByRailContentIds(recommendedItems)
1351
+ }
1352
+
1353
+ return await fetchRelatedLessons(railContentId, brand).then((result) =>
1354
+ result.related_lessons?.splice(0, count)
1355
+ )
1348
1356
  }
1349
1357
 
1350
1358
  /**
@@ -1414,18 +1422,20 @@ async function fetchRelatedByLicense(railcontentId, brand, onlyUseSongTypes, cou
1414
1422
  */
1415
1423
  export async function fetchRelatedLessons(railContentId, brand) {
1416
1424
  const filterSameTypeAndSortOrder = await new FilterBuilder(
1417
- `_type==^._type && _type in ${JSON.stringify(typeWithSortOrder)} && brand == "${brand}" && railcontent_id !=${railContentId}`,
1425
+ `_type==^._type && _type in ${JSON.stringify(typeWithSortOrder)} && brand == "${brand}" && railcontent_id !=${railContentId}`
1418
1426
  ).buildFilter()
1419
1427
  const filterSameType = await new FilterBuilder(
1420
- `_type==^._type && !(_type in ${JSON.stringify(typeWithSortOrder)}) && !(defined(parent_type)) && brand == "${brand}" && railcontent_id !=${railContentId}`,
1428
+ `_type==^._type && !(_type in ${JSON.stringify(typeWithSortOrder)}) && !(defined(parent_type)) && brand == "${brand}" && railcontent_id !=${railContentId}`
1421
1429
  ).buildFilter()
1422
1430
  const filterSongSameArtist = await new FilterBuilder(
1423
- `_type=="song" && _type==^._type && brand == "${brand}" && references(^.artist->_id) && railcontent_id !=${railContentId}`,
1431
+ `_type=="song" && _type==^._type && brand == "${brand}" && references(^.artist->_id) && railcontent_id !=${railContentId}`
1424
1432
  ).buildFilter()
1425
1433
  const filterSongSameGenre = await new FilterBuilder(
1426
- `_type=="song" && _type==^._type && brand == "${brand}" && references(^.genre[]->_id) && railcontent_id !=${railContentId}`,
1434
+ `_type=="song" && _type==^._type && brand == "${brand}" && references(^.genre[]->_id) && railcontent_id !=${railContentId}`
1427
1435
  ).buildFilter()
1428
- const filterNeighbouringSiblings = await new FilterBuilder(`references(^._id)`, {pullFutureContent: true}).buildFilter()
1436
+ const filterNeighbouringSiblings = await new FilterBuilder(`references(^._id)`, {
1437
+ pullFutureContent: true,
1438
+ }).buildFilter()
1429
1439
  const childrenFilter = await new FilterBuilder(``, { isChildrenFilter: true }).buildFilter()
1430
1440
  const queryFields = `_id, "id":railcontent_id, published_on, "instructor": instructor[0]->name, title, "thumbnail":thumbnail.asset->url, length_in_seconds, web_url_path, "type": _type, difficulty, difficulty_string, railcontent_id, artist->,"permission_id": permission[]->railcontent_id,_type, "genre": genre[]->name`
1431
1441
  const queryFieldsWithSort = queryFields + ', sort'
@@ -1446,15 +1456,15 @@ export async function fetchRelatedLessons(railContentId, brand) {
1446
1456
  let result = await fetchSanity(query, false)
1447
1457
 
1448
1458
  //there's no way in sanity to retrieve the index of an array, so we must calculate after fetch
1449
- if (result['for-calculations']['parents-list']) {
1459
+ if (result['for-calculations'] && result['for-calculations']['parents-list']) {
1450
1460
  const calc = result['for-calculations']
1451
1461
  const parentCount = calc['parents-list'].length
1452
- const currentParent = (calc['parents-list'].indexOf(result['parent_id']) + 1)
1462
+ const currentParent = calc['parents-list'].indexOf(result['parent_id']) + 1
1453
1463
  const siblingCount = calc['siblings-list'].length
1454
- const currentSibling = (calc['siblings-list'].indexOf(result['railcontent_id']) + 1)
1464
+ const currentSibling = calc['siblings-list'].indexOf(result['railcontent_id']) + 1
1455
1465
 
1456
1466
  delete result['for-calculations']
1457
- result = {...result, parentCount, currentParent, siblingCount, currentSibling}
1467
+ result = { ...result, parentCount, currentParent, siblingCount, currentSibling }
1458
1468
  return result
1459
1469
  } else {
1460
1470
  delete result['for-calculations']
@@ -1504,7 +1514,7 @@ export async function fetchPackAll(railcontentId, type = 'pack') {
1504
1514
  }
1505
1515
 
1506
1516
  export async function fetchLiveEvent(brand, forcedContentId = null) {
1507
- const LIVE_EXTRA_MINUTES = 30;
1517
+ const LIVE_EXTRA_MINUTES = 30
1508
1518
  //calendarIDs taken from addevent.php
1509
1519
  // TODO import instructor calendars to Sanity
1510
1520
  let defaultCalendarID = ''
@@ -1526,8 +1536,10 @@ export async function fetchLiveEvent(brand, forcedContentId = null) {
1526
1536
  }
1527
1537
  let startDateTemp = new Date()
1528
1538
  let endDateTemp = new Date()
1529
-
1530
- startDateTemp = new Date(startDateTemp.setMinutes(startDateTemp.getMinutes() + LIVE_EXTRA_MINUTES))
1539
+
1540
+ startDateTemp = new Date(
1541
+ startDateTemp.setMinutes(startDateTemp.getMinutes() + LIVE_EXTRA_MINUTES)
1542
+ )
1531
1543
  endDateTemp = new Date(endDateTemp.setMinutes(endDateTemp.getMinutes() - LIVE_EXTRA_MINUTES))
1532
1544
 
1533
1545
  // See LiveStreamEventService.getCurrentOrNextLiveEvent for some nice complicated logic which I don't think is actually importart
@@ -2394,17 +2406,13 @@ export async function fetchScheduledAndNewReleases(
2394
2406
  return fetchSanity(query, true)
2395
2407
  }
2396
2408
 
2397
- export async function fetchShows(
2398
- brand,
2399
- type,
2400
- sort = 'sort'
2401
- ) {
2409
+ export async function fetchShows(brand, type, sort = 'sort') {
2402
2410
  const sortOrder = getSortOrder(sort, brand)
2403
2411
  const filter = `_type == '${type}' && brand == '${brand}'`
2404
2412
  const filterParams = {}
2405
2413
 
2406
2414
  const query = await buildQuery(filter, filterParams, getFieldsForContentType(type), {
2407
- sortOrder: sortOrder
2415
+ sortOrder: sortOrder,
2408
2416
  })
2409
2417
  return fetchSanity(query, true)
2410
2418
  }
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
package/test/log.js CHANGED
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
package/.yarnrc.yml DELETED
@@ -1 +0,0 @@
1
- nodeLinker: node-modules