musora-content-services 2.105.0 → 2.106.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.
Files changed (169) hide show
  1. package/.coderabbit.yaml +0 -0
  2. package/.editorconfig +0 -0
  3. package/.github/pull_request_template.md +0 -0
  4. package/.github/workflows/conventional-commits.yaml +0 -0
  5. package/.github/workflows/docs.js.yml +0 -0
  6. package/.github/workflows/node.js.yml +0 -0
  7. package/.prettierignore +0 -0
  8. package/.prettierrc +0 -0
  9. package/CHANGELOG.md +7 -0
  10. package/CLAUDE.md +0 -0
  11. package/README.md +0 -0
  12. package/babel.config.cjs +0 -0
  13. package/jest.config.js +0 -0
  14. package/jsdoc.json +0 -0
  15. package/package.json +1 -1
  16. package/src/constants/award-assets.js +0 -0
  17. package/src/contentMetaData.js +0 -0
  18. package/src/infrastructure/http/HttpClient.ts +0 -0
  19. package/src/infrastructure/http/executors/FetchRequestExecutor.ts +0 -0
  20. package/src/infrastructure/http/index.ts +0 -0
  21. package/src/infrastructure/http/interfaces/HeaderProvider.ts +0 -0
  22. package/src/infrastructure/http/interfaces/HttpError.ts +0 -0
  23. package/src/infrastructure/http/interfaces/NetworkError.ts +0 -0
  24. package/src/infrastructure/http/interfaces/RequestExecutor.ts +0 -0
  25. package/src/infrastructure/http/interfaces/RequestOptions.ts +0 -0
  26. package/src/infrastructure/http/providers/DefaultHeaderProvider.ts +0 -0
  27. package/src/lib/brands.ts +0 -0
  28. package/src/lib/lastUpdated.js +0 -0
  29. package/src/services/api/types.js +0 -0
  30. package/src/services/api/types.ts +0 -0
  31. package/src/services/awards/internal/.indexignore +0 -0
  32. package/src/services/awards/internal/award-events.js +0 -0
  33. package/src/services/awards/internal/completion-data-generator.js +0 -0
  34. package/src/services/awards/internal/content-progress-observer.js +0 -0
  35. package/src/services/awards/internal/image-utils.js +0 -0
  36. package/src/services/awards/internal/message-generator.js +0 -0
  37. package/src/services/awards/internal/types.js +0 -0
  38. package/src/services/config.js +0 -0
  39. package/src/services/content/content.ts +0 -0
  40. package/src/services/content-org/content-org.js +0 -0
  41. package/src/services/content-org/guided-courses.ts +0 -0
  42. package/src/services/content-org/playlists-types.js +0 -0
  43. package/src/services/content-org/playlists.js +0 -0
  44. package/src/services/contentLikes.js +0 -0
  45. package/src/services/dataContext.js +0 -0
  46. package/src/services/dateUtils.js +0 -0
  47. package/src/services/eventsAPI.js +0 -0
  48. package/src/services/forums/categories.ts +0 -0
  49. package/src/services/forums/posts.ts +0 -0
  50. package/src/services/forums/types.ts +0 -0
  51. package/src/services/gamification/awards.ts +0 -0
  52. package/src/services/gamification/gamification.js +0 -0
  53. package/src/services/imageSRCBuilder.js +0 -0
  54. package/src/services/imageSRCVerify.js +0 -0
  55. package/src/services/liveTesting.ts +0 -0
  56. package/src/services/permissions/PermissionsAdapter.ts +0 -0
  57. package/src/services/permissions/PermissionsAdapterFactory.ts +0 -0
  58. package/src/services/permissions/PermissionsV1Adapter.ts +0 -0
  59. package/src/services/permissions/README.md +0 -0
  60. package/src/services/permissions/index.ts +0 -0
  61. package/src/services/recommendations.js +0 -0
  62. package/src/services/reporting/README.md +0 -0
  63. package/src/services/reporting/reporting.ts +0 -0
  64. package/src/services/reporting/types.ts +0 -0
  65. package/src/services/sentry/.indexignore +0 -0
  66. package/src/services/sentry/index.ts +0 -0
  67. package/src/services/sync/.indexignore +0 -0
  68. package/src/services/sync/adapters/factory.ts +0 -0
  69. package/src/services/sync/adapters/lokijs.ts +0 -0
  70. package/src/services/sync/adapters/sqlite.ts +0 -0
  71. package/src/services/sync/concurrency-safety.ts +0 -0
  72. package/src/services/sync/context/index.ts +0 -0
  73. package/src/services/sync/context/providers/base.ts +0 -0
  74. package/src/services/sync/context/providers/connectivity.ts +0 -0
  75. package/src/services/sync/context/providers/durability.ts +0 -0
  76. package/src/services/sync/context/providers/index.ts +0 -0
  77. package/src/services/sync/context/providers/session.ts +0 -0
  78. package/src/services/sync/context/providers/tabs.ts +0 -0
  79. package/src/services/sync/context/providers/visibility.ts +0 -0
  80. package/src/services/sync/database/factory.ts +0 -0
  81. package/src/services/sync/errors/boundary.ts +0 -0
  82. package/src/services/sync/errors/index.ts +8 -0
  83. package/src/services/sync/errors/validators.ts +42 -0
  84. package/src/services/sync/fetch.ts +1 -1
  85. package/src/services/sync/index.ts +0 -0
  86. package/src/services/sync/models/Base.ts +0 -0
  87. package/src/services/sync/models/ContentLike.ts +2 -1
  88. package/src/services/sync/models/ContentProgress.ts +26 -9
  89. package/src/services/sync/models/Practice.ts +32 -9
  90. package/src/services/sync/models/PracticeDayNote.ts +4 -2
  91. package/src/services/sync/models/UserAwardProgress.ts +14 -3
  92. package/src/services/sync/models/index.ts +0 -0
  93. package/src/services/sync/repositories/base.ts +0 -0
  94. package/src/services/sync/repositories/content-likes.ts +0 -0
  95. package/src/services/sync/repositories/index.ts +0 -0
  96. package/src/services/sync/repositories/practice-day-notes.ts +0 -0
  97. package/src/services/sync/repositories/practices.ts +0 -0
  98. package/src/services/sync/repository-proxy.ts +0 -0
  99. package/src/services/sync/resolver.ts +0 -0
  100. package/src/services/sync/run-scope.ts +0 -0
  101. package/src/services/sync/schema/index.ts +2 -2
  102. package/src/services/sync/serializers/index.ts +0 -0
  103. package/src/services/sync/serializers/model.ts +0 -0
  104. package/src/services/sync/serializers/raw.ts +0 -0
  105. package/src/services/sync/store/push-coalescer.ts +0 -0
  106. package/src/services/sync/store-configs.ts +0 -0
  107. package/src/services/sync/strategies/base.ts +0 -0
  108. package/src/services/sync/strategies/index.ts +0 -0
  109. package/src/services/sync/strategies/initial.ts +0 -0
  110. package/src/services/sync/strategies/polling.ts +0 -0
  111. package/src/services/sync/telemetry/index.ts +0 -0
  112. package/src/services/sync/telemetry/sampling.ts +0 -0
  113. package/src/services/sync/utils/event-emitter.ts +0 -0
  114. package/src/services/sync/utils/index.ts +0 -0
  115. package/src/services/sync/utils/throttle.ts +0 -0
  116. package/src/services/sync/utils/timers.ts +0 -0
  117. package/src/services/types.js +0 -0
  118. package/src/services/user/account.ts +0 -0
  119. package/src/services/user/chat.js +0 -0
  120. package/src/services/user/interests.js +0 -0
  121. package/src/services/user/management.js +0 -0
  122. package/src/services/user/notifications.js +0 -0
  123. package/src/services/user/payments.ts +0 -0
  124. package/src/services/user/permissions.js +0 -0
  125. package/src/services/user/profile.js +0 -0
  126. package/src/services/user/user-management-system.js +0 -0
  127. package/test/HttpClient.test.js +0 -0
  128. package/test/awards/award-alacarte-observer.test.js +0 -0
  129. package/test/awards/award-auto-refresh.test.js +0 -0
  130. package/test/awards/award-calculations.test.js +0 -0
  131. package/test/awards/award-certificate-display.test.js +0 -0
  132. package/test/awards/award-collection-edge-cases.test.js +0 -0
  133. package/test/awards/award-collection-filtering.test.js +0 -0
  134. package/test/awards/award-exclusion-handling.test.js +0 -0
  135. package/test/awards/award-multi-lesson.test.js +0 -0
  136. package/test/awards/award-observer-integration.test.js +0 -0
  137. package/test/awards/award-query-messages.test.js +0 -0
  138. package/test/awards/award-user-collection.test.js +0 -0
  139. package/test/awards/duplicate-prevention.test.js +0 -0
  140. package/test/awards/helpers/completion-mock.js +0 -0
  141. package/test/awards/helpers/index.js +0 -0
  142. package/test/awards/helpers/mock-setup.js +0 -0
  143. package/test/awards/helpers/progress-emitter.js +0 -0
  144. package/test/awards/message-generator.test.js +0 -0
  145. package/test/content.test.js +0 -0
  146. package/test/contentLikes.test.js +0 -0
  147. package/test/contentProgress.test.js +0 -0
  148. package/test/dataContext.test.js +0 -0
  149. package/test/forum.test.js +0 -0
  150. package/test/imageSRCBuilder.test.js +0 -0
  151. package/test/imageSRCVerify.test.js +0 -0
  152. package/test/lib/lastUpdated.test.js +0 -0
  153. package/test/live/contentProgressLive.test.js +0 -0
  154. package/test/live/railcontentLive.test.js +0 -0
  155. package/test/localStorageMock.js +0 -0
  156. package/test/log.js +0 -0
  157. package/test/mockData/award-definitions.js +0 -0
  158. package/test/mockData/mockData_fetchByRailContentIds_one_content.json +0 -0
  159. package/test/mockData/mockData_progress_content.json +0 -0
  160. package/test/mockData/mockData_sanity_progress_content.json +0 -0
  161. package/test/mockData/mockData_user_practices.json +0 -0
  162. package/test/notifications.test.js +0 -0
  163. package/test/progressRows.test.js +0 -0
  164. package/test/streakMessage.test.js +0 -0
  165. package/test/sync/models/award-database-integration.test.js +0 -0
  166. package/test/user/permissions.test.js +0 -0
  167. package/test/userActivity.test.js +0 -0
  168. package/tools/generate-index.cjs +0 -0
  169. package/.claude/settings.local.json +0 -18
