musora-content-services 1.0.78 → 1.0.79
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/CHANGELOG.md +2 -0
- package/link_mcs.sh +0 -0
- package/package.json +1 -1
- package/publish.sh +0 -0
- package/src/contentTypeConfig.js +22 -1
- package/src/index.d.ts +2 -0
- package/src/index.js +4 -0
- package/src/services/sanity.js +36 -14
- package/test/sanityQueryService.test.js +35 -0
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
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
|
+
### [1.0.79](https://github.com/railroadmedia/musora-content-services/compare/v1.0.77...v1.0.79) (2024-09-05)
|
|
6
|
+
|
|
5
7
|
### [1.0.77](https://github.com/railroadmedia/musora-content-services/compare/v1.0.76...v1.0.77) (2024-09-04)
|
|
6
8
|
|
|
7
9
|
### [1.0.76](https://github.com/railroadmedia/musora-content-services/compare/v1.0.75...v1.0.76) (2024-08-30)
|
package/link_mcs.sh
CHANGED
|
File without changes
|
package/package.json
CHANGED
package/publish.sh
CHANGED
|
File without changes
|
package/src/contentTypeConfig.js
CHANGED
|
@@ -134,13 +134,14 @@ let contentTypeConfig = {
|
|
|
134
134
|
'low_soundslice_slug'
|
|
135
135
|
]
|
|
136
136
|
},
|
|
137
|
-
'pack-
|
|
137
|
+
'pack-children': {
|
|
138
138
|
'fields': [
|
|
139
139
|
'child_count',
|
|
140
140
|
`"children": child[]->{
|
|
141
141
|
"description": ${descriptionField},
|
|
142
142
|
${getFieldsForContentType()}
|
|
143
143
|
}`,
|
|
144
|
+
'"resources": resource',
|
|
144
145
|
'"image": logo_image_url.asset->url',
|
|
145
146
|
'"thumbnail": thumbnail.asset->url',
|
|
146
147
|
'"light_logo": light_mode_logo_url.asset->url',
|
|
@@ -149,6 +150,26 @@ let contentTypeConfig = {
|
|
|
149
150
|
'total_xp',
|
|
150
151
|
]
|
|
151
152
|
},
|
|
153
|
+
'foundation': {
|
|
154
|
+
'fields': [
|
|
155
|
+
`"description": ${descriptionField}`,
|
|
156
|
+
`"instructors":instructor[]->name`,
|
|
157
|
+
`"units": child[]->{
|
|
158
|
+
"id": railcontent_id,
|
|
159
|
+
published_on,
|
|
160
|
+
child_count,
|
|
161
|
+
difficulty,
|
|
162
|
+
difficulty_string,
|
|
163
|
+
"thumbnail_url": thumbnail.asset->url,
|
|
164
|
+
"instructor": instructor[]->{name},
|
|
165
|
+
title,
|
|
166
|
+
"type": _type,
|
|
167
|
+
"description": ${descriptionField},
|
|
168
|
+
"url": web_url_path,
|
|
169
|
+
xp,
|
|
170
|
+
}`
|
|
171
|
+
]
|
|
172
|
+
},
|
|
152
173
|
// content with just the added 'instructors' Field
|
|
153
174
|
'student-focus': contentWithInstructorsField,
|
|
154
175
|
'quick-tips': contentWithInstructorsField,
|
package/src/index.d.ts
CHANGED
|
@@ -14,6 +14,7 @@ import {
|
|
|
14
14
|
fetchByRailContentIds,
|
|
15
15
|
fetchAll,
|
|
16
16
|
fetchAllFilterOptions,
|
|
17
|
+
fetchFoundation,
|
|
17
18
|
fetchMethods,
|
|
18
19
|
fetchMethod,
|
|
19
20
|
fetchMethodChildren,
|
|
@@ -51,6 +52,7 @@ declare module 'musora-content-services' {
|
|
|
51
52
|
fetchByRailContentIds,
|
|
52
53
|
fetchAll,
|
|
53
54
|
fetchAllFilterOptions,
|
|
55
|
+
fetchFoundation,
|
|
54
56
|
fetchMethods,
|
|
55
57
|
fetchMethod,
|
|
56
58
|
fetchMethodNextLesson,
|
package/src/index.js
CHANGED
|
@@ -16,6 +16,7 @@ import {
|
|
|
16
16
|
fetchAll,
|
|
17
17
|
fetchAllFilterOptions,
|
|
18
18
|
fetchMethodNextLesson,
|
|
19
|
+
fetchFoundation,
|
|
19
20
|
fetchMethod,
|
|
20
21
|
fetchMethods,
|
|
21
22
|
fetchMethodChildren,
|
|
@@ -38,6 +39,7 @@ import {
|
|
|
38
39
|
fetchAllCompletedStates,
|
|
39
40
|
fetchContentInProgress,
|
|
40
41
|
fetchVimeoData,
|
|
42
|
+
fetchContentPageUserData,
|
|
41
43
|
} from './services/railcontent.js';
|
|
42
44
|
|
|
43
45
|
|
|
@@ -57,6 +59,7 @@ export {
|
|
|
57
59
|
fetchByRailContentIds,
|
|
58
60
|
fetchAll,
|
|
59
61
|
fetchAllFilterOptions,
|
|
62
|
+
fetchFoundation,
|
|
60
63
|
fetchMethods,
|
|
61
64
|
fetchMethod,
|
|
62
65
|
fetchMethodChildren,
|
|
@@ -77,4 +80,5 @@ export {
|
|
|
77
80
|
fetchLiveEvent,
|
|
78
81
|
fetchChallengeOverview,
|
|
79
82
|
fetchVimeoData,
|
|
83
|
+
fetchContentPageUserData,
|
|
80
84
|
}
|
package/src/services/sanity.js
CHANGED
|
@@ -366,6 +366,7 @@ export async function fetchByRailContentIds(ids, contentType = undefined) {
|
|
|
366
366
|
* @param {string} [params.sort="-published_on"] - The field to sort the content by.
|
|
367
367
|
* @param {Array<string>} [params.includedFields=[]] - The fields to include in the query.
|
|
368
368
|
* @param {string} [params.groupBy=""] - The field to group the results by (e.g., 'artist', 'genre').
|
|
369
|
+
* @param {Array<string>} [params.progressIds=undefined] - An array of railcontent IDs to filter the results by. Used for filtering by progress.
|
|
369
370
|
* @returns {Promise<Object|null>} - The fetched content data or null if not found.
|
|
370
371
|
*
|
|
371
372
|
* @example
|
|
@@ -386,7 +387,8 @@ export async function fetchAll(brand, type, {
|
|
|
386
387
|
searchTerm = "",
|
|
387
388
|
sort = "-published_on",
|
|
388
389
|
includedFields = [],
|
|
389
|
-
groupBy = ""
|
|
390
|
+
groupBy = "",
|
|
391
|
+
progressIds = undefined
|
|
390
392
|
} = {}) {
|
|
391
393
|
let config = contentTypeConfig[type] ?? {};
|
|
392
394
|
let additionalFields = config?.fields ?? [];
|
|
@@ -406,6 +408,10 @@ export async function fetchAll(brand, type, {
|
|
|
406
408
|
? filtersToGroq(includedFields)
|
|
407
409
|
: "";
|
|
408
410
|
|
|
411
|
+
// limits the results to supplied progressIds for started & completed filters
|
|
412
|
+
const progressFilter = progressIds !== undefined ?
|
|
413
|
+
`&& railcontent_id in [${progressIds.join(',')}]` : "";
|
|
414
|
+
|
|
409
415
|
// Determine the sort order
|
|
410
416
|
const sortOrder = getSortOrder(sort);
|
|
411
417
|
|
|
@@ -417,15 +423,15 @@ export async function fetchAll(brand, type, {
|
|
|
417
423
|
if (groupBy !== "" && isGroupByOneToOne) {
|
|
418
424
|
query = `
|
|
419
425
|
{
|
|
420
|
-
"total": count(*[_type == '${groupBy}' && count(*[_type == '${type}' && brand == '${brand}' && ^._id == ${groupBy}._ref ${searchFilter} ${includedFieldsFilter}]._id) > 0]),
|
|
421
|
-
"entity": *[_type == '${groupBy}' && count(*[_type == '${type}' && brand == '${brand}' && ^._id == ${groupBy}._ref ${searchFilter} ${includedFieldsFilter}]._id) > 0]
|
|
426
|
+
"total": count(*[_type == '${groupBy}' && count(*[_type == '${type}' && brand == '${brand}' && ^._id == ${groupBy}._ref ${searchFilter} ${includedFieldsFilter} ${progressFilter}]._id) > 0]),
|
|
427
|
+
"entity": *[_type == '${groupBy}' && count(*[_type == '${type}' && brand == '${brand}' && ^._id == ${groupBy}._ref ${searchFilter} ${includedFieldsFilter} ${progressFilter}]._id) > 0]
|
|
422
428
|
{
|
|
423
429
|
'id': _id,
|
|
424
430
|
'type': _type,
|
|
425
431
|
name,
|
|
426
432
|
'head_shot_picture_url': thumbnail_url.asset->url,
|
|
427
|
-
'all_lessons_count': count(*[_type == '${type}' && brand == '${brand}' && ^._id == ${groupBy}._ref ${searchFilter} ${includedFieldsFilter}]._id),
|
|
428
|
-
'lessons': *[_type == '${type}' && brand == '${brand}' && ^._id == ${groupBy}._ref ${searchFilter} ${includedFieldsFilter}]{
|
|
433
|
+
'all_lessons_count': count(*[_type == '${type}' && brand == '${brand}' && ^._id == ${groupBy}._ref ${searchFilter} ${includedFieldsFilter} ${progressFilter}]._id),
|
|
434
|
+
'lessons': *[_type == '${type}' && brand == '${brand}' && ^._id == ${groupBy}._ref ${searchFilter} ${includedFieldsFilter} ${progressFilter}]{
|
|
429
435
|
${fieldsString},
|
|
430
436
|
${groupBy}
|
|
431
437
|
}[0...10]
|
|
@@ -436,15 +442,15 @@ export async function fetchAll(brand, type, {
|
|
|
436
442
|
} else if (groupBy !== "") {
|
|
437
443
|
query = `
|
|
438
444
|
{
|
|
439
|
-
"total": count(*[_type == '${groupBy}' && count(*[_type == '${type}' && brand == '${brand}' && ^._id in ${groupBy}[]._ref ${searchFilter} ${includedFieldsFilter}]._id) > 0]),
|
|
440
|
-
"entity": *[_type == '${groupBy}' && count(*[_type == '${type}' && brand == '${brand}' && ^._id in ${groupBy}[]._ref ${searchFilter} ${includedFieldsFilter}]._id) > 0]
|
|
445
|
+
"total": count(*[_type == '${groupBy}' && count(*[_type == '${type}' && brand == '${brand}' && ^._id in ${groupBy}[]._ref ${searchFilter} ${includedFieldsFilter} ${progressFilter}]._id) > 0]),
|
|
446
|
+
"entity": *[_type == '${groupBy}' && count(*[_type == '${type}' && brand == '${brand}' && ^._id in ${groupBy}[]._ref ${searchFilter} ${includedFieldsFilter} ${progressFilter}]._id) > 0]
|
|
441
447
|
{
|
|
442
448
|
'id': _id,
|
|
443
449
|
'type': _type,
|
|
444
450
|
name,
|
|
445
451
|
'head_shot_picture_url': thumbnail_url.asset->url,
|
|
446
|
-
'all_lessons_count': count(*[_type == '${type}' && brand == '${brand}' && ^._id in ${groupBy}[]._ref ${searchFilter} ${includedFieldsFilter}]._id),
|
|
447
|
-
'lessons': *[_type == '${type}' && brand == '${brand}' && ^._id in ${groupBy}[]._ref ${searchFilter} ${includedFieldsFilter}]{
|
|
452
|
+
'all_lessons_count': count(*[_type == '${type}' && brand == '${brand}' && ^._id in ${groupBy}[]._ref ${searchFilter} ${includedFieldsFilter} ${progressFilter}]._id),
|
|
453
|
+
'lessons': *[_type == '${type}' && brand == '${brand}' && ^._id in ${groupBy}[]._ref ${searchFilter} ${includedFieldsFilter} ${progressFilter}]{
|
|
448
454
|
${fieldsString},
|
|
449
455
|
${groupBy}
|
|
450
456
|
}[0...10]
|
|
@@ -455,10 +461,10 @@ export async function fetchAll(brand, type, {
|
|
|
455
461
|
} else {
|
|
456
462
|
query = `
|
|
457
463
|
{
|
|
458
|
-
"entity": *[_type == '${type}' && brand == "${brand}" ${searchFilter} ${includedFieldsFilter}] | order(${sortOrder}) [${start}...${end}] {
|
|
464
|
+
"entity": *[_type == '${type}' && brand == "${brand}" ${searchFilter} ${includedFieldsFilter} ${progressFilter}] | order(${sortOrder}) [${start}...${end}] {
|
|
459
465
|
${fieldsString}
|
|
460
466
|
},
|
|
461
|
-
"total": count(*[_type == '${type}' && brand == "${brand}" ${searchFilter} ${includedFieldsFilter}])
|
|
467
|
+
"total": count(*[_type == '${type}' && brand == "${brand}" ${searchFilter} ${includedFieldsFilter} ${progressFilter}])
|
|
462
468
|
}
|
|
463
469
|
`;
|
|
464
470
|
}
|
|
@@ -500,7 +506,7 @@ export function getSortOrder(sort= '-published_on', groupBy)
|
|
|
500
506
|
* @param {string} [artist] - Optional artist name to filter the results. If provided, the query will check if the artist's name matches.
|
|
501
507
|
* @param {string} contentType - The content type to fetch (e.g., 'song', 'lesson').
|
|
502
508
|
* @param {string} [term] - Optional search term to match against various fields such as title, album, artist name, and genre.
|
|
503
|
-
*
|
|
509
|
+
* @param {Array<string>} [progressIds=undefined] - An array of railcontent IDs to filter the results by. Used for filtering by progress.
|
|
504
510
|
* @returns {Promise<Object|null>} - A promise that resolves to an object containing the total results and filter options, or null if the query fails.
|
|
505
511
|
*
|
|
506
512
|
* @example
|
|
@@ -515,11 +521,15 @@ export async function fetchAllFilterOptions(
|
|
|
515
521
|
style,
|
|
516
522
|
artist,
|
|
517
523
|
contentType,
|
|
518
|
-
term
|
|
524
|
+
term,
|
|
525
|
+
progressIds = undefined
|
|
519
526
|
) {
|
|
520
527
|
const includedFieldsFilter = filters?.length > 0 ? filtersToGroq(filters) : undefined;
|
|
521
528
|
|
|
522
|
-
const
|
|
529
|
+
const progressFilter = progressIds !== undefined ?
|
|
530
|
+
`&& railcontent_id in [${progressIds.join(',')}]` : "";
|
|
531
|
+
|
|
532
|
+
const commonFilter = `_type == '${contentType}' && brand == "${brand}"${style ? ` && '${style}' in genre[]->name` : ''}${artist ? ` && artist->name == '${artist}'` : ''} ${progressFilter} ${includedFieldsFilter ? includedFieldsFilter : ''}`;
|
|
523
533
|
const query = `
|
|
524
534
|
{
|
|
525
535
|
"meta": {
|
|
@@ -594,6 +604,18 @@ export async function fetchMethods(brand) {
|
|
|
594
604
|
return fetchSanity(query, true);
|
|
595
605
|
}
|
|
596
606
|
|
|
607
|
+
/**
|
|
608
|
+
* Fetch the Foundations 2019.
|
|
609
|
+
* @param {string} slug - The slug of the method.
|
|
610
|
+
* @returns {Promise<Object|null>} - The fetched foundation data or null if not found.
|
|
611
|
+
*/
|
|
612
|
+
export async function fetchFoundation(slug) {
|
|
613
|
+
const query = `*[_type == 'foundation' && slug.current == "${slug}"] {
|
|
614
|
+
${ getFieldsForContentType('foundation') }
|
|
615
|
+
} | order(published_on asc)`
|
|
616
|
+
return fetchSanity(query, false);
|
|
617
|
+
}
|
|
618
|
+
|
|
597
619
|
/**
|
|
598
620
|
* Fetch the Method (learning-paths) for a specific brand.
|
|
599
621
|
* @param {string} brand - The brand for which to fetch methods.
|
|
@@ -27,6 +27,7 @@ const {
|
|
|
27
27
|
fetchChildren,
|
|
28
28
|
fetchMethod,
|
|
29
29
|
fetchMethods,
|
|
30
|
+
fetchFoundation,
|
|
30
31
|
} = require('../src/services/sanity.js');
|
|
31
32
|
|
|
32
33
|
describe('Sanity Queries', function () {
|
|
@@ -203,4 +204,38 @@ describe('Sanity Queries', function () {
|
|
|
203
204
|
expect(response.length).toBeGreaterThan(0);
|
|
204
205
|
expect(response[0].type).toBe('learning-path');
|
|
205
206
|
});
|
|
207
|
+
|
|
208
|
+
test('fetchAll-WithProgress', async () => {
|
|
209
|
+
const ids = [410213, 305649];
|
|
210
|
+
let response = await fetchAll('drumeo', 'song', {
|
|
211
|
+
sort: 'slug',
|
|
212
|
+
progressIds: ids,
|
|
213
|
+
});
|
|
214
|
+
expect(response.entity.length).toBe(2);
|
|
215
|
+
expect(response.entity[0].id = 305649);
|
|
216
|
+
expect(response.entity[1].id = 410213);
|
|
217
|
+
// change the type and we expect no results
|
|
218
|
+
response = await fetchAll('drumeo', 'quick-tip', {
|
|
219
|
+
sort: 'slug',
|
|
220
|
+
progressIds: ids,
|
|
221
|
+
});
|
|
222
|
+
expect(response.entity.length).toBe(0);
|
|
223
|
+
});
|
|
224
|
+
|
|
225
|
+
test('fetchAllFilterOptions-WithProgress', async () => {
|
|
226
|
+
const ids = [410213, 305649];
|
|
227
|
+
let response = await fetchAllFilterOptions('drumeo', '', '', '', 'song', '', ids);
|
|
228
|
+
expect(response.meta.totalResults).toBe(2);
|
|
229
|
+
// change the brand and we expect no results
|
|
230
|
+
response = await fetchAllFilterOptions('singeo', '', '', '', 'song', '', ids);
|
|
231
|
+
expect(response.meta.totalResults).toBe(0);
|
|
232
|
+
|
|
233
|
+
});
|
|
234
|
+
|
|
235
|
+
test('fetchFoundation', async () => {
|
|
236
|
+
const response = await fetchFoundation('foundations-2019');
|
|
237
|
+
//console.log(response);
|
|
238
|
+
expect(response.units.length).toBeGreaterThan(0);
|
|
239
|
+
expect(response.type).toBe('foundation');
|
|
240
|
+
});
|
|
206
241
|
});
|