musora-content-services 2.85.1 → 2.86.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.
- package/.coderabbit.yaml +0 -0
- package/.editorconfig +0 -0
- package/.github/pull_request_template.md +0 -0
- package/.github/workflows/conventional-commits.yaml +0 -0
- package/.github/workflows/docs.js.yml +0 -0
- package/.github/workflows/node.js.yml +0 -0
- package/.prettierignore +0 -0
- package/.prettierrc +0 -0
- package/CHANGELOG.md +19 -0
- package/README.md +0 -0
- package/babel.config.cjs +0 -0
- package/docs/Content.html +0 -0
- package/docs/ContentOrganization.html +2 -2
- package/docs/Forums.html +2 -2
- package/docs/Gamification.html +2 -2
- package/docs/TestUser.html +2 -2
- package/docs/UserManagementSystem.html +2 -2
- package/docs/api_types.js.html +2 -2
- package/docs/config.js.html +5 -2
- package/docs/content-org_content-org.js.html +2 -2
- package/docs/content-org_guided-courses.ts.html +2 -2
- package/docs/content-org_learning-paths.ts.html +126 -24
- package/docs/content-org_playlists-types.js.html +2 -2
- package/docs/content-org_playlists.js.html +2 -2
- package/docs/content.js.html +88 -10
- package/docs/content_artist.ts.html +36 -41
- package/docs/content_content.ts.html +0 -0
- package/docs/content_genre.ts.html +29 -34
- package/docs/content_instructor.ts.html +25 -27
- 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/forums_categories.ts.html +22 -3
- package/docs/forums_discussions.js.html +0 -0
- package/docs/forums_forum.js.html +0 -0
- package/docs/forums_forums.ts.html +2 -2
- package/docs/forums_posts.ts.html +2 -2
- package/docs/forums_threads.ts.html +9 -9
- package/docs/gamification_awards.js.html +0 -0
- package/docs/gamification_awards.ts.html +26 -12
- package/docs/gamification_gamification.js.html +2 -2
- package/docs/gamification_types.js.html +0 -0
- package/docs/global.html +2 -2
- package/docs/index.html +2 -2
- package/docs/liveTesting.ts.html +2 -2
- package/docs/module-Accounts.html +14 -14
- package/docs/module-Artist.html +12 -10
- package/docs/module-Awards.html +106 -6
- package/docs/module-Categories.html +0 -0
- package/docs/module-Config.html +5 -4
- package/docs/module-Content-Services-V2.html +440 -9
- package/docs/module-ForumCategories.html +0 -0
- package/docs/module-ForumDiscussions.html +0 -0
- package/docs/module-Forums.html +627 -63
- package/docs/module-Genre.html +6 -6
- package/docs/module-GuidedCourses.html +2 -2
- package/docs/module-Instructor.html +10 -10
- package/docs/module-Interests.html +2 -2
- package/docs/module-LearningPaths.html +640 -12
- package/docs/module-Onboarding.html +32 -8
- package/docs/module-Payments.html +2 -2
- package/docs/module-Permissions.html +2 -2
- package/docs/module-Playlists.html +2 -2
- package/docs/module-ProgressRow.html +2 -2
- package/docs/module-Railcontent-Services.html +2 -2
- package/docs/module-Sanity-Services.html +786 -1853
- package/docs/module-Sessions.html +2 -2
- package/docs/module-Threads.html +0 -0
- package/docs/module-UserActivity.html +4 -4
- package/docs/module-UserChat.html +2 -2
- package/docs/module-UserManagement.html +2 -2
- package/docs/module-UserMemberships.html +2 -2
- package/docs/module-UserNotifications.html +2 -2
- package/docs/module-UserProfile.html +2 -2
- package/docs/progress-row_method-card.js.html +3 -3
- package/docs/railcontent.js.html +2 -2
- package/docs/sanity.js.html +230 -321
- 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/userActivity.js.html +4 -3
- package/docs/user_account.ts.html +14 -13
- package/docs/user_chat.js.html +2 -2
- package/docs/user_interests.js.html +2 -2
- package/docs/user_management.js.html +2 -2
- package/docs/user_memberships.js.html +0 -0
- package/docs/user_memberships.ts.html +2 -2
- package/docs/user_notifications.js.html +2 -2
- package/docs/user_onboarding.ts.html +95 -4
- package/docs/user_payments.ts.html +2 -2
- package/docs/user_permissions.js.html +3 -3
- package/docs/user_profile.js.html +2 -2
- package/docs/user_sessions.js.html +2 -2
- package/docs/user_types.js.html +2 -2
- package/docs/user_user-management-system.js.html +2 -2
- package/jest.config.js +0 -0
- package/jsdoc.json +0 -0
- package/package.json +1 -1
- package/src/contentMetaData.js +0 -0
- package/src/contentTypeConfig.js +24 -16
- package/src/filterBuilder.js +0 -0
- package/src/index.d.ts +0 -0
- package/src/index.js +0 -0
- package/src/infrastructure/http/HttpClient.ts +0 -0
- package/src/infrastructure/http/executors/FetchRequestExecutor.ts +0 -0
- package/src/infrastructure/http/index.ts +0 -0
- package/src/infrastructure/http/interfaces/HeaderProvider.ts +0 -0
- package/src/infrastructure/http/interfaces/HttpError.ts +0 -0
- package/src/infrastructure/http/interfaces/NetworkError.ts +0 -0
- package/src/infrastructure/http/interfaces/RequestExecutor.ts +0 -0
- package/src/infrastructure/http/interfaces/RequestOptions.ts +0 -0
- package/src/infrastructure/http/providers/DefaultHeaderProvider.ts +0 -0
- package/src/lib/brands.ts +8 -0
- package/src/lib/httpHelper.js +0 -0
- package/src/lib/lastUpdated.js +0 -0
- package/src/lib/sanity/query.ts +30 -0
- package/src/services/api/types.js +0 -0
- package/src/services/api/types.ts +0 -0
- package/src/services/config.js +0 -0
- package/src/services/content/artist.ts +34 -39
- package/src/services/content/content.ts +7 -1
- package/src/services/content/genre.ts +27 -32
- package/src/services/content/instructor.ts +23 -25
- package/src/services/content-org/content-org.js +0 -0
- package/src/services/content-org/guided-courses.ts +0 -0
- package/src/services/content-org/learning-paths.ts +4 -4
- package/src/services/content-org/playlists-types.js +0 -0
- package/src/services/content-org/playlists.js +0 -0
- package/src/services/content.js +0 -0
- package/src/services/contentAggregator.js +5 -1
- package/src/services/contentLikes.js +0 -0
- package/src/services/contentProgress.js +6 -6
- package/src/services/dataContext.js +0 -0
- package/src/services/dateUtils.js +0 -0
- package/src/services/eventsAPI.js +0 -0
- package/src/services/forums/categories.ts +0 -0
- package/src/services/forums/forums.ts +0 -0
- package/src/services/forums/posts.ts +0 -0
- package/src/services/forums/threads.ts +0 -0
- package/src/services/forums/types.ts +0 -0
- package/src/services/gamification/awards.ts +0 -0
- package/src/services/gamification/gamification.js +0 -0
- package/src/services/imageSRCBuilder.js +0 -0
- package/src/services/imageSRCVerify.js +0 -0
- package/src/services/liveTesting.ts +0 -0
- package/src/services/permissions/PermissionsAdapter.ts +0 -0
- package/src/services/permissions/PermissionsAdapterFactory.ts +0 -0
- package/src/services/permissions/PermissionsV1Adapter.ts +0 -0
- package/src/services/permissions/PermissionsV2Adapter.ts +0 -0
- package/src/services/permissions/README.md +0 -0
- package/src/services/permissions/index.ts +0 -0
- package/src/services/progress-row/method-card.js +0 -0
- package/src/services/railcontent.js +0 -0
- package/src/services/recommendations.js +0 -0
- package/src/services/sanity.js +52 -45
- package/src/services/types.js +0 -0
- package/src/services/user/account.ts +0 -0
- package/src/services/user/chat.js +0 -0
- package/src/services/user/interests.js +0 -0
- package/src/services/user/management.js +0 -0
- package/src/services/user/memberships.ts +0 -0
- package/src/services/user/notifications.js +0 -0
- package/src/services/user/onboarding.ts +93 -2
- package/src/services/user/payments.ts +0 -0
- package/src/services/user/permissions.js +0 -0
- package/src/services/user/profile.js +0 -0
- package/src/services/user/sessions.js +0 -0
- package/src/services/user/types.d.ts +0 -0
- package/src/services/user/types.js +0 -0
- package/src/services/user/user-management-system.js +0 -0
- package/src/services/userActivity.js +1 -1
- package/test/HttpClient.test.js +0 -0
- package/test/content.test.js +0 -0
- package/test/contentLikes.test.js +0 -0
- package/test/contentProgress.test.js +0 -0
- package/test/dataContext.test.js +0 -0
- package/test/forum.test.js +0 -0
- package/test/imageSRCBuilder.test.js +0 -0
- package/test/imageSRCVerify.test.js +0 -0
- package/test/initializeTests.js +0 -0
- package/test/learningPaths.test.js +0 -0
- package/test/lib/lastUpdated.test.js +0 -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
- package/test/mockData/mockData_fetchByRailContentIds_one_content.json +0 -0
- package/test/mockData/mockData_progress_content.json +0 -0
- package/test/mockData/mockData_sanity_progress_content.json +0 -0
- package/test/mockData/mockData_user_practices.json +0 -0
- package/test/notifications.test.js +0 -0
- package/test/progressRows.test.js +0 -0
- package/test/sanityQueryService.test.js +0 -0
- package/test/streakMessage.test.js +0 -0
- package/test/user/permissions.test.js +0 -0
- package/test/userActivity.test.js +0 -0
- package/tools/generate-index.cjs +0 -0
- package/.claude/settings.local.json +0 -14
- package/.yarnrc.yml +0 -1
|
@@ -101,22 +101,22 @@ export async function resetAllLearningPaths() {
|
|
|
101
101
|
* @returns {Promise<Object>} Learning path with enriched lesson data
|
|
102
102
|
*/
|
|
103
103
|
export async function getEnrichedLearningPath(learningPathId) {
|
|
104
|
-
// TODO: replace addNextLesson with addNaviageTo
|
|
105
104
|
const response = (await addContextToContent(
|
|
106
105
|
fetchByRailContentId,
|
|
107
106
|
learningPathId,
|
|
108
107
|
'learning-path-v2',
|
|
109
108
|
{
|
|
109
|
+
collection: { id: learningPathId, type: 'learning-path-v2' },
|
|
110
110
|
dataField: 'children',
|
|
111
111
|
dataField_includeParent: true,
|
|
112
112
|
addProgressStatus: true,
|
|
113
113
|
addProgressPercentage: true,
|
|
114
114
|
addProgressTimestamp: true,
|
|
115
|
-
|
|
115
|
+
addNavigateTo: true,
|
|
116
116
|
}
|
|
117
117
|
)) as any
|
|
118
118
|
if (!response) return response
|
|
119
|
-
|
|
119
|
+
|
|
120
120
|
response.children = mapContentToParent(
|
|
121
121
|
response.children,
|
|
122
122
|
'learning-path-lesson-v2',
|
|
@@ -222,7 +222,7 @@ export async function fetchLearningPathLessons(
|
|
|
222
222
|
nextLPLessons = await getLearningPathLessonsByIds(nextContentIds, nextLearningPathId)
|
|
223
223
|
}
|
|
224
224
|
|
|
225
|
-
|
|
225
|
+
|
|
226
226
|
|
|
227
227
|
return {
|
|
228
228
|
...learningPath,
|
|
File without changes
|
|
File without changes
|
package/src/services/content.js
CHANGED
|
File without changes
|
|
@@ -173,7 +173,11 @@ function extractItemsFromData(data, dataField, isParentArray, includeParent) {
|
|
|
173
173
|
if (includeParent) {
|
|
174
174
|
if (isParentArray) {
|
|
175
175
|
for (const parent of data) {
|
|
176
|
-
|
|
176
|
+
if(Array.isArray(parent)){
|
|
177
|
+
items = [...items, ...parent]
|
|
178
|
+
} else {
|
|
179
|
+
items = [...items, parent]
|
|
180
|
+
}
|
|
177
181
|
}
|
|
178
182
|
} else {
|
|
179
183
|
items = [...items, data]
|
|
File without changes
|
|
@@ -410,7 +410,7 @@ function setStartedOrCompletedStatusInLocalContext(
|
|
|
410
410
|
|
|
411
411
|
if (!hierarchy) return
|
|
412
412
|
|
|
413
|
-
if (collection && collection.type === 'learning-path') {
|
|
413
|
+
if (collection && collection.type === 'learning-path-v2') {
|
|
414
414
|
bubbleOrTrickleLearningPathProgress(hierarchy, contentId, localContext, isCompleted, collection)
|
|
415
415
|
return
|
|
416
416
|
}
|
|
@@ -453,7 +453,7 @@ function resetStatusInLocalContext(localContext, contentId, hierarchy, collectio
|
|
|
453
453
|
let allChildIds
|
|
454
454
|
let learningPathId = null
|
|
455
455
|
let childrenIds = []
|
|
456
|
-
if (collection && collection.type === 'learning-path') {
|
|
456
|
+
if (collection && collection.type === 'learning-path-v2') {
|
|
457
457
|
[learningPathId, childrenIds] = findLearningPathAndChildren(hierarchy, contentId)
|
|
458
458
|
allChildIds = (learningPathId === contentId) ? childrenIds : []
|
|
459
459
|
} else {
|
|
@@ -471,7 +471,7 @@ function resetStatusInLocalContext(localContext, contentId, hierarchy, collectio
|
|
|
471
471
|
delete localContext.data[key]
|
|
472
472
|
}
|
|
473
473
|
})
|
|
474
|
-
if (collection && collection.type === 'learning-path') { // manual bubbling for LP
|
|
474
|
+
if (collection && collection.type === 'learning-path-v2') { // manual bubbling for LP
|
|
475
475
|
if (learningPathId !== contentId) {
|
|
476
476
|
bubbleLearningPathProgress(hierarchy, contentId, localContext, collection)
|
|
477
477
|
}
|
|
@@ -492,7 +492,7 @@ function resetStatusInLocalContext(localContext, contentId, hierarchy, collectio
|
|
|
492
492
|
* @param {string} sessionId - This function records a sessionId to pass into future updates to progress on the same video
|
|
493
493
|
* @param {int} instrumentId - enum value of instrument id
|
|
494
494
|
* @param {int} categoryId - enum value of category id
|
|
495
|
-
* @param {object|null} collection - optional collection info { type: 'learning-path', id: 123 }
|
|
495
|
+
* @param {object|null} collection - optional collection info { type: 'learning-path-v2', id: 123 }
|
|
496
496
|
*/
|
|
497
497
|
// NOTE: have not set up collection because its not super important for testing and this will change soon with watermelon
|
|
498
498
|
export async function recordWatchSession(
|
|
@@ -507,7 +507,7 @@ export async function recordWatchSession(
|
|
|
507
507
|
categoryId = null,
|
|
508
508
|
collection = null
|
|
509
509
|
) {
|
|
510
|
-
if (collection && collection.type === 'learning-path') {
|
|
510
|
+
if (collection && collection.type === 'learning-path-v2') {
|
|
511
511
|
console.log('Learning Path lesson watch sessions are not set up yet without watermelon')
|
|
512
512
|
return sessionId
|
|
513
513
|
}
|
|
@@ -640,7 +640,7 @@ function extractContentIdFromRecordKey(key) {
|
|
|
640
640
|
}
|
|
641
641
|
|
|
642
642
|
async function getContentHierarchy(contentId, collection = null) {
|
|
643
|
-
if (collection && collection.type === 'learning-path') {
|
|
643
|
+
if (collection && collection.type === 'learning-path-v2') {
|
|
644
644
|
return fetchMethodV2StructureFromId(contentId)
|
|
645
645
|
}
|
|
646
646
|
return await fetchHierarchy(contentId)
|
|
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/src/services/sanity.js
CHANGED
|
@@ -490,7 +490,10 @@ export async function fetchByRailContentIds(
|
|
|
490
490
|
}
|
|
491
491
|
return results.map(liveProcess)
|
|
492
492
|
}
|
|
493
|
-
const results = await fetchSanity(query, true, {
|
|
493
|
+
const results = await fetchSanity(query, true, {
|
|
494
|
+
customPostProcess: customPostProcess,
|
|
495
|
+
processNeedAccess: true,
|
|
496
|
+
})
|
|
494
497
|
|
|
495
498
|
const sortFuction = function compare(a, b) {
|
|
496
499
|
const indexA = ids.indexOf(a['id'])
|
|
@@ -510,8 +513,14 @@ export async function fetchContentRows(brand, pageName, contentRowSlug) {
|
|
|
510
513
|
if (pageName === 'lessons') pageName = 'lesson'
|
|
511
514
|
if (pageName === 'songs') pageName = 'song'
|
|
512
515
|
const rowString = contentRowSlug ? ` && slug.current == "${contentRowSlug.toLowerCase()}"` : ''
|
|
513
|
-
const lessonCountFilter = await new FilterBuilder(`_id in ^.child[]._ref`, {
|
|
514
|
-
|
|
516
|
+
const lessonCountFilter = await new FilterBuilder(`_id in ^.child[]._ref`, {
|
|
517
|
+
pullFutureContent: true,
|
|
518
|
+
showMembershipRestrictedContent: true,
|
|
519
|
+
}).buildFilter()
|
|
520
|
+
const childFilter = await new FilterBuilder('', {
|
|
521
|
+
isChildrenFilter: true,
|
|
522
|
+
showMembershipRestrictedContent: true,
|
|
523
|
+
}).buildFilter()
|
|
515
524
|
const query = `*[_type == 'recommended-content-row' && brand == '${brand}' && type == '${pageName}'${rowString}]{
|
|
516
525
|
brand,
|
|
517
526
|
name,
|
|
@@ -524,7 +533,7 @@ export async function fetchContentRows(brand, pageName, contentRowSlug) {
|
|
|
524
533
|
'lesson_count': coalesce(count(*[${lessonCountFilter}]), 0),
|
|
525
534
|
},
|
|
526
535
|
}`
|
|
527
|
-
return fetchSanity(query, true, {processNeedAccess: true})
|
|
536
|
+
return fetchSanity(query, true, { processNeedAccess: true })
|
|
528
537
|
}
|
|
529
538
|
|
|
530
539
|
/**
|
|
@@ -1084,7 +1093,11 @@ export async function jumpToContinueContent(railcontentId) {
|
|
|
1084
1093
|
* .catch(error => console.error(error));
|
|
1085
1094
|
*/
|
|
1086
1095
|
export async function fetchLessonContent(railContentId, { addParent = false } = {}) {
|
|
1087
|
-
const filterParams = {
|
|
1096
|
+
const filterParams = {
|
|
1097
|
+
isSingle: true,
|
|
1098
|
+
pullFutureContent: true,
|
|
1099
|
+
showMembershipRestrictedContent: true,
|
|
1100
|
+
}
|
|
1088
1101
|
|
|
1089
1102
|
const parentQuery = addParent
|
|
1090
1103
|
? `"parent_content_data": *[railcontent_id in [...(^.parent_content_data[].id)]]{
|
|
@@ -1236,20 +1249,20 @@ async function fetchRelatedByLicense(railcontentId, brand, onlyUseSongTypes, cou
|
|
|
1236
1249
|
export async function fetchSiblingContent(railContentId, brand = null) {
|
|
1237
1250
|
const filterGetParent = await new FilterBuilder(`references(^._id) && _type == ^.parent_type`, {
|
|
1238
1251
|
pullFutureContent: true,
|
|
1239
|
-
showMembershipRestrictedContent: true
|
|
1252
|
+
showMembershipRestrictedContent: true, // Show parent even without permissions
|
|
1240
1253
|
}).buildFilter()
|
|
1241
1254
|
const filterForParentList = await new FilterBuilder(
|
|
1242
1255
|
`references(^._id) && _type == ^.parent_type`,
|
|
1243
1256
|
{
|
|
1244
1257
|
pullFutureContent: true,
|
|
1245
1258
|
isParentFilter: true,
|
|
1246
|
-
showMembershipRestrictedContent: true
|
|
1259
|
+
showMembershipRestrictedContent: true, // Show parent even without permissions
|
|
1247
1260
|
}
|
|
1248
1261
|
).buildFilter()
|
|
1249
1262
|
|
|
1250
1263
|
const childrenFilter = await new FilterBuilder(``, {
|
|
1251
1264
|
isChildrenFilter: true,
|
|
1252
|
-
showMembershipRestrictedContent: true
|
|
1265
|
+
showMembershipRestrictedContent: true, // Show all lessons in sidebar, need_access applied on individual page
|
|
1253
1266
|
}).buildFilter()
|
|
1254
1267
|
|
|
1255
1268
|
const brandString = brand ? ` && brand == "${brand}"` : ''
|
|
@@ -1480,35 +1493,34 @@ export async function fetchByReference(
|
|
|
1480
1493
|
return fetchSanity(query, true)
|
|
1481
1494
|
}
|
|
1482
1495
|
|
|
1496
|
+
/**
|
|
1497
|
+
*
|
|
1498
|
+
* Return the top level parent content railcontent_id.
|
|
1499
|
+
* Ignores learning-path-v2 parents.
|
|
1500
|
+
* ex: if railcontentId is of type 'skill-pack-lesson', return the corresponding 'skill-pack' railcontent_id
|
|
1501
|
+
*
|
|
1502
|
+
* @param {int} railcontentId
|
|
1503
|
+
* @returns {Promise<int|null>}
|
|
1504
|
+
*/
|
|
1483
1505
|
export async function fetchTopLevelParentId(railcontentId) {
|
|
1506
|
+
const parentFilter = "railcontent_id in [...(^.parent_content_data[].id)]"
|
|
1484
1507
|
const statusFilter = "&& status in ['scheduled', 'published', 'archived', 'unlisted']"
|
|
1485
1508
|
|
|
1486
1509
|
const query = `*[railcontent_id == ${railcontentId}]{
|
|
1487
1510
|
railcontent_id,
|
|
1488
|
-
'parents': *[
|
|
1489
|
-
railcontent_id
|
|
1490
|
-
'parents': *[^._id in child[]._ref ${statusFilter}]{
|
|
1491
|
-
railcontent_id,
|
|
1492
|
-
'parents': *[^._id in child[]._ref ${statusFilter}]{
|
|
1493
|
-
railcontent_id,
|
|
1494
|
-
'parents': *[^._id in child[]._ref ${statusFilter}]{
|
|
1495
|
-
railcontent_id,
|
|
1496
|
-
}
|
|
1497
|
-
}
|
|
1498
|
-
}
|
|
1511
|
+
'parents': *[${parentFilter} ${statusFilter}]{
|
|
1512
|
+
railcontent_id
|
|
1499
1513
|
}
|
|
1500
1514
|
}`
|
|
1501
1515
|
let response = await fetchSanity(query, false, { processNeedAccess: false })
|
|
1502
1516
|
if (!response) return null
|
|
1503
|
-
let
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
return currentLevel['railcontent_id']
|
|
1509
|
-
}
|
|
1517
|
+
let parents = response['parents']
|
|
1518
|
+
let parentsLength = parents ? response['parents'].length : 0
|
|
1519
|
+
if (parentsLength > 0) {
|
|
1520
|
+
// return the last parent
|
|
1521
|
+
return parents[parentsLength - 1]['railcontent_id']
|
|
1510
1522
|
}
|
|
1511
|
-
return
|
|
1523
|
+
return response['railcontent_id']
|
|
1512
1524
|
}
|
|
1513
1525
|
|
|
1514
1526
|
export async function fetchHierarchy(railcontentId) {
|
|
@@ -1656,12 +1668,8 @@ export async function fetchSanity(
|
|
|
1656
1668
|
if (!results) {
|
|
1657
1669
|
throw new Error('No results found')
|
|
1658
1670
|
}
|
|
1659
|
-
results = processNeedAccess
|
|
1660
|
-
|
|
1661
|
-
: results
|
|
1662
|
-
results = processPageType
|
|
1663
|
-
? pageTypeDecorator(results)
|
|
1664
|
-
: results
|
|
1671
|
+
results = processNeedAccess ? await needsAccessDecorator(results, userPermissions) : results
|
|
1672
|
+
results = processPageType ? pageTypeDecorator(results) : results
|
|
1665
1673
|
return customPostProcess ? customPostProcess(results) : results
|
|
1666
1674
|
} else {
|
|
1667
1675
|
throw new Error('No results found')
|
|
@@ -1715,7 +1723,6 @@ function pageTypeDecorator(results) {
|
|
|
1715
1723
|
})
|
|
1716
1724
|
}
|
|
1717
1725
|
|
|
1718
|
-
|
|
1719
1726
|
function needsAccessDecorator(results, userPermissions) {
|
|
1720
1727
|
if (globalConfig.sanityConfig.useDummyRailContentMethods) return results
|
|
1721
1728
|
const adapter = getPermissionsAdapter()
|
|
@@ -2037,7 +2044,10 @@ export async function fetchTabData(
|
|
|
2037
2044
|
let filter = ''
|
|
2038
2045
|
|
|
2039
2046
|
filter = `brand == "${brand}" && (defined(railcontent_id)) ${includedFieldsFilter} ${progressFilter}`
|
|
2040
|
-
const childrenFilter = await new FilterBuilder(``, {
|
|
2047
|
+
const childrenFilter = await new FilterBuilder(``, {
|
|
2048
|
+
isChildrenFilter: true,
|
|
2049
|
+
showMembershipRestrictedContent: true,
|
|
2050
|
+
}).buildFilter()
|
|
2041
2051
|
const childrenFields = await getChildFieldsForContentType('tab-data')
|
|
2042
2052
|
const lessonCountFilter = await new FilterBuilder(`_id in ^.child[]._ref`).buildFilter()
|
|
2043
2053
|
entityFieldsString = ` ${fieldsString}
|
|
@@ -2052,14 +2062,16 @@ export async function fetchTabData(
|
|
|
2052
2062
|
),
|
|
2053
2063
|
length_in_seconds
|
|
2054
2064
|
),`
|
|
2055
|
-
const filterWithRestrictions = await new FilterBuilder(filter, {
|
|
2065
|
+
const filterWithRestrictions = await new FilterBuilder(filter, {
|
|
2066
|
+
showMembershipRestrictedContent: true,
|
|
2067
|
+
}).buildFilter()
|
|
2056
2068
|
query = buildEntityAndTotalQuery(filterWithRestrictions, entityFieldsString, {
|
|
2057
2069
|
sortOrder: sortOrder,
|
|
2058
2070
|
start: start,
|
|
2059
2071
|
end: end,
|
|
2060
2072
|
})
|
|
2061
2073
|
|
|
2062
|
-
let results = await fetchSanity(query, true, {processNeedAccess: true})
|
|
2074
|
+
let results = await fetchSanity(query, true, { processNeedAccess: true })
|
|
2063
2075
|
|
|
2064
2076
|
if (['recent', 'incomplete', 'completed'].includes(progress) && results.entity.length > 1) {
|
|
2065
2077
|
const orderMap = new Map(progressIds.map((id, index) => [id, index]))
|
|
@@ -2203,12 +2215,7 @@ export async function fetchMethodV2StructureFromId(contentId) {
|
|
|
2203
2215
|
*/
|
|
2204
2216
|
export async function fetchOwnedContent(
|
|
2205
2217
|
brand,
|
|
2206
|
-
{
|
|
2207
|
-
type = [],
|
|
2208
|
-
page = 1,
|
|
2209
|
-
limit = 10,
|
|
2210
|
-
sort = '-published_on',
|
|
2211
|
-
} = {}
|
|
2218
|
+
{ type = [], page = 1, limit = 10, sort = '-published_on' } = {}
|
|
2212
2219
|
) {
|
|
2213
2220
|
const start = (page - 1) * limit
|
|
2214
2221
|
const end = start + limit
|
|
@@ -2219,7 +2226,7 @@ export async function fetchOwnedContent(
|
|
|
2219
2226
|
// Build the type filter
|
|
2220
2227
|
let typeFilter = ''
|
|
2221
2228
|
if (type.length > 0) {
|
|
2222
|
-
const typesString = type.map(t => `'${t}'`).join(', ')
|
|
2229
|
+
const typesString = type.map((t) => `'${t}'`).join(', ')
|
|
2223
2230
|
typeFilter = `&& _type in [${typesString}]`
|
|
2224
2231
|
}
|
|
2225
2232
|
|
|
@@ -2228,7 +2235,7 @@ export async function fetchOwnedContent(
|
|
|
2228
2235
|
|
|
2229
2236
|
// Apply owned content filter
|
|
2230
2237
|
const filterWithRestrictions = await new FilterBuilder(filter, {
|
|
2231
|
-
showOnlyOwnedContent: true,
|
|
2238
|
+
showOnlyOwnedContent: true, // Key parameter: exclude membership content
|
|
2232
2239
|
}).buildFilter()
|
|
2233
2240
|
|
|
2234
2241
|
const fieldsString = DEFAULT_FIELDS.join(',')
|
package/src/services/types.js
CHANGED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
* @module Onboarding
|
|
3
3
|
*/
|
|
4
4
|
import { HttpClient } from '../../infrastructure/http/HttpClient'
|
|
5
|
+
import { Brand } from '../../lib/brands'
|
|
5
6
|
import { globalConfig } from '../config.js'
|
|
6
7
|
|
|
7
8
|
export interface OnboardingSteps {
|
|
@@ -131,17 +132,107 @@ export interface OnboardingRecommendedContent {
|
|
|
131
132
|
}
|
|
132
133
|
}
|
|
133
134
|
|
|
135
|
+
const recommendedContentCache: { [brand: string]: OnboardingRecommendedContent } = {
|
|
136
|
+
drumeo: {
|
|
137
|
+
id: 391995,
|
|
138
|
+
title: 'Getting Started On The Drums',
|
|
139
|
+
difficulty: 'Beginner',
|
|
140
|
+
lesson_count: 12,
|
|
141
|
+
skill_count: 1,
|
|
142
|
+
badge: 'https://cdn.sanity.io/files/4032r8py/staging/drumeo_badge.png',
|
|
143
|
+
description:
|
|
144
|
+
'Start your drumming journey with essential techniques and rhythms to get you playing quickly.',
|
|
145
|
+
video: {
|
|
146
|
+
external_id: '1002267396',
|
|
147
|
+
hlsManifestUrl:
|
|
148
|
+
'https://player.vimeo.com/external/1002267396.m3u8?s=abcdef1234567890abcdef1234567890abcdef12&oauth2_token_id=1284792284',
|
|
149
|
+
type: 'vimeo-video',
|
|
150
|
+
},
|
|
151
|
+
},
|
|
152
|
+
pianote: {
|
|
153
|
+
id: 412405,
|
|
154
|
+
title: 'Getting Started On The Piano',
|
|
155
|
+
difficulty: 'Beginner',
|
|
156
|
+
lesson_count: 4,
|
|
157
|
+
skill_count: 3,
|
|
158
|
+
badge:
|
|
159
|
+
'https://cdn.sanity.io/files/4032r8py/staging/9470587f03479b7c1f8019c3cbcbdfe12aa267f3.png',
|
|
160
|
+
description:
|
|
161
|
+
'The goal of this course is to introduce you to the keys, and get you playing a song as fast as possible. ',
|
|
162
|
+
video: {
|
|
163
|
+
external_id: '1001267395',
|
|
164
|
+
hlsManifestUrl:
|
|
165
|
+
'https://player.vimeo.com/external/1001267395.m3u8?s=8f8d8a8a762f688058e6e6fd6704c402baf1b797&oauth2_token_id=1284792283',
|
|
166
|
+
type: 'vimeo-video',
|
|
167
|
+
},
|
|
168
|
+
},
|
|
169
|
+
guitareo: {
|
|
170
|
+
id: 294635,
|
|
171
|
+
title: 'Getting Started On The Acoustic Guitar',
|
|
172
|
+
difficulty: 'Beginner',
|
|
173
|
+
lesson_count: 6,
|
|
174
|
+
skill_count: 5,
|
|
175
|
+
badge: 'https://cdn.sanity.io/files/4032r8py/staging/guitareo_badge.png',
|
|
176
|
+
description:
|
|
177
|
+
'New to the acoustic guitar? Then this Course is for you! Learn everything you need to get started on the acoustic guitar, and start playing music as fast as possible!',
|
|
178
|
+
video: {
|
|
179
|
+
external_id: '1003267397',
|
|
180
|
+
hlsManifestUrl:
|
|
181
|
+
'https://player.vimeo.com/external/1003267397.m3u8?s=1234567890abcdef1234567890abcdef12345678&oauth2_token_id=1284792285',
|
|
182
|
+
type: 'vimeo-video',
|
|
183
|
+
},
|
|
184
|
+
},
|
|
185
|
+
singeo: {
|
|
186
|
+
id: 712408,
|
|
187
|
+
title: 'Singing Starter Kit',
|
|
188
|
+
difficulty: 'Beginner',
|
|
189
|
+
lesson_count: 5,
|
|
190
|
+
skill_count: 4,
|
|
191
|
+
badge: 'https://cdn.sanity.io/files/4032r8py/staging/singeo_badge.png',
|
|
192
|
+
description:
|
|
193
|
+
'Welcome to the Singing Starter Kit! This course will teach you everything you need to know to sound better when you sing! You will learn how your unique voice works so that you can develop vocal strength, accurate pitch, and find confidence singing your favorite songs. You can sing, and the Singing Starter Kit is the perfect way to start your singing journey.',
|
|
194
|
+
video: {
|
|
195
|
+
external_id: '1004267398',
|
|
196
|
+
hlsManifestUrl:
|
|
197
|
+
'https://player.vimeo.com/external/1004267398.m3u8?s=fedcba0987654321fedcba0987654321fedcba09&oauth2_token_id=1284792286',
|
|
198
|
+
type: 'vimeo-video',
|
|
199
|
+
},
|
|
200
|
+
},
|
|
201
|
+
playbass: {
|
|
202
|
+
id: 294635,
|
|
203
|
+
title: 'Getting Started On The Acoustic Guitar',
|
|
204
|
+
difficulty: 'Beginner',
|
|
205
|
+
lesson_count: 6,
|
|
206
|
+
skill_count: 5,
|
|
207
|
+
badge: 'https://cdn.sanity.io/files/4032r8py/staging/guitareo_badge.png',
|
|
208
|
+
description:
|
|
209
|
+
'New to the acoustic guitar? Then this Course is for you! Learn everything you need to get started on the acoustic guitar, and start playing music as fast as possible!',
|
|
210
|
+
video: {
|
|
211
|
+
external_id: '1003267397',
|
|
212
|
+
hlsManifestUrl:
|
|
213
|
+
'https://player.vimeo.com/external/1003267397.m3u8?s=1234567890abcdef1234567890abcdef12345678&oauth2_token_id=1284792285',
|
|
214
|
+
type: 'vimeo-video',
|
|
215
|
+
},
|
|
216
|
+
},
|
|
217
|
+
}
|
|
218
|
+
|
|
134
219
|
/**
|
|
135
220
|
* Fetches recommended content for onboarding based on the specified brand.
|
|
136
221
|
*
|
|
137
|
-
* @param {string}
|
|
222
|
+
* @param {string} email - The user's email address.
|
|
223
|
+
* @param {Brand} brand - The brand identifier.
|
|
138
224
|
* @returns {Promise<OnboardingRecommendedContent>} - A promise that resolves with the recommended content.
|
|
139
225
|
* @throws {HttpError} - If the HTTP request fails.
|
|
140
226
|
*/
|
|
141
227
|
export async function getOnboardingRecommendedContent(
|
|
142
|
-
|
|
228
|
+
email: string,
|
|
229
|
+
brand: Brand
|
|
143
230
|
): Promise<OnboardingRecommendedContent> {
|
|
144
231
|
// TODO: Replace with real API call when available
|
|
232
|
+
if (recommendedContentCache[brand]) {
|
|
233
|
+
return recommendedContentCache[brand]
|
|
234
|
+
}
|
|
235
|
+
|
|
145
236
|
return {
|
|
146
237
|
id: 412405,
|
|
147
238
|
title: 'Getting Started On The Piano',
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -1347,7 +1347,7 @@ function mergeAndSortItems(items, limit) {
|
|
|
1347
1347
|
|
|
1348
1348
|
export function findIncompleteLesson(progressOnItems, currentContentId, contentType) {
|
|
1349
1349
|
const ids = Object.keys(progressOnItems).map(Number)
|
|
1350
|
-
if (contentType === 'guided-course' || contentType === 'learning-path') {
|
|
1350
|
+
if (contentType === 'guided-course' || contentType === 'learning-path-v2') {
|
|
1351
1351
|
// Return first incomplete lesson
|
|
1352
1352
|
return ids.find((id) => progressOnItems[id] !== 'completed') || ids.at(0)
|
|
1353
1353
|
}
|
package/test/HttpClient.test.js
CHANGED
|
File without changes
|
package/test/content.test.js
CHANGED
|
File without changes
|
|
File without changes
|
|
File without changes
|
package/test/dataContext.test.js
CHANGED
|
File without changes
|
package/test/forum.test.js
CHANGED
|
File without changes
|
|
File without changes
|
|
File without changes
|
package/test/initializeTests.js
CHANGED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
package/test/localStorageMock.js
CHANGED
|
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
|
|
File without changes
|
|
File without changes
|
package/tools/generate-index.cjs
CHANGED
|
File without changes
|
package/.yarnrc.yml
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
nodeLinker: node-modules
|