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.
- package/.github/workflows/node.js.yml +0 -0
- package/.prettierignore +0 -0
- package/.prettierrc +0 -0
- package/CHANGELOG.md +9 -0
- package/README.md +0 -0
- package/babel.config.cjs +0 -0
- package/docs/Content-Organization.html +2 -2
- package/docs/Gamification.html +245 -0
- package/docs/api_types.js.html +97 -0
- package/docs/config.js.html +2 -2
- package/docs/content-org_playlists-types.js.html +3 -5
- package/docs/content-org_playlists.js.html +8 -9
- package/docs/content.js.html +2 -2
- package/docs/fonts/Montserrat/Montserrat-Bold.eot +0 -0
- package/docs/fonts/Montserrat/Montserrat-Bold.ttf +0 -0
- package/docs/fonts/Montserrat/Montserrat-Bold.woff +0 -0
- package/docs/fonts/Montserrat/Montserrat-Bold.woff2 +0 -0
- package/docs/fonts/Montserrat/Montserrat-Regular.eot +0 -0
- package/docs/fonts/Montserrat/Montserrat-Regular.ttf +0 -0
- package/docs/fonts/Montserrat/Montserrat-Regular.woff +0 -0
- package/docs/fonts/Montserrat/Montserrat-Regular.woff2 +0 -0
- package/docs/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.eot +0 -0
- package/docs/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.svg +0 -0
- package/docs/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.ttf +0 -0
- package/docs/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.woff +0 -0
- package/docs/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.woff2 +0 -0
- package/docs/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.eot +0 -0
- package/docs/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.svg +0 -0
- package/docs/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.ttf +0 -0
- package/docs/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.woff +0 -0
- package/docs/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.woff2 +0 -0
- package/docs/gamification_awards.js.html +664 -0
- package/docs/gamification_gamification.js.html +76 -0
- package/docs/gamification_types.js.html +98 -0
- package/docs/global.html +1441 -153
- package/docs/index.html +2 -2
- package/docs/module-Awards.html +354 -0
- package/docs/module-Config.html +2 -2
- package/docs/module-Content-Services-V2.html +2 -2
- package/docs/module-Playlists.html +6 -6
- package/docs/module-Railcontent-Services.html +33 -194
- package/docs/module-Sanity-Services.html +885 -90
- package/docs/module-Session-Management.html +2 -2
- package/docs/module-User-Permissions.html +2 -2
- package/docs/railcontent.js.html +13 -25
- package/docs/sanity.js.html +76 -5
- package/docs/scripts/collapse.js +0 -0
- package/docs/scripts/commonNav.js +0 -0
- package/docs/scripts/linenumber.js +0 -0
- package/docs/scripts/nav.js +0 -0
- package/docs/scripts/polyfill.js +0 -0
- package/docs/scripts/prettify/Apache-License-2.0.txt +0 -0
- package/docs/scripts/prettify/lang-css.js +0 -0
- package/docs/scripts/prettify/prettify.js +0 -0
- package/docs/scripts/search.js +0 -0
- package/docs/styles/jsdoc.css +0 -0
- package/docs/styles/prettify.css +0 -0
- package/docs/user_permissions.js.html +3 -3
- package/docs/user_sessions.js.html +4 -4
- package/docs/user_types.js.html +2 -2
- package/jest.config.js +0 -0
- package/jsdoc.json +4 -2
- package/package.json +1 -1
- package/src/index.d.ts +5 -1
- package/src/index.js +5 -0
- package/src/lib/httpHelper.js +46 -0
- package/src/services/api/types.js +25 -0
- package/src/services/contentLikes.js +0 -0
- package/src/services/gamification/awards.js +592 -0
- package/src/services/gamification/gamification.js +4 -0
- package/src/services/gamification/types.js +26 -0
- package/src/services/railcontent.js +9 -59
- package/src/services/recommendations.js +8 -39
- package/src/services/sanity.js +12 -14
- package/src/services/user/management.js +35 -0
- package/test/live/contentProgressLive.test.js +0 -0
- package/test/live/railcontentLive.test.js +0 -0
- package/test/localStorageMock.js +0 -0
- package/test/log.js +0 -0
|
@@ -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
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
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
|
-
|
|
134
|
-
|
|
135
|
-
|
|
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
|
-
|
|
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
|
}
|
package/src/services/sanity.js
CHANGED
|
@@ -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
|
|
1368
|
-
let filterSongTypesWithSameLicense = await new FilterBuilder(
|
|
1369
|
-
|
|
1370
|
-
|
|
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
|
package/test/localStorageMock.js
CHANGED
|
File without changes
|
package/test/log.js
CHANGED
|
File without changes
|