musora-content-services 2.96.0 → 2.96.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/CHANGELOG.md CHANGED
@@ -2,6 +2,13 @@
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.96.1](https://github.com/railroadmedia/musora-content-services/compare/v2.96.0...v2.96.1) (2025-12-09)
6
+
7
+
8
+ ### Bug Fixes
9
+
10
+ * **agi:** interface return types ([cc0cfae](https://github.com/railroadmedia/musora-content-services/commit/cc0cfae1282266567ac46a6eb072f76ffde7032e))
11
+
5
12
  ## [2.96.0](https://github.com/railroadmedia/musora-content-services/compare/v2.95.5...v2.96.0) (2025-12-09)
6
13
 
7
14
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "musora-content-services",
3
- "version": "2.96.0",
3
+ "version": "2.96.1",
4
4
  "description": "A package for Musoras content services ",
5
5
  "main": "src/index.js",
6
6
  "type": "module",
@@ -15,6 +15,11 @@ export interface Artist {
15
15
  lessonCount: number
16
16
  }
17
17
 
18
+ export interface Artists {
19
+ data: Artist[]
20
+ total: number
21
+ }
22
+
18
23
  /**
19
24
  * Fetch all artists with lessons available for a specific brand.
20
25
  *
@@ -29,7 +34,7 @@ export interface Artist {
29
34
  export async function fetchArtists(
30
35
  brand: Brands | string,
31
36
  options: BuildQueryOptions = { sort: 'lower(name) asc' }
32
- ): Promise<Artist[] | null> {
37
+ ): Promise<Artists> {
33
38
  const lessonFilter = await new FilterBuilder(`brand == "${brand}" && references(^._id)`, {
34
39
  bypassPermissions: true,
35
40
  }).buildFilter()
@@ -15,6 +15,11 @@ export interface Genre {
15
15
  thumbnail: string
16
16
  }
17
17
 
18
+ export interface Genres {
19
+ data: Genre[]
20
+ total: number
21
+ }
22
+
18
23
  /**
19
24
  * Fetch all genres with lessons available for a specific brand.
20
25
  *
@@ -29,7 +34,7 @@ export interface Genre {
29
34
  export async function fetchGenres(
30
35
  brand: Brands | string,
31
36
  options: BuildQueryOptions = { sort: 'lower(name) asc' }
32
- ): Promise<Genre[]> {
37
+ ): Promise<Genres> {
33
38
  const lessonFilter = await new FilterBuilder(`brand == "${brand}" && references(^._id)`, {
34
39
  bypassPermissions: true,
35
40
  }).buildFilter()
@@ -35,7 +35,7 @@ export interface Instructors {
35
35
  export async function fetchInstructors(
36
36
  brand: Brands | string,
37
37
  options: BuildQueryOptions
38
- ): Promise<Instructor[]> {
38
+ ): Promise<Instructors> {
39
39
  const lessonFilter = await new FilterBuilder(`brand == "${brand}" && references(^._id)`, {
40
40
  bypassPermissions: true,
41
41
  }).buildFilter()
@@ -308,12 +308,7 @@ function serializeIds(ids: { id: RecordId }): { client_record_id: RecordId } {
308
308
 
309
309
  function deserializeRecord(record: SyncSyncable<BaseModel, 'client_record_id'> | null): SyncSyncable<BaseModel, 'id'> | null {
310
310
  if (record) {
311
- const { client_record_id: id, ...rest } = record as any
312
-
313
- if ('collection_type' in rest && rest.collection_type === 'self') {
314
- rest.collection_type = null
315
- rest.collection_id = null
316
- }
311
+ const { client_record_id: id, ...rest } = record
317
312
 
318
313
  return {
319
314
  ...rest,
@@ -2,9 +2,12 @@ import BaseModel from './Base'
2
2
  import { SYNC_TABLES } from '../schema'
3
3
 
4
4
  export enum COLLECTION_TYPE {
5
+ SELF = 'self',
6
+ GUIDED_COURSE = 'guided-course',
5
7
  LEARNING_PATH = 'learning-path-v2',
6
8
  PLAYLIST = 'playlist',
7
9
  }
10
+ export const COLLECTION_ID_SELF = 0
8
11
 
9
12
  export enum STATE {
10
13
  STARTED = 'started',
@@ -13,8 +16,8 @@ export enum STATE {
13
16
 
14
17
  export default class ContentProgress extends BaseModel<{
15
18
  content_id: number
16
- collection_type: COLLECTION_TYPE | null
17
- collection_id: number | null
19
+ collection_type: COLLECTION_TYPE
20
+ collection_id: number
18
21
  state: STATE
19
22
  progress_percent: number
20
23
  resume_time_seconds: number | null
@@ -34,10 +37,10 @@ export default class ContentProgress extends BaseModel<{
34
37
  return this._getRaw('progress_percent') as number
35
38
  }
36
39
  get collection_type() {
37
- return (this._getRaw('collection_type') as COLLECTION_TYPE) || null
40
+ return this._getRaw('collection_type') as COLLECTION_TYPE
38
41
  }
39
42
  get collection_id() {
40
- return (this._getRaw('collection_id') as number) || null
43
+ return this._getRaw('collection_id') as number
41
44
  }
42
45
  get resume_time_seconds() {
43
46
  return (this._getRaw('resume_time_seconds') as number) || null
@@ -55,10 +58,10 @@ export default class ContentProgress extends BaseModel<{
55
58
  set progress_percent(value: number) {
56
59
  this._setRaw('progress_percent', Math.min(100, Math.max(0, value)))
57
60
  }
58
- set collection_type(value: COLLECTION_TYPE | null) {
61
+ set collection_type(value: COLLECTION_TYPE) {
59
62
  this._setRaw('collection_type', value)
60
63
  }
61
- set collection_id(value: number | null) {
64
+ set collection_id(value: number) {
62
65
  this._setRaw('collection_id', value)
63
66
  }
64
67
  set resume_time_seconds(value: number | null) {
@@ -1,12 +1,12 @@
1
1
  import SyncRepository, { Q } from './base'
2
- import ContentProgress, { COLLECTION_TYPE, STATE } from '../models/ContentProgress'
2
+ import ContentProgress, { COLLECTION_TYPE, COLLECTION_ID_SELF, STATE } from '../models/ContentProgress'
3
3
 
4
4
  export default class ProgressRepository extends SyncRepository<ContentProgress> {
5
5
  // null collection only
6
6
  async startedIds(limit?: number) {
7
7
  return this.queryAllIds(...[
8
- Q.where('collection_type', null),
9
- Q.where('collection_id', null),
8
+ Q.where('collection_type', COLLECTION_TYPE.SELF),
9
+ Q.where('collection_id', COLLECTION_ID_SELF),
10
10
 
11
11
  Q.where('state', STATE.STARTED),
12
12
  Q.sortBy('updated_at', 'desc'),
@@ -18,8 +18,8 @@ export default class ProgressRepository extends SyncRepository<ContentProgress>
18
18
  // null collection only
19
19
  async completedIds(limit?: number) {
20
20
  return this.queryAllIds(...[
21
- Q.where('collection_type', null),
22
- Q.where('collection_id', null),
21
+ Q.where('collection_type', COLLECTION_TYPE.SELF),
22
+ Q.where('collection_id', COLLECTION_ID_SELF),
23
23
 
24
24
  Q.where('state', STATE.COMPLETED),
25
25
  Q.sortBy('updated_at', 'desc'),
@@ -55,8 +55,8 @@ export default class ProgressRepository extends SyncRepository<ContentProgress>
55
55
  } = {}
56
56
  ) {
57
57
  const clauses: Q.Clause[] = [
58
- Q.where('collection_type', null),
59
- Q.where('collection_id', null),
58
+ Q.where('collection_type', COLLECTION_TYPE.SELF),
59
+ Q.where('collection_id', COLLECTION_ID_SELF),
60
60
 
61
61
  Q.or(Q.where('state', STATE.STARTED), Q.where('state', STATE.COMPLETED)),
62
62
  Q.sortBy('updated_at', 'desc'),
@@ -80,8 +80,8 @@ export default class ProgressRepository extends SyncRepository<ContentProgress>
80
80
  async mostRecentlyUpdatedId(contentIds: number[], collection: { type: COLLECTION_TYPE; id: number } | null = null) {
81
81
  return this.queryOneId(
82
82
  Q.where('content_id', Q.oneOf(contentIds)),
83
- Q.where('collection_type', collection?.type ?? null),
84
- Q.where('collection_id', collection?.id ?? null),
83
+ Q.where('collection_type', collection?.type ?? COLLECTION_TYPE.SELF),
84
+ Q.where('collection_id', collection?.id ?? COLLECTION_ID_SELF),
85
85
 
86
86
  Q.sortBy('updated_at', 'desc')
87
87
  )
@@ -93,8 +93,8 @@ export default class ProgressRepository extends SyncRepository<ContentProgress>
93
93
  ) {
94
94
  const clauses = [
95
95
  Q.where('content_id', contentId),
96
- Q.where('collection_type', collection?.type ?? null),
97
- Q.where('collection_id', collection?.id ?? null),
96
+ Q.where('collection_type', collection?.type ?? COLLECTION_TYPE.SELF),
97
+ Q.where('collection_id', collection?.id ?? COLLECTION_ID_SELF),
98
98
  ]
99
99
 
100
100
  return await this.queryOne(...clauses)
@@ -106,8 +106,8 @@ export default class ProgressRepository extends SyncRepository<ContentProgress>
106
106
  ) {
107
107
  const clauses = [
108
108
  Q.where('content_id', Q.oneOf(contentIds)),
109
- Q.where('collection_type', collection?.type ?? null),
110
- Q.where('collection_id', collection?.id ?? null),
109
+ Q.where('collection_type', collection?.type ?? COLLECTION_TYPE.SELF),
110
+ Q.where('collection_id', collection?.id ?? COLLECTION_ID_SELF),
111
111
  ]
112
112
 
113
113
  return await this.queryAll(...clauses)
@@ -118,8 +118,8 @@ export default class ProgressRepository extends SyncRepository<ContentProgress>
118
118
 
119
119
  const result = this.upsertOne(id, (r) => {
120
120
  r.content_id = contentId
121
- r.collection_type = collection?.type ?? null
122
- r.collection_id = collection?.id ?? null
121
+ r.collection_type = collection?.type ?? COLLECTION_TYPE.SELF
122
+ r.collection_id = collection?.id ?? COLLECTION_ID_SELF
123
123
 
124
124
  r.state = progressPct === 100 ? STATE.COMPLETED : STATE.STARTED
125
125
  r.progress_percent = progressPct
@@ -142,8 +142,8 @@ export default class ProgressRepository extends SyncRepository<ContentProgress>
142
142
  progressPercent: progressPct,
143
143
  progressStatus: progressPct === 100 ? STATE.COMPLETED : STATE.STARTED,
144
144
  bubble: true,
145
- collectionType: collection?.type ?? null,
146
- collectionId: collection?.id ?? null,
145
+ collectionType: collection?.type ?? COLLECTION_TYPE.SELF,
146
+ collectionId: collection?.id ?? COLLECTION_ID_SELF,
147
147
  resumeTimeSeconds: resumeTime ?? null,
148
148
  timestamp: Date.now()
149
149
  })
@@ -165,8 +165,8 @@ export default class ProgressRepository extends SyncRepository<ContentProgress>
165
165
  ProgressRepository.generateId(contentId, collection),
166
166
  (r: ContentProgress) => {
167
167
  r.content_id = contentId
168
- r.collection_type = collection?.type ?? null
169
- r.collection_id = collection?.id ?? null
168
+ r.collection_type = collection?.type ?? COLLECTION_TYPE.SELF
169
+ r.collection_id = collection?.id ?? COLLECTION_ID_SELF
170
170
 
171
171
  r.state = progressPct === 100 ? STATE.COMPLETED : STATE.STARTED
172
172
  r.progress_percent = progressPct
@@ -185,8 +185,8 @@ export default class ProgressRepository extends SyncRepository<ContentProgress>
185
185
  ProgressRepository.generateId(+contentId, collection),
186
186
  (r: ContentProgress) => {
187
187
  r.content_id = +contentId
188
- r.collection_type = collection?.type ?? null
189
- r.collection_id = collection?.id ?? null
188
+ r.collection_type = collection?.type ?? COLLECTION_TYPE.SELF
189
+ r.collection_id = collection?.id ?? COLLECTION_ID_SELF
190
190
 
191
191
  r.state = progressPct === 100 ? STATE.COMPLETED : STATE.STARTED
192
192
  r.progress_percent = progressPct
@@ -204,10 +204,6 @@ export default class ProgressRepository extends SyncRepository<ContentProgress>
204
204
  contentId: number,
205
205
  collection: { type: COLLECTION_TYPE; id: number } | null
206
206
  ) {
207
- if (collection) {
208
- return `${contentId}:${collection.type}:${collection.id}`
209
- } else {
210
- return `${contentId}`
211
- }
207
+ return `${contentId}:${collection?.type || COLLECTION_TYPE.SELF}:${collection?.id || COLLECTION_ID_SELF}`
212
208
  }
213
209
  }
@@ -1,9 +0,0 @@
1
- {
2
- "permissions": {
3
- "allow": [
4
- "Bash(rg:*)",
5
- "Bash(npm run lint:*)"
6
- ],
7
- "deny": []
8
- }
9
- }