musora-content-services 2.1.0 → 2.2.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 (79) hide show
  1. package/.github/workflows/node.js.yml +0 -0
  2. package/.prettierignore +0 -0
  3. package/.prettierrc +0 -0
  4. package/CHANGELOG.md +9 -0
  5. package/README.md +0 -0
  6. package/babel.config.cjs +0 -0
  7. package/docs/Content-Organization.html +2 -2
  8. package/docs/Gamification.html +245 -0
  9. package/docs/api_types.js.html +97 -0
  10. package/docs/config.js.html +2 -2
  11. package/docs/content-org_playlists-types.js.html +3 -5
  12. package/docs/content-org_playlists.js.html +8 -9
  13. package/docs/content.js.html +2 -2
  14. package/docs/fonts/Montserrat/Montserrat-Bold.eot +0 -0
  15. package/docs/fonts/Montserrat/Montserrat-Bold.ttf +0 -0
  16. package/docs/fonts/Montserrat/Montserrat-Bold.woff +0 -0
  17. package/docs/fonts/Montserrat/Montserrat-Bold.woff2 +0 -0
  18. package/docs/fonts/Montserrat/Montserrat-Regular.eot +0 -0
  19. package/docs/fonts/Montserrat/Montserrat-Regular.ttf +0 -0
  20. package/docs/fonts/Montserrat/Montserrat-Regular.woff +0 -0
  21. package/docs/fonts/Montserrat/Montserrat-Regular.woff2 +0 -0
  22. package/docs/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.eot +0 -0
  23. package/docs/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.svg +0 -0
  24. package/docs/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.ttf +0 -0
  25. package/docs/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.woff +0 -0
  26. package/docs/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.woff2 +0 -0
  27. package/docs/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.eot +0 -0
  28. package/docs/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.svg +0 -0
  29. package/docs/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.ttf +0 -0
  30. package/docs/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.woff +0 -0
  31. package/docs/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.woff2 +0 -0
  32. package/docs/gamification_awards.js.html +664 -0
  33. package/docs/gamification_gamification.js.html +76 -0
  34. package/docs/gamification_types.js.html +98 -0
  35. package/docs/global.html +1441 -153
  36. package/docs/index.html +2 -2
  37. package/docs/module-Awards.html +354 -0
  38. package/docs/module-Config.html +2 -2
  39. package/docs/module-Content-Services-V2.html +2 -2
  40. package/docs/module-Playlists.html +6 -6
  41. package/docs/module-Railcontent-Services.html +33 -194
  42. package/docs/module-Sanity-Services.html +885 -90
  43. package/docs/module-Session-Management.html +2 -2
  44. package/docs/module-User-Permissions.html +2 -2
  45. package/docs/railcontent.js.html +13 -25
  46. package/docs/sanity.js.html +76 -5
  47. package/docs/scripts/collapse.js +0 -0
  48. package/docs/scripts/commonNav.js +0 -0
  49. package/docs/scripts/linenumber.js +0 -0
  50. package/docs/scripts/nav.js +0 -0
  51. package/docs/scripts/polyfill.js +0 -0
  52. package/docs/scripts/prettify/Apache-License-2.0.txt +0 -0
  53. package/docs/scripts/prettify/lang-css.js +0 -0
  54. package/docs/scripts/prettify/prettify.js +0 -0
  55. package/docs/scripts/search.js +0 -0
  56. package/docs/styles/jsdoc.css +0 -0
  57. package/docs/styles/prettify.css +0 -0
  58. package/docs/user_permissions.js.html +3 -3
  59. package/docs/user_sessions.js.html +4 -4
  60. package/docs/user_types.js.html +2 -2
  61. package/jest.config.js +0 -0
  62. package/jsdoc.json +4 -2
  63. package/package.json +1 -1
  64. package/src/index.d.ts +5 -1
  65. package/src/index.js +5 -0
  66. package/src/lib/httpHelper.js +46 -0
  67. package/src/services/api/types.js +25 -0
  68. package/src/services/contentLikes.js +0 -0
  69. package/src/services/gamification/awards.js +592 -0
  70. package/src/services/gamification/gamification.js +4 -0
  71. package/src/services/gamification/types.js +26 -0
  72. package/src/services/railcontent.js +9 -59
  73. package/src/services/recommendations.js +8 -39
  74. package/src/services/sanity.js +12 -14
  75. package/src/services/user/management.js +35 -0
  76. package/test/live/contentProgressLive.test.js +0 -0
  77. package/test/live/railcontentLive.test.js +0 -0
  78. package/test/localStorageMock.js +0 -0
  79. package/test/log.js +0 -0