package/.coderabbit.yaml CHANGED
File without changes
package/.editorconfig CHANGED
File without changes
File without changes
File without changes
File without changes
File without changes
package/.prettierignore CHANGED
File without changes
package/.prettierrc CHANGED
File without changes
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.106.0](https://github.com/railroadmedia/musora-content-services/compare/v2.105.0...v2.106.0) (2025-12-18)
6
+
7
+
8
+ ### Features
9
+
10
+ * Add some validators prior to writing to watermelon ([#663](https://github.com/railroadmedia/musora-content-services/issues/663)) ([9eeedac](https://github.com/railroadmedia/musora-content-services/commit/9eeedac5a3cf8b4eedd091fcb8252ffd5bae6c85))
11
+
5
12
  ## [2.105.0](https://github.com/railroadmedia/musora-content-services/compare/v2.104.9...v2.105.0) (2025-12-17)
6
13
 
7
14
 
package/CLAUDE.md CHANGED
File without changes
package/README.md CHANGED
File without changes
package/babel.config.cjs CHANGED
File without changes
package/jest.config.js CHANGED
File without changes
package/jsdoc.json CHANGED
File without changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "musora-content-services",
3
- "version": "2.105.0",
3
+ "version": "2.106.0",
4
4
  "description": "A package for Musoras content services ",
5
5
  "main": "src/index.js",
6
6
  "type": "module",
File without changes
File without changes
File without changes
File without changes
File without changes
package/src/lib/brands.ts 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
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
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
@@ -47,3 +47,11 @@ export class SyncUnexpectedError extends SyncError {
47
47
  Object.setPrototypeOf(this, new.target.prototype)
48
48
  }
49
49
  }
50
+
51
+ export class SyncValidationError extends SyncError {
52
+ constructor(message: string, value: any, expected: any) {
53
+ super('validationError', { message: message, value: value, expected: expected })
54
+ this.name = 'SyncValidationError'
55
+ Object.setPrototypeOf(this, new.target.prototype)
56
+ }
57
+ }
@@ -0,0 +1,42 @@
1
+ import { SyncValidationError } from './index'
2
+
3
+
4
+ export function throwIfNotNumber(val: any) {
5
+ // note: this will accept decimal values
6
+ if (typeof val !== 'number') throw new SyncValidationError('Sync value is not a number: ' + val, typeof val, 'number');
7
+ return val
8
+ }
9
+
10
+ export function throwIfNotString(val: any) {
11
+ if (typeof val !== 'string') throw new SyncValidationError('Sync value is not a string: ' + val, typeof val, 'string');
12
+ return val
13
+ }
14
+
15
+ export function throwIfNotBoolean(val: any) {
16
+ if (typeof val !== 'boolean') throw new SyncValidationError('Sync value is not a boolean: ' + val, typeof val, 'boolean');
17
+ return val
18
+ }
19
+
20
+ export function throwIfNotNullableNumber(val: any) {
21
+ return val === null ? val : throwIfNotNumber(val)
22
+ }
23
+
24
+ export function throwIfNotNullableString(val: any) {
25
+ return val === null ? val : throwIfNotString(val)
26
+ }
27
+
28
+ export function throwIfOutsideRange(val: number, minimum?: number, maximum?: number) {
29
+ if (minimum !== undefined && val < minimum) throw new SyncValidationError('Sync value is less than minimum value ' + minimum + ': ' + val, val, null);
30
+ if (maximum !== undefined && val > maximum) throw new SyncValidationError('Sync value is greater than maximum value ' + maximum + ': ' + val, val, null);
31
+ return val
32
+ }
33
+
34
+ export function throwIfMaxLengthExceeded(val: string, maximum: number) {
35
+ if (val.length > maximum) throw new SyncValidationError('Sync value exceeds the maximum length ' + maximum + ': ' + val, val, null);
36
+ return val
37
+ }
38
+
39
+ export function throwIfInvalidEnumValue(val: string, enumClass: any) {
40
+ if (!Object.values(enumClass).includes(val)) throw new SyncValidationError('Sync value is invalid enum value: ' + val, val, enumClass);
41
+ return val
42
+ }
@@ -34,7 +34,7 @@ type SyncPushFetchFailureResponse = SyncResponseBase & {
34
34
  failureType: 'fetch'
35
35
  isRetryable: boolean
36
36
  }
37
- type SyncPushFailureResponse = SyncResponseBase & {
37
+ export type SyncPushFailureResponse = SyncResponseBase & {
38
38
  ok: false,
39
39
  failureType: 'error'
40
40
  originalError: Error
File without changes
File without changes
@@ -1,5 +1,6 @@
1
1
  import { SYNC_TABLES } from '../schema'
2
2
  import BaseModel from './Base'
3
+ import { throwIfNotNumber } from '../errors/validators'
3
4
 
4
5
  export default class ContentLike extends BaseModel<{
5
6
  content_id: number
@@ -11,6 +12,6 @@ export default class ContentLike extends BaseModel<{
11
12
  }
12
13
 
13
14
  set content_id(value: number) {
14
- this._setRaw('content_id', value)
15
+ this._setRaw('content_id', throwIfNotNumber(value))
15
16
  }
16
17
  }
@@ -1,5 +1,12 @@
1
1
  import BaseModel from './Base'
2
2
  import { SYNC_TABLES } from '../schema'
3
+ import {
4
+ throwIfInvalidEnumValue,
5
+ throwIfNotNullableNumber,
6
+ throwIfNotNullableString,
7
+ throwIfNotNumber,
8
+ throwIfOutsideRange,
9
+ } from '../errors/validators'
3
10
 
4
11
  export enum COLLECTION_TYPE {
5
12
  SELF = 'self',
@@ -16,6 +23,7 @@ export enum STATE {
16
23
 
17
24
  export default class ContentProgress extends BaseModel<{
18
25
  content_id: number
26
+ content_brand: string | null
19
27
  collection_type: COLLECTION_TYPE
20
28
  collection_id: number
21
29
  state: STATE
@@ -28,7 +36,7 @@ export default class ContentProgress extends BaseModel<{
28
36
  return this._getRaw('content_id') as number
29
37
  }
30
38
  get content_brand() {
31
- return this._getRaw('content_brand') as string
39
+ return this._getRaw('content_brand') as string | null
32
40
  }
33
41
  get state() {
34
42
  return this._getRaw('state') as STATE
@@ -47,28 +55,37 @@ export default class ContentProgress extends BaseModel<{
47
55
  }
48
56
 
49
57
  set content_id(value: number) {
50
- this._setRaw('content_id', value)
58
+ // unsigned int
59
+ throwIfNotNumber(value)
60
+ this._setRaw('content_id', throwIfOutsideRange(value, 0))
51
61
  }
52
- set content_brand(value: string) {
53
- this._setRaw('content_brand', value)
62
+ set content_brand(value: string | null) {
63
+ this._setRaw('content_brand', throwIfNotNullableString(value))
54
64
  }
55
65
  // IMPORTANT: progress percent only moves forward and is clamped between 0 and 100
56
66
  // also has implications for last-write-wins sync strategy
57
67
  set progress_percent(value: number) {
58
- const normalizedValue = Math.min(100, Math.max(0, value))
59
- const percent = normalizedValue === 0 ? 0 : Math.max(normalizedValue, this.progress_percent)
68
+ // tinyint unsigned
69
+ throwIfNotNumber(value)
70
+ throwIfOutsideRange(value, 0, 100)
71
+ const percent = value === 0 ? 0 : Math.max(value, this.progress_percent)
60
72
 
61
73
  this._setRaw('progress_percent', percent)
62
74
  this._setRaw('state', percent === 100 ? STATE.COMPLETED : STATE.STARTED)
63
75
  }
64
76
  set collection_type(value: COLLECTION_TYPE) {
65
- this._setRaw('collection_type', value)
77
+ // enum collection_type
78
+ this._setRaw('collection_type', throwIfInvalidEnumValue(value, COLLECTION_TYPE))
66
79
  }
67
80
  set collection_id(value: number) {
68
- this._setRaw('collection_id', value)
81
+ // unsigned mediumint 16777215
82
+ throwIfNotNumber(value)
83
+ this._setRaw('collection_id', throwIfOutsideRange(value, 0, 16777215))
69
84
  }
70
85
  set resume_time_seconds(value: number | null) {
71
- this._setRaw('resume_time_seconds', value !== null ? Math.max(0, value) : null)
86
+ // smallint unsigned
87
+ throwIfNotNullableNumber(value)
88
+ this._setRaw('resume_time_seconds', value !== null ? throwIfOutsideRange(value, 0, 65535) : value)
72
89
  }
73
90
 
74
91
  }
@@ -1,5 +1,14 @@
1
1
  import { SYNC_TABLES } from '../schema'
2
2
  import BaseModel from './Base'
3
+ import {
4
+ throwIfMaxLengthExceeded,
5
+ throwIfNotBoolean,
6
+ throwIfNotNullableNumber,
7
+ throwIfNotNullableString,
8
+ throwIfNotNumber,
9
+ throwIfNotString,
10
+ throwIfOutsideRange,
11
+ } from '../errors/validators'
3
12
 
4
13
  export default class Practice extends BaseModel<{
5
14
  manual_id: string | null
@@ -43,30 +52,44 @@ export default class Practice extends BaseModel<{
43
52
  }
44
53
 
45
54
  set manual_id(value: string | null) {
46
- this._setRaw('manual_id', value)
55
+ // char(26)
56
+ throwIfNotNullableString(value)
57
+ this._setRaw('manual_id', value !== null ? throwIfMaxLengthExceeded(value, 26) : value)
47
58
  }
48
59
  set content_id(value: number | null) {
49
- this._setRaw('content_id', value)
60
+ // int unsigned
61
+ throwIfNotNullableNumber(value)
62
+ this._setRaw('content_id', value !== null ? throwIfOutsideRange(value, 0) : value)
50
63
  }
51
64
  set date(value: string) {
52
- this._setRaw('date', value)
65
+ this._setRaw('date', throwIfNotString(value))
53
66
  }
54
67
  set auto(value: boolean) {
55
- this._setRaw('auto', value)
68
+ // tinyint(1)
69
+ this._setRaw('auto', throwIfNotBoolean(value))
56
70
  }
57
71
  set duration_seconds(value: number) {
58
- this._setRaw('duration_seconds', value)
72
+ throwIfNotNumber(value)
73
+ this._setRaw('duration_seconds', throwIfOutsideRange(value, 0, 59999))
59
74
  }
60
75
  set title(value: string | null) {
61
- this._setRaw('title', value)
76
+ // varchar(64)
77
+ throwIfNotNullableString(value)
78
+ this._setRaw('title', value !== null ? throwIfMaxLengthExceeded(value, 64) : value)
62
79
  }
63
80
  set thumbnail_url(value: string | null) {
64
- this._setRaw('thumbnail_url', value)
81
+ // varchar(255)
82
+ throwIfNotNullableString(value)
83
+ this._setRaw('thumbnail_url', value !== null ? throwIfMaxLengthExceeded(value, 255) : value)
65
84
  }
66
85
  set category_id(value: number | null) {
67
- this._setRaw('category_id', value)
86
+ // tinyint unsigned
87
+ throwIfNotNullableNumber(value)
88
+ this._setRaw('category_id', value !== null ? throwIfOutsideRange(value, 0, 255) : value)
68
89
  }
69
90
  set instrument_id(value: number | null) {
70
- this._setRaw('instrument_id', value)
91
+ // tinyint unsigned
92
+ throwIfNotNullableNumber(value)
93
+ this._setRaw('instrument_id', value !== null ? throwIfOutsideRange(value, 0, 255) : value)
71
94
  }
72
95
  }
@@ -1,5 +1,6 @@
1
1
  import { SYNC_TABLES } from '../schema'
2
2
  import BaseModel from './Base'
3
+ import { throwIfMaxLengthExceeded, throwIfNotString } from '../errors/validators'
3
4
 
4
5
  export default class PracticeDayNote extends BaseModel<{
5
6
  date: string
@@ -15,9 +16,10 @@ export default class PracticeDayNote extends BaseModel<{
15
16
  }
16
17
 
17
18
  set date(value: string) {
18
- this._setRaw('date', value)
19
+ this._setRaw('date', throwIfNotString(value))
19
20
  }
20
21
  set notes(value: string) {
21
- this._setRaw('notes', value)
22
+ throwIfNotString(value)
23
+ this._setRaw('notes', throwIfMaxLengthExceeded(value, 3000))
22
24
  }
23
25
  }
@@ -1,6 +1,13 @@
1
1
  import BaseModel from './Base'
2
2
  import { SYNC_TABLES } from '../schema'
3
3
  import type { CompletionData } from '../../awards/types'
4
+ import {
5
+ throwIfMaxLengthExceeded,
6
+ throwIfNotNullableString,
7
+ throwIfNotNumber,
8
+ throwIfNotString,
9
+ throwIfOutsideRange,
10
+ } from '../errors/validators'
4
11
 
5
12
  export default class UserAwardProgress extends BaseModel<{
6
13
  award_id: string
@@ -34,15 +41,19 @@ export default class UserAwardProgress extends BaseModel<{
34
41
  }
35
42
 
36
43
  set award_id(value: string) {
37
- this._setRaw('award_id', value)
44
+ // varchar(255)
45
+ throwIfNotString(value)
46
+ this._setRaw('award_id', throwIfMaxLengthExceeded(value, 255))
38
47
  }
39
48
 
40
49
  set progress_percentage(value: number) {
41
- this._setRaw('progress_percentage', value)
50
+ // int
51
+ throwIfNotNumber(value)
52
+ this._setRaw('progress_percentage', throwIfOutsideRange(value, 0, 100))
42
53
  }
43
54
 
44
55
  set completed_at(value: string | null) {
45
- this._setRaw('completed_at', value)
56
+ this._setRaw('completed_at', throwIfNotNullableString(value))
46
57
  }
47
58
 
48
59
  set progress_data(value: any) {
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
@@ -21,8 +21,8 @@ const contentProgressTable = tableSchema({
21
21
  columns: [
22
22
  { name: 'content_id', type: 'number', isIndexed: true },
23
23
  { name: 'content_brand', type: 'string', isOptional: true, isIndexed: true },
24
- { name: 'collection_type', type: 'string', isOptional: true, isIndexed: true },
25
- { name: 'collection_id', type: 'number', isOptional: true, isIndexed: true },
24
+ { name: 'collection_type', type: 'string', isIndexed: true },
25
+ { name: 'collection_id', type: 'number', isIndexed: true },
26
26
  { name: 'state', type: 'string', isIndexed: true },
27
27
  { name: 'progress_percent', type: 'number' },
28
28
  { name: 'resume_time_seconds', type: 'number', isOptional: true },
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
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
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/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
@@ -1,18 +0,0 @@
1
- {
2
- "permissions": {
3
- "allow": [
4
- "Bash(find:*)",
5
- "Bash(docker exec:*)",
6
- "Bash(npm test:*)",
7
- "WebSearch",
8
- "WebFetch(domain:watermelondb.dev)",
9
- "WebFetch(domain:github.com)",
10
- "Bash(git checkout:*)",
11
- "Bash(npm run doc:*)",
12
- "Bash(cat:*)",
13
- "Bash(tr:*)"
14
- ],
15
- "deny": [],
16
- "ask": []
17
- }
18
- }