musora-content-services 1.0.104 → 1.0.107
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 +6 -0
- package/docs/config.js.html +1 -1
- package/docs/index.html +46 -8
- package/docs/module-Config.html +1 -1
- package/docs/module-Railcontent-Services.html +1 -1
- package/docs/module-Sanity-Services.html +26 -26
- package/docs/railcontent.js.html +13 -13
- package/docs/sanity.js.html +7 -3
- package/package.json +1 -1
- package/src/contentTypeConfig.js +21 -13
- package/src/filterBuilder.js +122 -0
- package/src/services/railcontent.js +12 -12
- package/src/services/sanity.js +205 -86
- package/test/log.js +5 -0
- package/test/sanityQueryService.test.js +240 -33
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
export class FilterBuilder {
|
|
4
|
+
|
|
5
|
+
STATUS_SCHEDULED = 'scheduled';
|
|
6
|
+
|
|
7
|
+
constructor(
|
|
8
|
+
filter = '',
|
|
9
|
+
{
|
|
10
|
+
user = undefined,
|
|
11
|
+
availableContentStatuses = [],
|
|
12
|
+
bypassPermissions = false,
|
|
13
|
+
pullFutureContent = false,
|
|
14
|
+
getFutureContentOnly = false,
|
|
15
|
+
getFutureScheduledContentsOnly = false,
|
|
16
|
+
|
|
17
|
+
}={}) {
|
|
18
|
+
this.user = user;
|
|
19
|
+
this.availableContentStatuses = availableContentStatuses;
|
|
20
|
+
this.bypassPermissions = bypassPermissions;
|
|
21
|
+
this.pullFutureContent = pullFutureContent;
|
|
22
|
+
this.getFutureContentOnly = getFutureContentOnly;
|
|
23
|
+
this.getFutureScheduledContentsOnly = getFutureScheduledContentsOnly;
|
|
24
|
+
this.filter = filter;
|
|
25
|
+
this.debug = process.env.DEBUG === 'true' || false;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
static withOnlyFilterAvailableStatuses(filter, availableContentStatuses) {
|
|
30
|
+
return new FilterBuilder(filter,{
|
|
31
|
+
availableContentStatuses,
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
buildFilter() {
|
|
36
|
+
if (this.debug) console.log('baseFilter', this.filter);
|
|
37
|
+
const filter = this
|
|
38
|
+
._applyContentStatuses()
|
|
39
|
+
._applyPermissions()
|
|
40
|
+
._applyPublishingDateRestrictions()
|
|
41
|
+
._trimAmpersands() // just in case
|
|
42
|
+
.filter;
|
|
43
|
+
if (this.debug) console.log('finalFilter', filter);
|
|
44
|
+
return filter;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
_applyContentStatuses() {
|
|
48
|
+
// This must be run before _applyPublishDateRestrictions()
|
|
49
|
+
if (this.availableContentStatuses.length === 0) return this;
|
|
50
|
+
// I'm not sure if I'm 100% on this logic, but this is my intepretation of the ContentRepository logic
|
|
51
|
+
if (this.getFutureScheduledContentsOnly && this.availableContentStatuses.includes(this.STATUS_SCHEDULED)) {
|
|
52
|
+
// we must pull in future content here, otherwise we'll restrict on content this is published in the past and remove any scheduled content
|
|
53
|
+
this.pullFutureContent = true;
|
|
54
|
+
const now = new Date().toISOString();
|
|
55
|
+
let statuses = [...this.availableContentStatuses];
|
|
56
|
+
statuses.splice(statuses.indexOf(this.STATUS_SCHEDULED));
|
|
57
|
+
this._andWhere(`(status in ${arrayToStringRepresentation(statuses)} || (status == '${this.STATUS_SCHEDULED}' && published_on >= '${now}'))`)
|
|
58
|
+
|
|
59
|
+
} else {
|
|
60
|
+
this._andWhere(`status in ${arrayToStringRepresentation(this.availableContentStatuses)}`);
|
|
61
|
+
}
|
|
62
|
+
return this;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
_applyPermissions() {
|
|
66
|
+
if (this.bypassPermissions) return this;
|
|
67
|
+
// TODO these need to be pulled from the user and reference either ID, or railcontent_id
|
|
68
|
+
const requiredPermissions = this._getUserPermissions();
|
|
69
|
+
if (requiredPermissions.length === 0) return this;
|
|
70
|
+
// handle pullSongsContent, I think the flagging on this needs to be backwards compared to BE
|
|
71
|
+
// if using id, switch railcontent_id to _id in the below query
|
|
72
|
+
this._andWhere(`references(*[_type == 'permission' && railcontent_id in ${arrayToRawRepresentation(requiredPermissions)}]._id)`);
|
|
73
|
+
return this;
|
|
74
|
+
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
_getUserPermissions() {
|
|
78
|
+
// TODO need user store up and running to complete this, until then just null check
|
|
79
|
+
return this?.user?.permissions ?? [];
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
_applyPublishingDateRestrictions() {
|
|
83
|
+
const now = new Date().toISOString();
|
|
84
|
+
if (this.getFutureContentOnly) {
|
|
85
|
+
this._andWhere(`published_on >= '${now}'`);
|
|
86
|
+
} else if (!this.pullFutureContent) {
|
|
87
|
+
this._andWhere(`published_on <= '${now}'`);
|
|
88
|
+
} else {
|
|
89
|
+
const date = new Date();
|
|
90
|
+
const theFuture = new Date(date.setMonth(date.getMonth() + 18));
|
|
91
|
+
this._andWhere(`published_on <= '${theFuture}'`);
|
|
92
|
+
}
|
|
93
|
+
return this;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
_andWhere(query) {
|
|
97
|
+
const leadingAmpersand = this.filter ? ' && ' : '';
|
|
98
|
+
this.filter += leadingAmpersand + query;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
_orWhere(query) {
|
|
102
|
+
if (!this.filter) throw new Error("invalid query, _orWhere needs to be called on an existing query");
|
|
103
|
+
this.filter += ` || (${query})`;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
_trimAmpersands() {
|
|
107
|
+
this.filter = this.filter.trim();
|
|
108
|
+
while( this.filter.charAt(0) === '&' || this.filter.charAt(0) === ' ' ) this.filter = this.filter.substring(1);
|
|
109
|
+
while( this.filter.charAt(this.filter.length) === '&' || this.filter.charAt(this.filter.length) === ' ' ) this.filter = this.filter.slice(-1);
|
|
110
|
+
return this;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
export function arrayToStringRepresentation(arr) {
|
|
117
|
+
return '[' + arr.map(item => `'${item}'`).join(',') + ']';
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
export function arrayToRawRepresentation(arr) {
|
|
121
|
+
return '[' + arr.map(item => `${item}`).join(',') + ']';
|
|
122
|
+
}
|
|
@@ -150,15 +150,15 @@ export async function fetchSongsInProgress(brand) {
|
|
|
150
150
|
* .then(songs => console.log(songs))
|
|
151
151
|
* .catch(error => console.error(error));
|
|
152
152
|
*/
|
|
153
|
-
export async function fetchContentInProgress(type="all", brand, {
|
|
154
|
-
page = 1,
|
|
155
|
-
limit = 10,
|
|
156
|
-
} = {}) {
|
|
153
|
+
export async function fetchContentInProgress(type="all", brand, { page, limit } = {}) {
|
|
157
154
|
let url;
|
|
155
|
+
const limitString = limit ? `&limit=${limit}` : '';
|
|
156
|
+
const pageString = page ? `&page=${page}` : '';
|
|
157
|
+
|
|
158
158
|
if(type === "all") {
|
|
159
|
-
url = `/content/in_progress/${globalConfig.railcontentConfig.userId}?brand=${brand}
|
|
159
|
+
url = `/content/in_progress/${globalConfig.railcontentConfig.userId}?brand=${brand}${limitString}${pageString}`;
|
|
160
160
|
} else {
|
|
161
|
-
url = `/content/in_progress/${globalConfig.railcontentConfig.userId}?content_type=${type}&brand=${brand}
|
|
161
|
+
url = `/content/in_progress/${globalConfig.railcontentConfig.userId}?content_type=${type}&brand=${brand}${limitString}${pageString}`;
|
|
162
162
|
}
|
|
163
163
|
const headers = {
|
|
164
164
|
'Content-Type': 'application/json',
|
|
@@ -192,15 +192,15 @@ export async function fetchContentInProgress(type="all", brand, {
|
|
|
192
192
|
* .then(songs => console.log(songs))
|
|
193
193
|
* .catch(error => console.error(error));
|
|
194
194
|
*/
|
|
195
|
-
export async function fetchCompletedContent(type="all", brand, {
|
|
196
|
-
page = 1,
|
|
197
|
-
limit = 10,
|
|
198
|
-
} = {}) {
|
|
195
|
+
export async function fetchCompletedContent(type="all", brand, { page, limit } = {}) {
|
|
199
196
|
let url;
|
|
197
|
+
const limitString = limit ? `&limit=${limit}` : '';
|
|
198
|
+
const pageString = page ? `&page=${page}` : '';
|
|
199
|
+
|
|
200
200
|
if(type === "all") {
|
|
201
|
-
url = `/content/completed/${globalConfig.railcontentConfig.userId}?brand=${brand}
|
|
201
|
+
url = `/content/completed/${globalConfig.railcontentConfig.userId}?brand=${brand}${limitString}${pageString}`;
|
|
202
202
|
} else {
|
|
203
|
-
url = `/content/completed/${globalConfig.railcontentConfig.userId}?content_type=${type}&brand=${brand}
|
|
203
|
+
url = `/content/completed/${globalConfig.railcontentConfig.userId}?content_type=${type}&brand=${brand}${limitString}${pageString}`;
|
|
204
204
|
}
|
|
205
205
|
const headers = {
|
|
206
206
|
'Content-Type': 'application/json',
|