@@ -0,0 +1,4 @@
1
+ /**
2
+ * @namespace Gamification
3
+ * @property {module:Awards} Awards
4
+ */
@@ -0,0 +1,26 @@
1
+ /**
2
+ * @typedef {Object} Award
3
+ * @property {string} username - The username of the user.
4
+ * @property {number} streak - The name of the award.
5
+ * @property {number} minutes_practiced - The name of the award.
6
+ * @property {Date} date_completed - Date of completion
7
+ * @property {string} challenge_title - The name of the challenge completed.
8
+ * @property {string} award_text - Award description
9
+ * @property {string} tier - Award tier [bronze, silver, gold]
10
+ * @property {string} award - Award image URL
11
+ * @property {string} award_64 - Award image in base64
12
+ * @property {string} instructor_signature - Instructor signature image URL
13
+ * @property {string} instructor_signature_64 - Instructor signature image in base64
14
+ * @property {string} musora_logo - Musora logo image URL
15
+ * @property {string} musora_logo_64 - Musora logo image in base64
16
+ * @property {string} brand_logo - Brand logo image URL
17
+ * @property {string} brand_logo_64 - Brand logo image in base64
18
+ * @property {string} ribbon_image - Ribbon image URL
19
+ * @property {string} ribbon_image_64 - Ribbon image in base64
20
+ * @property {number} id - ID of the challenge completed
21
+ * @property {string} artist_name - Name of the artist featured in the challenge
22
+ * @property {string} dark_mode_logo_url - Dark mode logo image URL
23
+ * @property {string} light_mode_logo_url - Light mode logo image URL
24
+ * @property {string} logo_image_url - Name of the artist featured in the challenge
25
+ * @property {string} web_url_path - URL path for the challenge
26
+ */
@@ -4,6 +4,7 @@
4
4
  import { contentStatusCompleted } from './contentProgress.js'
5
5
 
6
6
  import { globalConfig } from './config.js'
7
+ import { fetchJSONHandler } from '../lib/httpHelper.js'
7
8
 
8
9
  /**
9
10
  * Exported functions that are excluded from index generation.
@@ -294,54 +295,6 @@ async function deleteDataHandler(url, data) {
294
295
  return fetchHandler(url, 'delete')
295
296
  }
296
297
 
297
- // TODO: this should be extracted to a utility file
298
- export async function fetchHandler(url, method = 'get', dataVersion = null, body = null) {
299
- let headers = {
300
- 'Content-Type': 'application/json',
301
- Accept: 'application/json',
302
- 'X-CSRF-TOKEN': globalConfig.railcontentConfig.token,
303
- }
304
-
305
- if (!globalConfig.isMA) {
306
- const params = new URLSearchParams(window.location.search)
307
- if (params.get('testNow')) {
308
- headers['testNow'] = params.get('testNow')
309
- }
310
- if (params.get('timezone')) {
311
- headers['M-Client-Timezone'] = params.get('timezone')
312
- }
313
- }
314
-
315
- if (globalConfig.localTimezoneString) {
316
- headers['M-Client-Timezone'] = globalConfig.localTimezoneString
317
- }
318
-
319
- if (globalConfig.railcontentConfig.authToken) {
320
- headers['Authorization'] = `Bearer ${globalConfig.railcontentConfig.authToken}`
321
- }
322
-
323
- if (dataVersion) headers['Data-Version'] = dataVersion
324
- const options = {
325
- method,
326
- headers,
327
- }
328
- if (body) {
329
- options.body = JSON.stringify(body)
330
- }
331
- try {
332
- const response = await fetchAbsolute(url, options)
333
- if (response.ok) {
334
- return await response.json()
335
- } else {
336
- console.error(`Fetch error: ${method} ${url} ${response.status} ${response.statusText}`)
337
- console.log(response)
338
- }
339
- } catch (error) {
340
- console.error('Fetch error:', error)
341
- }
342
- return null
343
- }
344
-
345
298
  export async function fetchUserLikes(currentVersion) {
346
299
  let url = `/api/content/v1/user/likes`
347
300
  return fetchDataHandler(url, currentVersion)
@@ -1223,15 +1176,12 @@ export async function editComment(commentId, comment) {
1223
1176
  return await patchDataHandler(url, data)
1224
1177
  }
1225
1178
 
1226
- function fetchAbsolute(url, params) {
1227
- if (globalConfig.railcontentConfig.authToken) {
1228
- params.headers['Authorization'] = `Bearer ${globalConfig.railcontentConfig.authToken}`
1229
- }
1230
-
1231
- if (globalConfig.railcontentConfig.baseUrl) {
1232
- if (url.startsWith('/')) {
1233
- return fetch(globalConfig.railcontentConfig.baseUrl + url, params)
1234
- }
1235
- }
1236
- return fetch(url, params)
1179
+ export async function fetchHandler(url, method = 'get', dataVersion = null, body = null) {
1180
+ return fetchJSONHandler(
1181
+ url,
1182
+ globalConfig.railcontentConfig.token,
1183
+ globalConfig.railcontentConfig.baseUrl,
1184
+ method,
1185
+ dataVersion,
1186
+ body)
1237
1187
  }
@@ -3,6 +3,7 @@
3
3
  */
