musora-content-services 2.92.3 → 2.92.7
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/docs.js.yml +64 -47
- package/CHANGELOG.md +23 -0
- package/package.json +1 -1
- package/src/index.d.ts +2 -0
- package/src/index.js +2 -0
- package/src/lib/brands.ts +7 -7
- package/src/services/content/artist.ts +10 -7
- package/src/services/content/genre.ts +10 -7
- package/src/services/content/instructor.ts +7 -7
- package/src/services/content-org/learning-paths.ts +3 -3
- package/src/services/progress-row/method-card.js +1 -1
- package/src/services/reporting/reporting.ts +19 -15
- package/src/services/sync/fetch.ts +3 -0
- package/src/services/user/onboarding.ts +3 -3
- package/docs/Content.html +0 -269
- package/docs/ContentOrganization.html +0 -245
- package/docs/Forums.html +0 -269
- package/docs/Gamification.html +0 -245
- package/docs/TestUser.html +0 -260
- package/docs/UserManagementSystem.html +0 -317
- package/docs/api_types.js.html +0 -97
- package/docs/config.js.html +0 -140
- package/docs/content-org_content-org.js.html +0 -76
- package/docs/content-org_guided-courses.ts.html +0 -110
- package/docs/content-org_learning-paths.ts.html +0 -391
- package/docs/content-org_playlists-types.js.html +0 -128
- package/docs/content-org_playlists.js.html +0 -440
- package/docs/content.js.html +0 -603
- package/docs/content_artist.ts.html +0 -206
- package/docs/content_content.ts.html +0 -77
- package/docs/content_genre.ts.html +0 -209
- package/docs/content_instructor.ts.html +0 -206
- 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 -978
- 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 -1049
- 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 +0 -156
- package/docs/forums_discussions.js.html +0 -95
- package/docs/forums_forum.js.html +0 -95
- package/docs/forums_forums.ts.html +0 -160
- package/docs/forums_posts.ts.html +0 -284
- package/docs/forums_threads.ts.html +0 -284
- package/docs/gamification_awards.js.html +0 -165
- package/docs/gamification_awards.ts.html +0 -195
- package/docs/gamification_gamification.js.html +0 -76
- package/docs/gamification_types.js.html +0 -80
- package/docs/global.html +0 -6019
- package/docs/index.html +0 -167
- package/docs/liveTesting.ts.html +0 -103
- package/docs/module-Accounts.html +0 -2283
- package/docs/module-Artist.html +0 -993
- package/docs/module-Awards.html +0 -836
- package/docs/module-Categories.html +0 -711
- package/docs/module-Config.html +0 -431
- package/docs/module-Content-Services-V2.html +0 -2998
- package/docs/module-ForumCategories.html +0 -687
- package/docs/module-ForumDiscussions.html +0 -370
- package/docs/module-Forums.html +0 -16599
- package/docs/module-Genre.html +0 -981
- package/docs/module-GuidedCourses.html +0 -108
- package/docs/module-Instructor.html +0 -929
- package/docs/module-Interests.html +0 -1066
- package/docs/module-LearningPaths.html +0 -2424
- package/docs/module-Onboarding.html +0 -882
- package/docs/module-Payments.html +0 -392
- package/docs/module-Permissions.html +0 -406
- package/docs/module-Playlists.html +0 -3030
- package/docs/module-ProgressRow.html +0 -108
- package/docs/module-Railcontent-Services.html +0 -5876
- package/docs/module-Sanity-Services.html +0 -8244
- package/docs/module-Sessions.html +0 -575
- package/docs/module-Threads.html +0 -1119
- package/docs/module-UserActivity.html +0 -4534
- package/docs/module-UserChat.html +0 -410
- package/docs/module-UserManagement.html +0 -1932
- package/docs/module-UserMemberships.html +0 -829
- package/docs/module-UserNotifications.html +0 -2595
- package/docs/module-UserProfile.html +0 -370
- package/docs/progress-row_method-card.js.html +0 -184
- package/docs/railcontent.js.html +0 -724
- package/docs/sanity.js.html +0 -2322
- package/docs/scripts/collapse.js +0 -39
- package/docs/scripts/commonNav.js +0 -28
- package/docs/scripts/linenumber.js +0 -25
- package/docs/scripts/nav.js +0 -12
- package/docs/scripts/polyfill.js +0 -4
- package/docs/scripts/prettify/Apache-License-2.0.txt +0 -202
- package/docs/scripts/prettify/lang-css.js +0 -2
- package/docs/scripts/prettify/prettify.js +0 -28
- package/docs/scripts/search.js +0 -99
- package/docs/styles/jsdoc.css +0 -776
- package/docs/styles/prettify.css +0 -80
- package/docs/userActivity.js.html +0 -1512
- package/docs/user_account.ts.html +0 -265
- package/docs/user_chat.js.html +0 -98
- package/docs/user_interests.js.html +0 -150
- package/docs/user_management.js.html +0 -258
- package/docs/user_memberships.js.html +0 -144
- package/docs/user_memberships.ts.html +0 -292
- package/docs/user_notifications.js.html +0 -374
- package/docs/user_onboarding.ts.html +0 -329
- package/docs/user_payments.ts.html +0 -146
- package/docs/user_permissions.js.html +0 -110
- package/docs/user_profile.js.html +0 -115
- package/docs/user_sessions.js.html +0 -170
- package/docs/user_types.js.html +0 -224
- package/docs/user_user-management-system.js.html +0 -79
|
@@ -1,61 +1,78 @@
|
|
|
1
|
-
name:
|
|
1
|
+
name: Deploy Docs to GitHub Pages
|
|
2
2
|
on:
|
|
3
3
|
push:
|
|
4
|
-
branches: [project-v2]
|
|
4
|
+
branches: [main, project-v2]
|
|
5
|
+
|
|
6
|
+
# Required permissions for GitHub Pages deployment
|
|
7
|
+
permissions:
|
|
8
|
+
contents: read
|
|
9
|
+
pages: write
|
|
10
|
+
id-token: write
|
|
11
|
+
|
|
12
|
+
# Allow only one concurrent deployment
|
|
13
|
+
concurrency:
|
|
14
|
+
group: "pages"
|
|
15
|
+
cancel-in-progress: false
|
|
5
16
|
|
|
6
17
|
jobs:
|
|
7
|
-
|
|
18
|
+
deploy-docs:
|
|
8
19
|
runs-on: ubuntu-latest
|
|
20
|
+
environment:
|
|
21
|
+
name: github-pages
|
|
22
|
+
url: ${{ steps.deployment.outputs.page_url }}
|
|
23
|
+
|
|
9
24
|
steps:
|
|
25
|
+
- name: Checkout main branch
|
|
26
|
+
uses: actions/checkout@v4
|
|
27
|
+
with:
|
|
28
|
+
ref: main
|
|
29
|
+
path: main-content
|
|
30
|
+
|
|
10
31
|
- name: Checkout project-v2 branch
|
|
11
32
|
uses: actions/checkout@v4
|
|
12
33
|
with:
|
|
13
34
|
ref: project-v2
|
|
14
|
-
path:
|
|
35
|
+
path: v2-content
|
|
15
36
|
|
|
16
|
-
- name:
|
|
17
|
-
uses: actions/
|
|
37
|
+
- name: Setup Node.js
|
|
38
|
+
uses: actions/setup-node@v4
|
|
18
39
|
with:
|
|
19
|
-
|
|
20
|
-
path: main-content
|
|
21
|
-
token: ${{ secrets.PROJECT_V2_DOCS_TOKEN }} #use separate token to trigger other actions
|
|
40
|
+
node-version: '20'
|
|
22
41
|
|
|
23
|
-
- name:
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
- name: Commit and push changes to main
|
|
41
|
-
id: commit
|
|
42
|
+
- name: Install dependencies for v1
|
|
43
|
+
working-directory: main-content
|
|
44
|
+
run: npm ci
|
|
45
|
+
|
|
46
|
+
- name: Generate v1 documentation
|
|
47
|
+
working-directory: main-content
|
|
48
|
+
run: npm run doc
|
|
49
|
+
|
|
50
|
+
- name: Install dependencies for v2
|
|
51
|
+
working-directory: v2-content
|
|
52
|
+
run: npm ci
|
|
53
|
+
|
|
54
|
+
- name: Generate v2 documentation
|
|
55
|
+
working-directory: v2-content
|
|
56
|
+
run: npm run doc
|
|
57
|
+
|
|
58
|
+
- name: Combine v1 and v2 docs into deployment structure
|
|
42
59
|
run: |
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
60
|
+
mkdir -p _site
|
|
61
|
+
# Copy v1 docs to root
|
|
62
|
+
cp -r main-content/docs/* _site/
|
|
63
|
+
# Copy v2 docs to /v2/ subdirectory
|
|
64
|
+
mkdir -p _site/v2
|
|
65
|
+
cp -r v2-content/docs/* _site/v2/
|
|
66
|
+
echo "✅ Combined v1 (root) and v2 (/v2/) documentation"
|
|
67
|
+
|
|
68
|
+
- name: Setup GitHub Pages
|
|
69
|
+
uses: actions/configure-pages@v4
|
|
70
|
+
|
|
71
|
+
- name: Upload combined documentation artifact
|
|
72
|
+
uses: actions/upload-pages-artifact@v3
|
|
73
|
+
with:
|
|
74
|
+
path: './_site'
|
|
75
|
+
|
|
76
|
+
- name: Deploy to GitHub Pages
|
|
77
|
+
id: deployment
|
|
78
|
+
uses: actions/deploy-pages@v4
|
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,29 @@
|
|
|
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.92.7](https://github.com/railroadmedia/musora-content-services/compare/v2.92.6...v2.92.7) (2025-12-02)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
### Bug Fixes
|
|
9
|
+
|
|
10
|
+
* **agi:** make brand parameter less strict for now ([#603](https://github.com/railroadmedia/musora-content-services/issues/603)) ([b440b92](https://github.com/railroadmedia/musora-content-services/commit/b440b92ae1b4aab80d7e5ac5238c1e386cf09db8))
|
|
11
|
+
|
|
12
|
+
### [2.92.6](https://github.com/railroadmedia/musora-content-services/compare/v2.92.5...v2.92.6) (2025-12-02)
|
|
13
|
+
|
|
14
|
+
### [2.92.5](https://github.com/railroadmedia/musora-content-services/compare/v2.92.3...v2.92.5) (2025-12-02)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
### Bug Fixes
|
|
18
|
+
|
|
19
|
+
* fixes to get things working with watermelon. added todos for subsequent commits ([#601](https://github.com/railroadmedia/musora-content-services/issues/601)) ([ed83230](https://github.com/railroadmedia/musora-content-services/commit/ed83230006c1fc3a79dfd1a4955fb3785651bf1b))
|
|
20
|
+
|
|
21
|
+
### [2.92.4](https://github.com/railroadmedia/musora-content-services/compare/v2.92.3...v2.92.4) (2025-12-02)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
### Bug Fixes
|
|
25
|
+
|
|
26
|
+
* fixes to get things working with watermelon. added todos for subsequent commits ([#601](https://github.com/railroadmedia/musora-content-services/issues/601)) ([ed83230](https://github.com/railroadmedia/musora-content-services/commit/ed83230006c1fc3a79dfd1a4955fb3785651bf1b))
|
|
27
|
+
|
|
5
28
|
### [2.92.3](https://github.com/railroadmedia/musora-content-services/compare/v2.92.2...v2.92.3) (2025-11-28)
|
|
6
29
|
|
|
7
30
|
### [2.92.2](https://github.com/railroadmedia/musora-content-services/compare/v2.92.0...v2.92.2) (2025-11-28)
|
package/package.json
CHANGED
package/src/index.d.ts
CHANGED
|
@@ -92,6 +92,7 @@ import {
|
|
|
92
92
|
contentStatusReset,
|
|
93
93
|
contentStatusStarted,
|
|
94
94
|
getAllCompleted,
|
|
95
|
+
getAllCompletedByIds,
|
|
95
96
|
getAllStarted,
|
|
96
97
|
getAllStartedOrCompleted,
|
|
97
98
|
getLastInteractedOf,
|
|
@@ -561,6 +562,7 @@ declare module 'musora-content-services' {
|
|
|
561
562
|
getActiveDiscussions,
|
|
562
563
|
getActivePath,
|
|
563
564
|
getAllCompleted,
|
|
565
|
+
getAllCompletedByIds,
|
|
564
566
|
getAllStarted,
|
|
565
567
|
getAllStartedOrCompleted,
|
|
566
568
|
getAwardDataForGuidedContent,
|
package/src/index.js
CHANGED
|
@@ -96,6 +96,7 @@ import {
|
|
|
96
96
|
contentStatusReset,
|
|
97
97
|
contentStatusStarted,
|
|
98
98
|
getAllCompleted,
|
|
99
|
+
getAllCompletedByIds,
|
|
99
100
|
getAllStarted,
|
|
100
101
|
getAllStartedOrCompleted,
|
|
101
102
|
getLastInteractedOf,
|
|
@@ -560,6 +561,7 @@ export {
|
|
|
560
561
|
getActiveDiscussions,
|
|
561
562
|
getActivePath,
|
|
562
563
|
getAllCompleted,
|
|
564
|
+
getAllCompletedByIds,
|
|
563
565
|
getAllStarted,
|
|
564
566
|
getAllStartedOrCompleted,
|
|
565
567
|
getAwardDataForGuidedContent,
|
package/src/lib/brands.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
export enum
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
1
|
+
export enum Brands {
|
|
2
|
+
Musora = 'musora',
|
|
3
|
+
Drumeo = 'drumeo',
|
|
4
|
+
Pianote = 'pianote',
|
|
5
|
+
Guitareo = 'guitareo',
|
|
6
|
+
Singeo = 'singeo',
|
|
7
|
+
Playbass = 'playbass',
|
|
8
8
|
}
|
|
@@ -6,7 +6,7 @@ import { FilterBuilder } from '../../filterBuilder.js'
|
|
|
6
6
|
import { buildDataAndTotalQuery } from '../../lib/sanity/query'
|
|
7
7
|
import { fetchSanity, getSortOrder } from '../sanity.js'
|
|
8
8
|
import { Lesson } from './content'
|
|
9
|
-
import {
|
|
9
|
+
import { Brands } from '../../lib/brands'
|
|
10
10
|
|
|
11
11
|
export interface Artist {
|
|
12
12
|
slug: string
|
|
@@ -18,7 +18,7 @@ export interface Artist {
|
|
|
18
18
|
/**
|
|
19
19
|
* Fetch all artists with lessons available for a specific brand.
|
|
20
20
|
*
|
|
21
|
-
* @param {
|
|
21
|
+
* @param {Brands|string} brand - The brand for which to fetch artists.
|
|
22
22
|
* @returns {Promise<Artist[]|null>} - A promise that resolves to an array of artist objects or null if not found.
|
|
23
23
|
*
|
|
24
24
|
* @example
|
|
@@ -26,7 +26,7 @@ export interface Artist {
|
|
|
26
26
|
* .then(artists => console.log(artists))
|
|
27
27
|
* .catch(error => console.error(error));
|
|
28
28
|
*/
|
|
29
|
-
export async function fetchArtists(brand:
|
|
29
|
+
export async function fetchArtists(brand: Brands | string): Promise<Artist[] | null> {
|
|
30
30
|
const filter = await new FilterBuilder(
|
|
31
31
|
`_type == "song" && brand == "${brand}" && references(^._id)`,
|
|
32
32
|
{ bypassPermissions: true }
|
|
@@ -45,7 +45,7 @@ export async function fetchArtists(brand: Brand): Promise<Artist[] | null> {
|
|
|
45
45
|
* Fetch a single artist by their Sanity ID.
|
|
46
46
|
*
|
|
47
47
|
* @param {string} slug - The name of the artist to fetch.
|
|
48
|
-
* @param {
|
|
48
|
+
* @param {Brands|string} [brand] - The brand for which to fetch the artist.
|
|
49
49
|
* @returns {Promise<Artist|null>} - A promise that resolves to an artist objects or null if not found.
|
|
50
50
|
*
|
|
51
51
|
* @example
|
|
@@ -53,7 +53,10 @@ export async function fetchArtists(brand: Brand): Promise<Artist[] | null> {
|
|
|
53
53
|
* .then(artists => console.log(artists))
|
|
54
54
|
* .catch(error => console.error(error));
|
|
55
55
|
*/
|
|
56
|
-
export async function fetchArtistBySlug(
|
|
56
|
+
export async function fetchArtistBySlug(
|
|
57
|
+
slug: string,
|
|
58
|
+
brand?: Brands | string
|
|
59
|
+
): Promise<Artist | null> {
|
|
57
60
|
const brandFilter = brand ? `brand == "${brand}" && ` : ''
|
|
58
61
|
const filter = await new FilterBuilder(`${brandFilter} _type == "song" && references(^._id)`, {
|
|
59
62
|
bypassPermissions: true,
|
|
@@ -84,7 +87,7 @@ export interface LessonsByArtistResponse {
|
|
|
84
87
|
/**
|
|
85
88
|
* Fetch the artist's lessons.
|
|
86
89
|
* @param {string} slug - The slug of the artist
|
|
87
|
-
* @param {
|
|
90
|
+
* @param {Brands|string} brand - The brand for which to fetch lessons.
|
|
88
91
|
* @param {string} contentType - The type of the lessons we need to get from the artist. If not defined, groq will get lessons from all content types
|
|
89
92
|
* @param {Object} params - Parameters for sorting, searching, pagination and filtering.
|
|
90
93
|
* @param {string} [params.sort="-published_on"] - The field to sort the lessons by.
|
|
@@ -102,7 +105,7 @@ export interface LessonsByArtistResponse {
|
|
|
102
105
|
*/
|
|
103
106
|
export async function fetchArtistLessons(
|
|
104
107
|
slug: string,
|
|
105
|
-
brand:
|
|
108
|
+
brand: Brands | string,
|
|
106
109
|
contentType: string,
|
|
107
110
|
{
|
|
108
111
|
sort = '-published_on',
|
|
@@ -6,7 +6,7 @@ import { fetchSanity, getSortOrder } from '../sanity.js'
|
|
|
6
6
|
import { FilterBuilder } from '../../filterBuilder.js'
|
|
7
7
|
import { Lesson } from './content'
|
|
8
8
|
import { buildDataAndTotalQuery } from '../../lib/sanity/query'
|
|
9
|
-
import {
|
|
9
|
+
import { Brands } from '../../lib/brands'
|
|
10
10
|
|
|
11
11
|
export interface Genre {
|
|
12
12
|
name: string
|
|
@@ -18,7 +18,7 @@ export interface Genre {
|
|
|
18
18
|
/**
|
|
19
19
|
* Fetch all genres with lessons available for a specific brand.
|
|
20
20
|
*
|
|
21
|
-
* @param {string} [brand] - The brand for which to fetch the genre for. Lesson count will be filtered by this brand if provided.
|
|
21
|
+
* @param {Brands|string} [brand] - The brand for which to fetch the genre for. Lesson count will be filtered by this brand if provided.
|
|
22
22
|
* @returns {Promise<Genre[]>} - A promise that resolves to an genre object or null if not found.
|
|
23
23
|
*
|
|
24
24
|
* @example
|
|
@@ -26,7 +26,7 @@ export interface Genre {
|
|
|
26
26
|
* .then(genres => console.log(genres))
|
|
27
27
|
* .catch(error => console.error(error));
|
|
28
28
|
*/
|
|
29
|
-
export async function fetchGenres(brand:
|
|
29
|
+
export async function fetchGenres(brand: Brands | string): Promise<Genre[]> {
|
|
30
30
|
const filter = await new FilterBuilder(`brand == "${brand}" && references(^._id)`, {
|
|
31
31
|
bypassPermissions: true,
|
|
32
32
|
}).buildFilter()
|
|
@@ -46,7 +46,7 @@ export async function fetchGenres(brand: Brand): Promise<Genre[]> {
|
|
|
46
46
|
* Fetch a single genre by their slug and brand
|
|
47
47
|
*
|
|
48
48
|
* @param {string} slug - The slug of the genre to fetch.
|
|
49
|
-
* @param {
|
|
49
|
+
* @param {Brands|string} [brand] - The brand for which to fetch the genre. Lesson count will be filtered by this brand if provided.
|
|
50
50
|
* @returns {Promise<Genre[]|null>} - A promise that resolves to an genre object or null if not found.
|
|
51
51
|
*
|
|
52
52
|
* @example
|
|
@@ -54,7 +54,10 @@ export async function fetchGenres(brand: Brand): Promise<Genre[]> {
|
|
|
54
54
|
* .then(genres => console.log(genres))
|
|
55
55
|
* .catch(error => console.error(error));
|
|
56
56
|
*/
|
|
57
|
-
export async function fetchGenreBySlug(
|
|
57
|
+
export async function fetchGenreBySlug(
|
|
58
|
+
slug: string,
|
|
59
|
+
brand?: Brands | string
|
|
60
|
+
): Promise<Genre | null> {
|
|
58
61
|
const brandFilter = brand ? `brand == "${brand}" && ` : ''
|
|
59
62
|
const filter = await new FilterBuilder(`${brandFilter} references(^._id)`, {
|
|
60
63
|
bypassPermissions: true,
|
|
@@ -88,7 +91,7 @@ export interface LessonsByGenreResponse {
|
|
|
88
91
|
/**
|
|
89
92
|
* Fetch the genre's lessons.
|
|
90
93
|
* @param {string} slug - The slug of the genre
|
|
91
|
-
* @param {
|
|
94
|
+
* @param {Brands|string} brand - The brand for which to fetch lessons.
|
|
92
95
|
* @param {Object} params - Parameters for sorting, searching, pagination and filtering.
|
|
93
96
|
* @param {string} [params.sort="-published_on"] - The field to sort the lessons by.
|
|
94
97
|
* @param {string} [params.searchTerm=""] - The search term to filter the lessons.
|
|
@@ -105,7 +108,7 @@ export interface LessonsByGenreResponse {
|
|
|
105
108
|
*/
|
|
106
109
|
export async function fetchGenreLessons(
|
|
107
110
|
slug: string,
|
|
108
|
-
brand:
|
|
111
|
+
brand: Brands | string,
|
|
109
112
|
contentType?: string,
|
|
110
113
|
{
|
|
111
114
|
sort = '-published_on',
|
|
@@ -6,7 +6,7 @@ import { filtersToGroq, getFieldsForContentType } from '../../contentTypeConfig.
|
|
|
6
6
|
import { fetchSanity, getSortOrder } from '../sanity.js'
|
|
7
7
|
import { Lesson } from './content'
|
|
8
8
|
import { buildDataAndTotalQuery } from '../../lib/sanity/query'
|
|
9
|
-
import {
|
|
9
|
+
import { Brands } from '../../lib/brands'
|
|
10
10
|
|
|
11
11
|
export interface Instructor {
|
|
12
12
|
lessonCount: number
|
|
@@ -19,7 +19,7 @@ export interface Instructor {
|
|
|
19
19
|
/**
|
|
20
20
|
* Fetch all instructor with lessons available for a specific brand.
|
|
21
21
|
*
|
|
22
|
-
* @param {
|
|
22
|
+
* @param {Brands|string} brand - The brand for which to fetch instructors.
|
|
23
23
|
* @returns {Promise<Instructor[]>} - A promise that resolves to an array of instructor objects.
|
|
24
24
|
*
|
|
25
25
|
* @example
|
|
@@ -27,7 +27,7 @@ export interface Instructor {
|
|
|
27
27
|
* .then(instructors => console.log(instructors))
|
|
28
28
|
* .catch(error => console.error(error));
|
|
29
29
|
*/
|
|
30
|
-
export async function fetchInstructors(brand:
|
|
30
|
+
export async function fetchInstructors(brand: Brands | string): Promise<Instructor[]> {
|
|
31
31
|
const filter = await new FilterBuilder(`brand == "${brand}" && references(^._id)`, {
|
|
32
32
|
bypassPermissions: true,
|
|
33
33
|
}).buildFilter()
|
|
@@ -46,7 +46,7 @@ export async function fetchInstructors(brand: Brand): Promise<Instructor[]> {
|
|
|
46
46
|
* Fetch a single instructor by their name
|
|
47
47
|
*
|
|
48
48
|
* @param {string} slug - The slug of the instructor to fetch.
|
|
49
|
-
* @param {
|
|
49
|
+
* @param {Brands|string} [brand] - The brand for which to fetch the instructor. Lesson count will be filtered by this brand if provided.
|
|
50
50
|
* @returns {Promise<Instructor[]>} - A promise that resolves to an instructor object or null if not found.
|
|
51
51
|
*
|
|
52
52
|
* @example
|
|
@@ -56,7 +56,7 @@ export async function fetchInstructors(brand: Brand): Promise<Instructor[]> {
|
|
|
56
56
|
*/
|
|
57
57
|
export async function fetchInstructorBySlug(
|
|
58
58
|
slug: string,
|
|
59
|
-
brand?:
|
|
59
|
+
brand?: Brands | string
|
|
60
60
|
): Promise<Instructor | null> {
|
|
61
61
|
const brandFilter = brand ? `brand == "${brand}" && ` : ''
|
|
62
62
|
const filter = await new FilterBuilder(`${brandFilter} references(^._id)`, {
|
|
@@ -89,8 +89,8 @@ export interface InstructorLessonsResponse {
|
|
|
89
89
|
|
|
90
90
|
/**
|
|
91
91
|
* Fetch the data needed for the instructor screen.
|
|
92
|
-
* @param {string} brand - The brand for which to fetch instructor lessons
|
|
93
92
|
* @param {string} slug - The slug of the instructor
|
|
93
|
+
* @param {Brands|string} brand - The brand for which to fetch instructor lessons
|
|
94
94
|
*
|
|
95
95
|
* @param {FetchInstructorLessonsOptions} options - Parameters for pagination, filtering and sorting.
|
|
96
96
|
* @param {string} [options.sortOrder="-published_on"] - The field to sort the lessons by.
|
|
@@ -107,7 +107,7 @@ export interface InstructorLessonsResponse {
|
|
|
107
107
|
*/
|
|
108
108
|
export async function fetchInstructorLessons(
|
|
109
109
|
slug: string,
|
|
110
|
-
brand:
|
|
110
|
+
brand: Brands | string,
|
|
111
111
|
{
|
|
112
112
|
sortOrder = '-published_on',
|
|
113
113
|
searchTerm = '',
|
|
@@ -268,7 +268,7 @@ export async function completeMethodIntroVideo(introVideoId: number, brand: stri
|
|
|
268
268
|
response.intro_video_response = await completeIfNotCompleted(introVideoId)
|
|
269
269
|
|
|
270
270
|
const methodStructure = await fetchMethodV2Structure(brand)
|
|
271
|
-
const learningPathId = methodStructure.
|
|
271
|
+
const learningPathId = methodStructure.learning_paths[0].id
|
|
272
272
|
|
|
273
273
|
response.active_path_response = await startLearningPath(brand, learningPathId)
|
|
274
274
|
|
|
@@ -279,7 +279,7 @@ export async function completeMethodIntroVideo(introVideoId: number, brand: stri
|
|
|
279
279
|
interface completeLearningPathIntroVideo {
|
|
280
280
|
intro_video_response: Object | null,
|
|
281
281
|
learning_path_reset_response: void | null,
|
|
282
|
-
lesson_import_response: Object
|
|
282
|
+
lesson_import_response: Object | null
|
|
283
283
|
}
|
|
284
284
|
/**
|
|
285
285
|
* Handles completion of learning path intro video and other related actions.
|
|
@@ -299,12 +299,12 @@ export async function completeLearningPathIntroVideo(introVideoId: number, learn
|
|
|
299
299
|
const collection = { id: learningPathId, type: 'learning-path-v2' }
|
|
300
300
|
|
|
301
301
|
if (!lessonsToImport) {
|
|
302
|
-
// returns nothing now, but it will when watermelon comes 'round
|
|
303
302
|
response.learning_path_reset_response = await contentStatusReset(learningPathId, collection)
|
|
304
303
|
|
|
305
304
|
} else {
|
|
306
305
|
response.lesson_import_response = {}
|
|
307
306
|
for (const contentId of lessonsToImport) {
|
|
307
|
+
// todo: create bulk complete endpoint with bubbling. and set up watermelon method bubbling
|
|
308
308
|
response.lesson_import_response[contentId] = await contentStatusCompleted(contentId, collection)
|
|
309
309
|
}
|
|
310
310
|
}
|
|
@@ -18,7 +18,7 @@ export async function getMethodCard(brand) {
|
|
|
18
18
|
const introVideo = await fetchMethodV2IntroVideo(brand)
|
|
19
19
|
const introVideoProgressState = await getProgressState(introVideo?.id)
|
|
20
20
|
//resetAllLearningPaths()
|
|
21
|
-
if (introVideoProgressState
|
|
21
|
+
if (introVideoProgressState !== 'completed') {
|
|
22
22
|
//startLearningPath('drumeo', 422533)
|
|
23
23
|
const timestamp = Math.floor(Date.now() / 1000)
|
|
24
24
|
return {
|
|
@@ -9,13 +9,8 @@
|
|
|
9
9
|
|
|
10
10
|
import { HttpClient } from '../../infrastructure/http/HttpClient'
|
|
11
11
|
import { globalConfig } from '../config.js'
|
|
12
|
-
import {
|
|
13
|
-
|
|
14
|
-
ReportableType,
|
|
15
|
-
IssueTypeMap,
|
|
16
|
-
ReportIssueOption,
|
|
17
|
-
} from './types'
|
|
18
|
-
import {Brand} from "../../lib/brands";
|
|
12
|
+
import { ReportResponse, ReportableType, IssueTypeMap, ReportIssueOption } from './types'
|
|
13
|
+
import { Brands } from '../../lib/brands'
|
|
19
14
|
|
|
20
15
|
/**
|
|
21
16
|
* Parameters for submitting a report with type-safe issue values
|
|
@@ -30,7 +25,7 @@ export type ReportParams<T extends ReportableType = ReportableType> = {
|
|
|
30
25
|
/** Details about the issue - required when issue is 'other', not sent otherwise */
|
|
31
26
|
details?: string
|
|
32
27
|
/** Brand context (required: drumeo, pianote, guitareo, singeo, playbass) */
|
|
33
|
-
brand:
|
|
28
|
+
brand: Brands | string
|
|
34
29
|
}
|
|
35
30
|
|
|
36
31
|
/**
|
|
@@ -73,7 +68,9 @@ export type ReportParams<T extends ReportableType = ReportableType> = {
|
|
|
73
68
|
* brand: 'drumeo'
|
|
74
69
|
* })
|
|
75
70
|
*/
|
|
76
|
-
export async function report<T extends ReportableType>(
|
|
71
|
+
export async function report<T extends ReportableType>(
|
|
72
|
+
params: ReportParams<T>
|
|
73
|
+
): Promise<ReportResponse> {
|
|
77
74
|
const httpClient = new HttpClient(globalConfig.baseUrl)
|
|
78
75
|
|
|
79
76
|
// Build request body
|
|
@@ -125,7 +122,10 @@ export async function report<T extends ReportableType>(params: ReportParams<T>):
|
|
|
125
122
|
* // { value: 'other', label: 'Other' }
|
|
126
123
|
* // ]
|
|
127
124
|
*/
|
|
128
|
-
export function getReportIssueOptions(
|
|
125
|
+
export function getReportIssueOptions(
|
|
126
|
+
type: ReportableType,
|
|
127
|
+
isMobileApp: boolean = false
|
|
128
|
+
): ReportIssueOption[] {
|
|
129
129
|
switch (type) {
|
|
130
130
|
case 'forum_post':
|
|
131
131
|
return [
|
|
@@ -147,7 +147,10 @@ export function getReportIssueOptions(type: ReportableType, isMobileApp: boolean
|
|
|
147
147
|
|
|
148
148
|
case 'content':
|
|
149
149
|
const contentOptions = [
|
|
150
|
-
{
|
|
150
|
+
{
|
|
151
|
+
value: 'incorrect_metadata',
|
|
152
|
+
label: 'The lesson image, title or description is incorrect',
|
|
153
|
+
},
|
|
151
154
|
{ value: 'video_issue', label: 'Video issue' },
|
|
152
155
|
]
|
|
153
156
|
|
|
@@ -165,7 +168,10 @@ export function getReportIssueOptions(type: ReportableType, isMobileApp: boolean
|
|
|
165
168
|
|
|
166
169
|
case 'playlist':
|
|
167
170
|
const playlistOptions = [
|
|
168
|
-
{
|
|
171
|
+
{
|
|
172
|
+
value: 'incorrect_metadata',
|
|
173
|
+
label: 'The lesson image, title or description is incorrect',
|
|
174
|
+
},
|
|
169
175
|
{ value: 'video_issue', label: 'Video issue' },
|
|
170
176
|
]
|
|
171
177
|
|
|
@@ -182,8 +188,6 @@ export function getReportIssueOptions(type: ReportableType, isMobileApp: boolean
|
|
|
182
188
|
return playlistOptions
|
|
183
189
|
|
|
184
190
|
default:
|
|
185
|
-
return [
|
|
186
|
-
{ value: 'other', label: 'Other' },
|
|
187
|
-
]
|
|
191
|
+
return [{ value: 'other', label: 'Other' }]
|
|
188
192
|
}
|
|
189
193
|
}
|
|
@@ -117,6 +117,9 @@ export function makeFetchRequest(input: RequestInfo, init?: RequestInit): (sessi
|
|
|
117
117
|
...init,
|
|
118
118
|
headers: {
|
|
119
119
|
...init?.headers,
|
|
120
|
+
...globalConfig.sessionConfig?.token ? {
|
|
121
|
+
'Authorization': `Bearer ${globalConfig.sessionConfig.token}`
|
|
122
|
+
} : {},
|
|
120
123
|
'Content-Type': 'application/json',
|
|
121
124
|
'X-Sync-Client-Id': session.getClientId(),
|
|
122
125
|
...(session.getSessionId() ? {
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* @module Onboarding
|
|
3
3
|
*/
|
|
4
4
|
import { HttpClient } from '../../infrastructure/http/HttpClient'
|
|
5
|
-
import {
|
|
5
|
+
import { Brands } from '../../lib/brands'
|
|
6
6
|
import { globalConfig } from '../config.js'
|
|
7
7
|
|
|
8
8
|
export interface OnboardingSteps {
|
|
@@ -224,13 +224,13 @@ const recommendedContentCache: { [brand: string]: OnboardingRecommendedContent }
|
|
|
224
224
|
* Fetches recommended content for onboarding based on the specified brand.
|
|
225
225
|
*
|
|
226
226
|
* @param {string} email - The user's email address.
|
|
227
|
-
* @param {
|
|
227
|
+
* @param {Brands} brand - The brand identifier.
|
|
228
228
|
* @returns {Promise<OnboardingRecommendedContent>} - A promise that resolves with the recommended content.
|
|
229
229
|
* @throws {HttpError} - If the HTTP request fails.
|
|
230
230
|
*/
|
|
231
231
|
export async function getOnboardingRecommendedContent(
|
|
232
232
|
email: string,
|
|
233
|
-
brand:
|
|
233
|
+
brand: Brands
|
|
234
234
|
): Promise<OnboardingRecommendedContent> {
|
|
235
235
|
// TODO: Replace with real API call when available
|
|
236
236
|
if (recommendedContentCache[brand]) {
|