musora-content-services 2.16.0 → 2.17.0

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 (166) 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/conventional-commits.yaml +0 -0
  5. package/.github/workflows/docs.js.yml +0 -0
  6. package/.github/workflows/node.js.yml +0 -0
  7. package/.prettierignore +0 -0
  8. package/.prettierrc +0 -0
  9. package/.yarnrc.yml +1 -0
  10. package/CHANGELOG.md +15 -0
  11. package/README.md +0 -0
  12. package/babel.config.cjs +0 -0
  13. package/docs/Content-Organization.html +0 -0
  14. package/docs/ContentOrganization.html +2 -2
  15. package/docs/Gamification.html +2 -2
  16. package/docs/UserManagement.html +0 -0
  17. package/docs/UserManagementSystem.html +2 -2
  18. package/docs/api_types.js.html +2 -2
  19. package/docs/config.js.html +2 -2
  20. package/docs/content-org_content-org.js.html +2 -2
  21. package/docs/content-org_playlists-types.js.html +2 -2
  22. package/docs/content-org_playlists.js.html +2 -2
  23. package/docs/content.js.html +2 -2
  24. package/docs/fonts/Montserrat/Montserrat-Bold.eot +0 -0
  25. package/docs/fonts/Montserrat/Montserrat-Bold.ttf +0 -0
  26. package/docs/fonts/Montserrat/Montserrat-Bold.woff +0 -0
  27. package/docs/fonts/Montserrat/Montserrat-Bold.woff2 +0 -0
  28. package/docs/fonts/Montserrat/Montserrat-Regular.eot +0 -0
  29. package/docs/fonts/Montserrat/Montserrat-Regular.ttf +0 -0
  30. package/docs/fonts/Montserrat/Montserrat-Regular.woff +0 -0
  31. package/docs/fonts/Montserrat/Montserrat-Regular.woff2 +0 -0
  32. package/docs/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.eot +0 -0
  33. package/docs/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.svg +0 -0
  34. package/docs/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.ttf +0 -0
  35. package/docs/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.woff +0 -0
  36. package/docs/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.woff2 +0 -0
  37. package/docs/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.eot +0 -0
  38. package/docs/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.svg +0 -0
  39. package/docs/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.ttf +0 -0
  40. package/docs/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.woff +0 -0
  41. package/docs/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.woff2 +0 -0
  42. package/docs/gamification_awards.js.html +2 -2
  43. package/docs/gamification_gamification.js.html +2 -2
  44. package/docs/gamification_types.js.html +2 -2
  45. package/docs/global.html +2 -2
  46. package/docs/global.html#User +0 -0
  47. package/docs/index.html +2 -2
  48. package/docs/module-Awards.html +2 -2
  49. package/docs/module-Config.html +2 -2
  50. package/docs/module-Content-Services-V2.html +2 -2
  51. package/docs/module-Interests.html +2 -2
  52. package/docs/module-Notifications.html +0 -0
  53. package/docs/module-Permissions.html +2 -2
  54. package/docs/module-Playlists.html +2 -2
  55. package/docs/module-Railcontent-Services.html +175 -7
  56. package/docs/module-Sanity-Services.html +28 -28
  57. package/docs/module-Session-Management.html +0 -0
  58. package/docs/module-Sessions.html +2 -2
  59. package/docs/module-User-Activity.html +0 -0
  60. package/docs/module-User-Management.html +0 -0
  61. package/docs/module-User-Permissions.html +0 -0
  62. package/docs/module-UserActivity.html +30 -6
  63. package/docs/module-UserChat.html +2 -2
  64. package/docs/module-UserManagement.html +2 -2
  65. package/docs/module-UserNotifications.html +12 -98
  66. package/docs/module-UserProfile.html +2 -2
  67. package/docs/railcontent.js.html +19 -2
  68. package/docs/sanity.js.html +17 -8
  69. package/docs/scripts/collapse.js +0 -0
  70. package/docs/scripts/commonNav.js +0 -0
  71. package/docs/scripts/linenumber.js +0 -0
  72. package/docs/scripts/nav.js +0 -0
  73. package/docs/scripts/polyfill.js +0 -0
  74. package/docs/scripts/prettify/Apache-License-2.0.txt +0 -0
  75. package/docs/scripts/prettify/lang-css.js +0 -0
  76. package/docs/scripts/prettify/prettify.js +0 -0
  77. package/docs/scripts/search.js +0 -0
  78. package/docs/styles/jsdoc.css +0 -0
  79. package/docs/styles/prettify.css +0 -0
  80. package/docs/types.js.html +0 -0
  81. package/docs/userActivity.js.html +15 -21
  82. package/docs/user_chat.js.html +2 -2
  83. package/docs/user_interests.js.html +2 -2
  84. package/docs/user_management.js.html +2 -2
  85. package/docs/user_notifications.js.html +8 -18
  86. package/docs/user_permissions.js.html +2 -2
  87. package/docs/user_profile.js.html +2 -2
  88. package/docs/user_sessions.js.html +2 -2
  89. package/docs/user_types.js.html +2 -2
  90. package/docs/user_user-management-system.js.html +2 -2
  91. package/docs/user_user-management.js.html +0 -0
  92. package/jest.config.js +0 -0
  93. package/jsdoc.json +0 -0
  94. package/link_mcs.sh +0 -0
  95. package/package.json +1 -1
  96. package/src/contentMetaData.js +0 -0
  97. package/src/filterBuilder.js +0 -0
  98. package/src/index.d.ts +2 -0
  99. package/src/index.js +2 -0
  100. package/src/infrastructure/http/HttpClient.ts +0 -0
  101. package/src/infrastructure/http/executors/FetchRequestExecutor.ts +0 -0
  102. package/src/infrastructure/http/index.ts +0 -0
  103. package/src/infrastructure/http/interfaces/HeaderProvider.ts +0 -0
  104. package/src/infrastructure/http/interfaces/HttpError.ts +0 -0
  105. package/src/infrastructure/http/interfaces/NetworkError.ts +0 -0
  106. package/src/infrastructure/http/interfaces/RequestExecutor.ts +0 -0
  107. package/src/infrastructure/http/interfaces/RequestOptions.ts +0 -0
  108. package/src/infrastructure/http/providers/DefaultHeaderProvider.ts +0 -0
  109. package/src/lib/httpHelper.js +0 -0
  110. package/src/lib/lastUpdated.js +0 -0
  111. package/src/services/api/types.js +0 -0
  112. package/src/services/config.js +0 -0
  113. package/src/services/content-org/content-org.js +0 -0
  114. package/src/services/content-org/guided-courses.ts +0 -0
  115. package/src/services/content-org/playlists-types.js +0 -0
  116. package/src/services/content-org/playlists.js +0 -0
  117. package/src/services/content.js +0 -0
  118. package/src/services/contentAggregator.js +0 -0
  119. package/src/services/contentLikes.js +0 -0
  120. package/src/services/contentProgress.js +0 -0
  121. package/src/services/dataContext.js +0 -0
  122. package/src/services/dateUtils.js +0 -0
  123. package/src/services/forum.js +0 -0
  124. package/src/services/gamification/awards.js +0 -0
  125. package/src/services/gamification/gamification.js +0 -0
  126. package/src/services/gamification/types.js +0 -0
  127. package/src/services/imageSRCBuilder.js +0 -0
  128. package/src/services/railcontent.js +17 -0
  129. package/src/services/recommendations.js +0 -0
  130. package/src/services/sanity.js +11 -3
  131. package/src/services/types.js +0 -0
  132. package/src/services/user/chat.js +0 -0
  133. package/src/services/user/interests.js +0 -0
  134. package/src/services/user/management.js +0 -0
  135. package/src/services/user/notifications.js +6 -16
  136. package/src/services/user/permissions.js +0 -0
  137. package/src/services/user/profile.js +0 -0
  138. package/src/services/user/sessions.js +0 -0
  139. package/src/services/user/types.js +0 -0
  140. package/src/services/user/user-management-system.js +0 -0
  141. package/src/services/userActivity.js +0 -0
  142. package/test/HttpClient.test.js +0 -0
  143. package/test/content.test.js +0 -0
  144. package/test/contentLikes.test.js +0 -0
  145. package/test/contentProgress.test.js +0 -0
  146. package/test/dataContext.test.js +0 -0
  147. package/test/forum.test.js +0 -0
  148. package/test/imageSRCBuilder.test.js +0 -0
  149. package/test/imageSRCVerify.test.js +0 -0
  150. package/test/initializeTests.js +0 -0
  151. package/test/lib/lastUpdated.test.js +0 -0
  152. package/test/live/contentProgressLive.test.js +0 -0
  153. package/test/live/railcontentLive.test.js +0 -0
  154. package/test/localStorageMock.js +0 -0
  155. package/test/log.js +0 -0
  156. package/test/mockData/mockData_fetchByRailContentIds_one_content.json +0 -0
  157. package/test/mockData/mockData_progress_content.json +0 -0
  158. package/test/mockData/mockData_sanity_progress_content.json +0 -0
  159. package/test/mockData/mockData_user_practices.json +0 -0
  160. package/test/notifications.test.js +3 -12
  161. package/test/progressRows.test.js +0 -0
  162. package/test/sanityQueryService.test.js +0 -0
  163. package/test/streakMessage.test.js +0 -0
  164. package/test/user/permissions.test.js +0 -0
  165. package/test/userActivity.test.js +0 -0
  166. package/tools/generate-index.cjs +0 -0