4
4
 
5
5
  import { globalConfig } from './config.js'
6
+ import { fetchJSONHandler} from '../lib/httpHelper.js'
6
7
 
7
8
  /**
8
9
  * Exported functions that are excluded from index generation.
@@ -129,44 +130,12 @@ export async function recommendations(brand, {
129
130
  }
130
131
 
131
132
  async function fetchHandler(url, method = 'get', body = null) {
132
-
133
- let headers = {
134
- 'Content-Type': 'application/json',
135
- Accept: 'application/json',
136
- 'X-CSRF-TOKEN': globalConfig.recommendationsConfig.token,
137
- }
138
-
139
- const options = {
133
+ return fetchJSONHandler(
134
+ url,
135
+ globalConfig.recommendationsConfig.token,
136
+ globalConfig.recommendationsConfig.baseUrl,
140
137
  method,
141
- headers,
142
- }
143
-
144
- if (body) {
145
- options.body = JSON.stringify(body)
146
- }
147
- try {
148
- const response = await fetchAbsolute(url, options)
149
- if (response.ok) {
150
- return await response.json()
151
- } else {
152
- console.error(`Fetch error: ${method} ${url} ${response.status} ${response.statusText}`)
153
- console.log(response)
154
- }
155
- } catch (error) {
156
- console.error('Fetch error:', error)
157
- }
158
- return null
159
- }
160
-
161
-
162
- function fetchAbsolute(url, params) {
163
- if (globalConfig.recommendationsConfig.token) {
164
- params.headers['Authorization'] = `Bearer ${globalConfig.recommendationsConfig.token}`
165
- }
166
- if (globalConfig.recommendationsConfig.baseUrl) {
167
- if (url.startsWith('/')) {
168
- return fetch(globalConfig.recommendationsConfig.baseUrl + url, params)
169
- }
170
- }
171
- return fetch(url, params)
138
+ null,
139
+ body
140
+ )
172
141
  }
@@ -15,7 +15,7 @@ import {
15
15
  getNewReleasesTypes,
16
16
  coachLessonsTypes,
17
17
  getChildFieldsForContentType,
18
- SONG_TYPES
18
+ SONG_TYPES,
19
19
  } from '../contentTypeConfig.js'
20
20
  import { fetchSimilarItems } from './recommendations.js'
21
21
  import { processMetadata, typeWithSortOrder } from '../contentMetaData.js'
@@ -1321,7 +1321,7 @@ export async function fetchLessonContent(railContentId) {
1321
1321
  * @param count
1322
1322
  * @returns {Promise<Array<Object>|null>}
1323
1323
  */
1324
- export async function fetchRelatedRecommendedContent(railContentId, brand, count=10) {
1324
+ export async function fetchRelatedRecommendedContent(railContentId, brand, count = 10) {
1325
1325
  const recommendedItems = await fetchSimilarItems(railContentId, brand, count)
1326
1326
  return fetchByRailContentIds(recommendedItems)
1327
1327
  }
@@ -1333,9 +1333,9 @@ export async function fetchRelatedRecommendedContent(railContentId, brand, count
1333
1333
  * @param railcontentId
1334
1334
  * @param brand
1335
1335
  * @param count
1336
- * @returns {Promise<*>}
1336
+ * @returns {Promise<Array<Object>>}
1337
1337
  */
1338
- export async function fetchOtherSongVersions(railcontentId, brand, count=3){
1338
+ export async function fetchOtherSongVersions(railcontentId, brand, count = 3) {
1339
1339
  return fetchRelatedByLicense(railcontentId, brand, true, count)
1340
1340
  }
1341
1341
 
@@ -1346,9 +1346,9 @@ export async function fetchOtherSongVersions(railcontentId, brand, count=3){
1346
1346
  * @param {integer} railcontentId
1347
1347
  * @param {string} brand
1348
1348
  * @param {integer:3} count
1349
- * @returns {Promise<*>}
1349
+ * @returns {Promise<Array<Object>>}
1350
1350
  */
1351
- export async function fetchLessonsFeaturingThisContent(railcontentId, brand, count=3){
1351
+ export async function fetchLessonsFeaturingThisContent(railcontentId, brand, count = 3) {
1352
1352
  return fetchRelatedByLicense(railcontentId, brand, false, count)
1353
1353
  }
1354
1354
 
@@ -1359,16 +1359,15 @@ export async function fetchLessonsFeaturingThisContent(railcontentId, brand, cou
1359
1359
  * @param {string} brand
1360
1360
  * @param {boolean} onlyUseSongTypes - if true, only return the song type documents. If false, return everything except those
1361
1361
  * @param {integer:3} count
1362
- * @returns {Promise<*[]>}
1362
+ * @returns {Promise<Array<Object>>}
1363
1363
  */
1364
1364
  async function fetchRelatedByLicense(railcontentId, brand, onlyUseSongTypes, count) {
1365
1365
  const typeCheck = `@->_type in [${arrayJoinWithQuotes(SONG_TYPES)}]`
1366
1366
  const typeCheckString = onlyUseSongTypes ? `${typeCheck}` : `!(${typeCheck})`
1367
- const contentFromLicenseFilter =`_type == 'license' && references(^._id)].content[${typeCheckString} && @->railcontent_id != ${railcontentId}`
1368
- let filterSongTypesWithSameLicense = await new FilterBuilder(
1369
- contentFromLicenseFilter,
1370
- {isChildrenFilter: true},
1371
- ).buildFilter()
1367
+ const contentFromLicenseFilter = `_type == 'license' && references(^._id)].content[${typeCheckString} && @->railcontent_id != ${railcontentId}`
1368
+ let filterSongTypesWithSameLicense = await new FilterBuilder(contentFromLicenseFilter, {
1369
+ isChildrenFilter: true,
1370
+ }).buildFilter()
1372
1371
  let queryFields = getFieldsForContentType()
1373
1372
  const baseParentQuery = `railcontent_id == ${railcontentId}`
1374
1373
  let parentQuery = await new FilterBuilder(baseParentQuery).buildFilter()
@@ -1383,7 +1382,7 @@ async function fetchRelatedByLicense(railcontentId, brand, onlyUseSongTypes, cou
1383
1382
  }[0...1]`
1384
1383
 
1385
1384
  const results = await fetchSanity(query, false)
1386
- return results['related_by_license'] ?? [];
1385
+ return results['related_by_license'] ?? []
1387
1386
  }
1388
1387
 
1389
1388
  /**
@@ -2350,4 +2349,3 @@ export async function fetchScheduledAndNewReleases(
2350
2349
 
2351
2350
  return fetchSanity(query, true)
2352
2351
  }
2353
-
@@ -0,0 +1,35 @@
1
+ /**
2
+ * @module User-Management
3
+ */
4
+ import { fetchHandler } from '../railcontent.js'
5
+
6
+
7
+
8
+ /**
9
+ * Exported functions that are excluded from index generation.
10
+ *
11
+ * @type {string[]}
12
+ */
13
+ const excludeFromGeneratedIndex = []
14
+
15
+ const baseUrl = `/api/user-management-system`
16
+
17
+ /**
18
+ * Block the provided user
19
+ * @param userId
20
+ * @returns {Promise<any|string|null>}
21
+ */
22
+ export async function blockUser(userId) {
23
+ const url = `${baseUrl}/v1/block/${userId}`
24
+ return fetchHandler(url, 'post')
25
+ }
26
+
27
+ /**
28
+ * Unblock the provided user. Returns a 422 if the user wasn't blocked
29
+ * @param userId
30
+ * @returns {Promise<any|string|null>}
31
+ */
32
+ export async function unblockUser(userId) {
33
+ const url = `${baseUrl}/v1/unblock/${userId}`
34
+ return fetchHandler(url, 'post')
35
+ }
File without changes
File without changes
File without changes
package/test/log.js CHANGED
File without changes