File without changes
File without changes
package/src/index.d.ts CHANGED
@@ -118,6 +118,7 @@ import {
118
118
  fetchChallengeLessonData,
119
119
  fetchChallengeMetadata,
120
120
  fetchChallengeUserActiveChallenges,
121
+ fetchComment,
121
122
  fetchCommentRelies,
122
123
  fetchComments,
123
124
  fetchCompletedChallenges,
@@ -342,6 +343,7 @@ declare module 'musora-content-services' {
342
343
  fetchChatSettings,
343
344
  fetchCoachLessons,
344
345
  fetchComingSoon,
346
+ fetchComment,
345
347
  fetchCommentModContentData,
346
348
  fetchCommentRelies,
347
349
  fetchComments,
package/src/index.js CHANGED
@@ -118,6 +118,7 @@ import {
118
118
  fetchChallengeLessonData,
119
119
  fetchChallengeMetadata,
120
120
  fetchChallengeUserActiveChallenges,
121
+ fetchComment,
121
122
  fetchCommentRelies,
122
123
  fetchComments,
123
124
  fetchCompletedChallenges,
@@ -341,6 +342,7 @@ export {
341
342
  fetchChatSettings,
342
343
  fetchCoachLessons,
343
344
  fetchComingSoon,
345
+ fetchComment,
344
346
  fetchCommentModContentData,
345
347
  fetchCommentRelies,
346
348
  fetchComments,
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
@@ -755,6 +755,23 @@ export async function reportComment(commentId, issue) {
755
755
  return await postDataHandler(url, data)
756
756
  }
757
757
 
758
+ /**
759
+ * Fetches a single comment by its ID.
760
+ *
761
+ * @param {number|string} commentId - The ID of the comment to fetch.
762
+ * @returns {Promise<Object|null>} - A promise that resolves to the comment object if found, otherwise null.
763
+ *
764
+ * @example
765
+ * fetchComment(123)
766
+ * .then(comment => console.log(comment))
767
+ * .catch(error => console.error(error));
768
+ */
769
+ export async function fetchComment(commentId) {
770
+ const url = `/api/content/v1/comments/${commentId}`
771
+ const comment = await fetchHandler(url)
772
+ return comment.parent ? comment.parent : comment
773
+ }
774
+
758
775
  export async function fetchUserPractices(currentVersion = 0, { userId } = {}) {
759
776
  const params = new URLSearchParams();
760
777
  if (userId) params.append('user_id', userId);
File without changes
@@ -17,7 +17,7 @@ import {
17
17
  getChildFieldsForContentType,
18
18
  SONG_TYPES,
19
19
  } from '../contentTypeConfig.js'
20
- import { fetchSimilarItems } from './recommendations.js'
20
+ import {fetchSimilarItems, recommendations} from './recommendations.js'
21
21
  import { processMetadata, typeWithSortOrder } from '../contentMetaData.js'
22
22
 
23
23
  import { globalConfig } from './config.js'
@@ -903,7 +903,7 @@ async function getProgressFilter(progress, progressIds) {
903
903
  export function getSortOrder(sort = '-published_on', brand, groupBy) {
904
904
  // Determine the sort order
905
905
  let sortOrder = ''
906
- const isDesc = sort.startsWith('-')
906
+ let isDesc = sort.startsWith('-')
907
907
  sort = isDesc ? sort.substring(1) : sort
908
908
  switch (sort) {
909
909
  case 'slug':
@@ -919,6 +919,10 @@ export function getSortOrder(sort = '-published_on', brand, groupBy) {
919
919
  sortOrder = isDesc ? 'coalesce(popularity, -1)' : 'popularity'
920
920
  }
921
921
  break
922
+ case 'recommended':
923
+ sortOrder = 'published_on'
924
+ isDesc = true
925
+ break
922
926
  case 'published_on':
923
927
  default:
924
928
  sortOrder = 'published_on'
@@ -2337,6 +2341,10 @@ export async function fetchTabData(
2337
2341
 
2338
2342
  // limits the results to supplied progressIds for started & completed filters
2339
2343
  const progressFilter = await getProgressFilter(progress, progressIds)
2344
+ if(sort == "recommended"){
2345
+ progressIds = await recommendations(brand);
2346
+ withoutPagination = true;
2347
+ }
2340
2348
 
2341
2349
  let fields = DEFAULT_FIELDS
2342
2350
  let fieldsString = fields.join(',')
@@ -2369,7 +2377,7 @@ export async function fetchTabData(
2369
2377
 
2370
2378
  let results = await fetchSanity(query, true);
2371
2379
 
2372
- if (['recent', 'incomplete', 'completed'].includes(progress) && results.entity.length > 1) {
2380
+ if ((['recent', 'incomplete', 'completed'].includes(progress) || sort == "recommended" )&& results.entity.length > 1) {
2373
2381
  const orderMap = new Map(progressIds.map((id, index) => [id, index]))
2374
2382
  results.entity = results.entity
2375
2383
  .sort((a, b) => {
File without changes
File without changes
File without changes
File without changes
@@ -16,7 +16,6 @@ const NotificationChannels = {
16
16
  * Fetches notifications for a given brand with optional filters for unread status and limit.
17
17
  *
18
18
  * @param {Object} [options={}] - Options for fetching notifications.
19
- * @param {string} options.brand - The brand to filter notifications by. (Required)
20
19
  * @param {number} [options.limit=10] - The maximum number of notifications to fetch.
21
20
  * @param {number} [options.page=1] - The page number for pagination.
22
21
  * @param {boolean} [options.onlyUnread=false] - Whether to fetch only unread notifications. If true, adds `unread=1` to the query.
@@ -26,17 +25,13 @@ const NotificationChannels = {
26
25
  * @throws {Error} - Throws an error if the brand is not provided.
27
26
  *
28
27
  * @example
29
- * fetchNotifications({ brand: 'drumeo', limit: 5, onlyUnread: true, page: 2 })
28
+ * fetchNotifications({ limit: 5, onlyUnread: true, page: 2 })
30
29
  * .then(notifications => console.log(notifications))
31
30
  * .catch(error => console.error(error));
32
31
  */
33
- export async function fetchNotifications({ brand = null, limit = 10, onlyUnread = false, page = 1 } = {}) {
34
- if (!brand) {
35
- throw new Error('brand is required')
36
- }
37
-
32
+ export async function fetchNotifications({ limit = 10, onlyUnread = false, page = 1 } = {}) {
38
33
  const unreadParam = onlyUnread ? '&unread=1' : ''
39
- const url = `${baseUrl}/v1?brand=${brand}${unreadParam}&limit=${limit}&page=${page}`
34
+ const url = `${baseUrl}/v1?limit=${limit}&page=${page}${unreadParam}`
40
35
  return fetchHandler(url, 'get')
41
36
  }
42
37
 
@@ -66,8 +61,6 @@ export async function markNotificationAsRead(notificationId) {
66
61
  /**
67
62
  * Marks all notifications as read for a specific brand.
68
63
  *
69
- * @param {string} brand - The brand to filter notifications by.
70
- *
71
64
  * @returns {Promise<any>} - A promise that resolves when all notifications are marked as read.
72
65
  *
73
66
  * @example
@@ -75,8 +68,8 @@ export async function markNotificationAsRead(notificationId) {
75
68
  * .then(response => console.log(response))
76
69
  * .catch(error => console.error(error));
77
70
  */
78
- export async function markAllNotificationsAsRead(brand) {
79
- const url = `${baseUrl}/v1/read?brand=${brand}`
71
+ export async function markAllNotificationsAsRead() {
72
+ const url = `${baseUrl}/v1/read`
80
73
  return fetchHandler(url, 'put')
81
74
  }
82
75
 
@@ -141,10 +134,7 @@ export async function deleteNotification(notificationId) {
141
134
  * .catch(error => console.error(error));
142
135
  */
143
136
  export async function fetchUnreadCount({ brand = null} = {}) {
144
- if (!brand) {
145
- throw new Error('brand is required')
146
- }
147
- const url = `${baseUrl}/v1/unread-count?brand=${brand}`
137
+ const url = `${baseUrl}/v1/unread-count`
148
138
  return fetchHandler(url, 'get')
149
139
  }
150
140
 
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
@@ -16,22 +16,17 @@ describe('UserNotifications module', function () {
16
16
  })
17
17
 
18
18
  describe('fetchNotifications', () => {
19
- it('throws if brand not provided', async () => {
20
- await expect(UserNotifications.fetchNotifications()).rejects.toThrow('brand is required')
21
- })
22
-
23
19
  it('calls fetchHandler with correct url and method', async () => {
24
20
  fetchHandler.mockResolvedValueOnce([{ id: 1 }])
25
21
 
26
22
  const result = await UserNotifications.fetchNotifications({
27
- brand: 'drumeo',
28
23
  limit: 5,
29
24
  onlyUnread: true,
30
25
  page: 2,
31
26
  })
32
27
 
33
28
  expect(fetchHandler).toHaveBeenCalledWith(
34
- `${baseUrl}/v1?brand=drumeo&unread=1&limit=5&page=2`,
29
+ `${baseUrl}/v1?limit=5&page=2&unread=1`,
35
30
  'get'
36
31
  )
37
32
  expect(result).toEqual([{ id: 1 }])
@@ -91,15 +86,11 @@ describe('UserNotifications module', function () {
91
86
  })
92
87
 
93
88
  describe('fetchUnreadCount', () => {
94
- it('throws if brand not provided', async () => {
95
- await expect(UserNotifications.fetchUnreadCount()).rejects.toThrow('brand is required')
96
- })
97
-
98
89
  it('calls fetchHandler with correct url and method', async () => {
99
90
  fetchHandler.mockResolvedValueOnce({ unread_count: 42 })
100
91
 
101
- const result = await UserNotifications.fetchUnreadCount({ brand: 'drumeo' })
102
- expect(fetchHandler).toHaveBeenCalledWith(`${baseUrl}/v1/unread-count?brand=drumeo`, 'get')
92
+ const result = await UserNotifications.fetchUnreadCount()
93
+ expect(fetchHandler).toHaveBeenCalledWith(`${baseUrl}/v1/unread-count`, 'get')
103
94
  expect(result).toEqual({ unread_count: 42 })
104
95
  })
105
96
  })
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes