@zengenti/contensis-react-base 3.0.0-beta.78 → 3.0.0-beta.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/cjs/contensis-react-base.js +531 -319
- package/cjs/contensis-react-base.js.map +1 -1
- package/cjs/setCachingHeaders-ee619bdf.js +12 -0
- package/cjs/setCachingHeaders-ee619bdf.js.map +1 -0
- package/cjs/util.js +199 -42
- package/cjs/util.js.map +1 -1
- package/esm/contensis-react-base.js +532 -320
- package/esm/contensis-react-base.js.map +1 -1
- package/esm/setCachingHeaders-d49060e1.js +10 -0
- package/esm/setCachingHeaders-d49060e1.js.map +1 -0
- package/esm/util.js +196 -41
- package/esm/util.js.map +1 -1
- package/models/app/pages/VersionInfo/components/VersionInfo.d.ts +1 -1
- package/models/redux/sagas/navigation.d.ts +1 -1
- package/models/server/features/linkdepth-api/LinkDepthSearchService.d.ts +24 -0
- package/models/server/features/linkdepth-api/QueryLevelResults.d.ts +50 -0
- package/models/server/features/linkdepth-api/search.d.ts +31 -0
- package/models/server/features/linkdepth-api/util.d.ts +11 -0
- package/models/user/hocs/withLogin.d.ts +2 -2
- package/models/user/hocs/withRegistration.d.ts +2 -2
- package/package.json +1 -1
- package/cjs/VersionInfo-4c9dfa6a.js +0 -181
- package/cjs/VersionInfo-4c9dfa6a.js.map +0 -1
- package/esm/VersionInfo-f5403b09.js +0 -172
- package/esm/VersionInfo-f5403b09.js.map +0 -1
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
4
|
|
|
5
|
-
var
|
|
5
|
+
var App = require('./App-80a696bc.js');
|
|
6
|
+
var contensisDeliveryApi = require('contensis-delivery-api');
|
|
6
7
|
var React = require('react');
|
|
7
8
|
var reactRedux = require('react-redux');
|
|
8
9
|
var sagas = require('./sagas-594b5ecd.js');
|
|
@@ -12,8 +13,8 @@ require('deepmerge');
|
|
|
12
13
|
require('query-string');
|
|
13
14
|
require('immer');
|
|
14
15
|
require('deep-equal');
|
|
15
|
-
var
|
|
16
|
-
var
|
|
16
|
+
var contensisCoreApi = require('contensis-core-api');
|
|
17
|
+
var setCachingHeaders = require('./setCachingHeaders-ee619bdf.js');
|
|
17
18
|
require('isomorphic-fetch');
|
|
18
19
|
var express = require('express');
|
|
19
20
|
var httpProxy = require('http-proxy');
|
|
@@ -34,11 +35,10 @@ var reactCookie = require('react-cookie');
|
|
|
34
35
|
var version = require('./version-330551f5.js');
|
|
35
36
|
var actions = require('./actions-8dc9e8de.js');
|
|
36
37
|
var selectors = require('./selectors-656da4b7.js');
|
|
37
|
-
require('
|
|
38
|
+
require('history');
|
|
38
39
|
require('@redux-saga/core/effects');
|
|
39
|
-
require('
|
|
40
|
+
require('loglevel');
|
|
40
41
|
require('./version-eba6d09b.js');
|
|
41
|
-
require('history');
|
|
42
42
|
require('./login-6b9de6a1.js');
|
|
43
43
|
require('./reducers-3a4f8971.js');
|
|
44
44
|
require('./ToJs-a9a8522b.js');
|
|
@@ -62,254 +62,43 @@ var path__default = /*#__PURE__*/_interopDefaultLegacy(path);
|
|
|
62
62
|
var serialize__default = /*#__PURE__*/_interopDefaultLegacy(serialize$1);
|
|
63
63
|
var minifyCssString__default = /*#__PURE__*/_interopDefaultLegacy(minifyCssString);
|
|
64
64
|
|
|
65
|
-
var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
|
|
66
|
-
|
|
67
65
|
/**
|
|
68
|
-
*
|
|
69
|
-
* The api supports a GET request and specified filters are supplied as query-string parameters.
|
|
70
|
-
* The response should be a normal Delivery API response.
|
|
71
|
-
* @param app Express app instance
|
|
72
|
-
* @param middlewareConfig Middleware configuration that represents the content types we want to search within, any filters that are required and any linkFields we wish to search within to derive a set of search results from the entries that contain the linkFields. Each key inside of linkFields represents another "linkDepth" of entries and we can specify all the same contentTypeId, filters, and linkFields of their own. There is no currently no limit on how deep these linkFields can go
|
|
73
|
-
* @returns Returns nothing if uri, contentTypeId or linkFields is not set in middlewareConfig
|
|
66
|
+
* Util class holds our search results helper boilerplate methods
|
|
74
67
|
*/
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
} = middlewareConfig;
|
|
81
|
-
if (!contentTypeId || !linkFields || !uri) return;
|
|
82
|
-
app.get(uri, makeLinkDepthMiddleware(middlewareConfig));
|
|
83
|
-
};
|
|
84
|
-
/** Create a content type hierarchy from supplied config and produces
|
|
85
|
-
* a RequestHandler function to serve our Express middleware */
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
const makeLinkDepthMiddleware = ({
|
|
89
|
-
contentTypeId,
|
|
90
|
-
filters,
|
|
91
|
-
sharedFilters,
|
|
92
|
-
linkFields
|
|
93
|
-
}) => {
|
|
94
|
-
try {
|
|
95
|
-
// Recursive function to flatten and index a provided nested config
|
|
96
|
-
const returnFieldIdKeys = (obj, level = 1) => {
|
|
97
|
-
var _Object$entries$map;
|
|
98
|
-
|
|
99
|
-
if (!obj) return {};
|
|
100
|
-
const mappedConfig = Object.entries(obj).map(([k, v]) => ({
|
|
101
|
-
contentTypeIds: Array.isArray(v.contentTypeId) ? v.contentTypeId : [v.contentTypeId || k],
|
|
102
|
-
fieldId: k,
|
|
103
|
-
filters: v.filters,
|
|
104
|
-
sharedFilters: v.sharedFilters
|
|
105
|
-
}));
|
|
106
|
-
const inner = (_Object$entries$map = Object.entries(obj).map(([k, v]) => returnFieldIdKeys(v.linkFields, level + 1))) === null || _Object$entries$map === void 0 ? void 0 : _Object$entries$map[0];
|
|
107
|
-
return {
|
|
108
|
-
[level]: mappedConfig,
|
|
109
|
-
...inner
|
|
110
|
-
};
|
|
111
|
-
};
|
|
112
|
-
|
|
113
|
-
const others = returnFieldIdKeys(linkFields); // Level 0 is read from the top-level of config
|
|
114
|
-
|
|
115
|
-
const contentTypeHierarchy = {
|
|
116
|
-
0: [{
|
|
117
|
-
contentTypeIds: Array.isArray(contentTypeId) ? contentTypeId : [contentTypeId],
|
|
118
|
-
filters,
|
|
119
|
-
sharedFilters
|
|
120
|
-
}],
|
|
121
|
-
...others
|
|
122
|
-
}; // The runtime express request handler
|
|
123
|
-
|
|
124
|
-
const linkDepthMiddleware = async (req, res) => {
|
|
125
|
-
try {
|
|
126
|
-
// Short cache duration copied from canterbury project
|
|
127
|
-
VersionInfo.setCachingHeaders(res, {
|
|
128
|
-
cacheControl: 'private',
|
|
129
|
-
surrogateControl: '10'
|
|
130
|
-
}); // Run our queries and provide a final result
|
|
131
|
-
// our params are sourced from the query-string
|
|
132
|
-
|
|
133
|
-
const result = await searchEventsTopDown(contentTypeHierarchy, req.query); // const result = await searchLinkDepthEntries(
|
|
134
|
-
// contentTypeHierarchy,
|
|
135
|
-
// req.query
|
|
136
|
-
// );
|
|
68
|
+
class Util {
|
|
69
|
+
static GetIds(entries, fieldId) {
|
|
70
|
+
if (fieldId) {
|
|
71
|
+
return entries === null || entries === void 0 ? void 0 : entries.map(e => {
|
|
72
|
+
var _e$fieldId, _e$fieldId2, _e$fieldId2$sys;
|
|
137
73
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
// This is a runtime error encountered when processing a given request
|
|
141
|
-
console.error(error);
|
|
142
|
-
res.statusCode = 500;
|
|
143
|
-
res.json(error);
|
|
144
|
-
}
|
|
145
|
-
};
|
|
74
|
+
return Array.isArray(e === null || e === void 0 ? void 0 : e[fieldId]) ? e === null || e === void 0 ? void 0 : (_e$fieldId = e[fieldId]) === null || _e$fieldId === void 0 ? void 0 : _e$fieldId.map(f => {
|
|
75
|
+
var _f$sys;
|
|
146
76
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
console.error(error);
|
|
77
|
+
return f === null || f === void 0 ? void 0 : (_f$sys = f.sys) === null || _f$sys === void 0 ? void 0 : _f$sys.id;
|
|
78
|
+
}) : (e === null || e === void 0 ? void 0 : (_e$fieldId2 = e[fieldId]) === null || _e$fieldId2 === void 0 ? void 0 : (_e$fieldId2$sys = _e$fieldId2.sys) === null || _e$fieldId2$sys === void 0 ? void 0 : _e$fieldId2$sys.id) || '';
|
|
79
|
+
}).flat();
|
|
80
|
+
}
|
|
152
81
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
res.json(JSON.stringify(error));
|
|
156
|
-
};
|
|
82
|
+
return entries === null || entries === void 0 ? void 0 : entries.map(e => {
|
|
83
|
+
var _e$sys;
|
|
157
84
|
|
|
158
|
-
|
|
85
|
+
return (e === null || e === void 0 ? void 0 : (_e$sys = e.sys) === null || _e$sys === void 0 ? void 0 : _e$sys.id) || '';
|
|
86
|
+
});
|
|
159
87
|
}
|
|
160
|
-
};
|
|
161
|
-
|
|
162
|
-
const getVarsFromConfig = (config, params) => {
|
|
163
|
-
// Build variables from query config to use in our Delivery API Query
|
|
164
|
-
const contentTypeIds = config.map(c => c.contentTypeIds).flat(); // Filters are the filters we are looking to include with the Query at this level
|
|
165
|
-
|
|
166
|
-
let filters = {}; // Shared filters are filters that share the same querystring key and are valid in multiple levels
|
|
167
|
-
|
|
168
|
-
let sharedFilters = {};
|
|
169
|
-
config.forEach(c => {
|
|
170
|
-
filters = { ...filters,
|
|
171
|
-
...c.filters
|
|
172
|
-
};
|
|
173
|
-
sharedFilters = { ...sharedFilters,
|
|
174
|
-
...c.sharedFilters
|
|
175
|
-
};
|
|
176
|
-
}); // FieldIds are the field name(s) in the parent/current entry that the
|
|
177
|
-
// entries are linked to, used to surface the next level based on id
|
|
178
|
-
// retrieved at the previous level
|
|
179
|
-
|
|
180
|
-
const fieldIds = config.map(c => c.fieldId).flat();
|
|
181
|
-
const queryFilters = makeFilterExpressions(filters, params);
|
|
182
|
-
const sharedQueryFilters = makeFilterExpressions(sharedFilters, params);
|
|
183
|
-
return {
|
|
184
|
-
contentTypeIds,
|
|
185
|
-
fieldIds,
|
|
186
|
-
filters,
|
|
187
|
-
queryFilters,
|
|
188
|
-
sharedFilters,
|
|
189
|
-
sharedQueryFilters
|
|
190
|
-
};
|
|
191
|
-
};
|
|
192
|
-
|
|
193
|
-
const makeDerivedIdsFilterExpression = (level, resultsAtLevel, ownIds = false, useFieldIds = false) => {
|
|
194
|
-
const previouslyDerivedIdsFilter = [];
|
|
195
|
-
const [prevFieldId, entries] = resultsAtLevel[level];
|
|
196
|
-
const prevKey = prevFieldId;
|
|
197
|
-
const prevResultIds = Util.GetIds(entries, useFieldIds ? prevFieldId : undefined);
|
|
198
|
-
if (prevKey && (prevResultIds === null || prevResultIds === void 0 ? void 0 : prevResultIds.length) > 0) previouslyDerivedIdsFilter.push({
|
|
199
|
-
key: ownIds ? 'sys.id' : `${prevFieldId}.sys.id`,
|
|
200
|
-
values: prevResultIds,
|
|
201
|
-
fieldOperator: 'in'
|
|
202
|
-
});else previouslyDerivedIdsFilter.push({
|
|
203
|
-
key: 'dud',
|
|
204
|
-
values: ['1'],
|
|
205
|
-
fieldOperator: 'in'
|
|
206
|
-
});
|
|
207
|
-
return previouslyDerivedIdsFilter;
|
|
208
|
-
};
|
|
209
|
-
|
|
210
|
-
const searchEventsTopDown = async (contentTypeHierarchy, params) => {
|
|
211
|
-
// Determine linkDepth for the final query by how many levels are in
|
|
212
|
-
// the contentTypeHierarchy object
|
|
213
|
-
const linkDepth = Object.keys(contentTypeHierarchy).length - 1 || 0; // Pre-size our results array to the size of our hierarchy
|
|
214
|
-
|
|
215
|
-
const resultsAtLevel = Object.values(contentTypeHierarchy).map((v, i, a) => {
|
|
216
|
-
const fieldId = i === 0 ? a[i + 1][0] : v[0];
|
|
217
|
-
return [fieldId.fieldId, []];
|
|
218
|
-
}); // [fieldId, results][]
|
|
219
88
|
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
const {
|
|
225
|
-
contentTypeIds,
|
|
226
|
-
fieldIds,
|
|
227
|
-
queryFilters,
|
|
228
|
-
sharedQueryFilters
|
|
229
|
-
} = getVarsFromConfig(levelConfig, params); // We won't have fetched any derived results to
|
|
230
|
-
// include as a field filter with the very first query
|
|
231
|
-
|
|
232
|
-
let previouslyDerivedIdsFilter = [];
|
|
89
|
+
static GetItems(result) {
|
|
90
|
+
return this.GetResults(result) ? result.items : [];
|
|
91
|
+
}
|
|
233
92
|
|
|
234
|
-
|
|
235
|
-
|
|
93
|
+
static GetResults(result) {
|
|
94
|
+
if (result !== null && result !== void 0 && result.items) {
|
|
95
|
+
return result;
|
|
96
|
+
} else {
|
|
97
|
+
return null;
|
|
236
98
|
}
|
|
99
|
+
}
|
|
237
100
|
|
|
238
|
-
|
|
239
|
-
contentTypeIds,
|
|
240
|
-
filters: queryFilters,
|
|
241
|
-
idFilters: previouslyDerivedIdsFilter,
|
|
242
|
-
sharedFilters: sharedQueryFilters,
|
|
243
|
-
versionStatus: params.versionStatus || 'published'
|
|
244
|
-
}); // These are all sub-queries, we only want ids returned in these to include
|
|
245
|
-
// them to filter by in our next level(s) queries, along with any other filters
|
|
246
|
-
// configured and found at this level
|
|
247
|
-
|
|
248
|
-
query.fields = currentLevel === 0 ? [] : ['sys.id']; // Scalability limitation for today
|
|
249
|
-
|
|
250
|
-
query.pageSize = 2000;
|
|
251
|
-
const levelQueryResult = await App.cachedSearch.searchUsingPost(query, 0);
|
|
252
|
-
resultsAtLevel[currentLevel][1] = Util.GetItems(levelQueryResult);
|
|
253
|
-
} // Build and run our final query containing all results
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
const {
|
|
257
|
-
contentTypeIds,
|
|
258
|
-
queryFilters,
|
|
259
|
-
sharedQueryFilters
|
|
260
|
-
} = getVarsFromConfig(Object.values(contentTypeHierarchy)[0], params);
|
|
261
|
-
const previouslyDerivedIdsFilter = makeDerivedIdsFilterExpression(1, resultsAtLevel);
|
|
262
|
-
const query = finalQuery({
|
|
263
|
-
contentTypeIds,
|
|
264
|
-
filters: queryFilters,
|
|
265
|
-
idFilters: previouslyDerivedIdsFilter,
|
|
266
|
-
sharedFilters: sharedQueryFilters,
|
|
267
|
-
versionStatus: params.versionStatus || 'published'
|
|
268
|
-
}, Object.entries(contentTypeHierarchy).filter(([k]) => k !== '0').map(([level, levelConfig]) => {
|
|
269
|
-
// LinkDepth level / current index
|
|
270
|
-
const currentLevel = Number(level); // Build variables from query config to use in our Delivery API Query
|
|
271
|
-
|
|
272
|
-
const {
|
|
273
|
-
contentTypeIds,
|
|
274
|
-
queryFilters,
|
|
275
|
-
sharedQueryFilters
|
|
276
|
-
} = getVarsFromConfig(levelConfig, params);
|
|
277
|
-
const previousIdsFilter = makeDerivedIdsFilterExpression(currentLevel, resultsAtLevel, true);
|
|
278
|
-
return {
|
|
279
|
-
contentTypeIds,
|
|
280
|
-
filters: queryFilters,
|
|
281
|
-
idFilters: previousIdsFilter,
|
|
282
|
-
sharedFilters: sharedQueryFilters,
|
|
283
|
-
versionStatus: params.versionStatus || 'published'
|
|
284
|
-
};
|
|
285
|
-
})); // This is the final query to be run and response returned to the caller
|
|
286
|
-
// Only this bit cares about linkDepth, fields and pagination parameters
|
|
287
|
-
|
|
288
|
-
query.fields = JSON.parse(params.fields || '[]');
|
|
289
|
-
query.pageSize = params.pageSize;
|
|
290
|
-
query.pageIndex = params.pageIndex;
|
|
291
|
-
query.orderBy = params.orderBy; // console.log(JSON.stringify(query.toJSON()));
|
|
292
|
-
|
|
293
|
-
const finalQueryResult = await App.cachedSearch.searchUsingPost(query, linkDepth);
|
|
294
|
-
const entriesWithResolvedParents = await resolveParentEntries(contentTypeIds, Array.from(new Set(resultsAtLevel[1][1].map(e => e.sys.contentTypeId || ''))), resultsAtLevel[0][0], Util.GetItems(finalQueryResult), params);
|
|
295
|
-
return { ...finalQueryResult,
|
|
296
|
-
items: entriesWithResolvedParents
|
|
297
|
-
};
|
|
298
|
-
};
|
|
299
|
-
|
|
300
|
-
const resolveParentEntries = async (parentContentTypeIds, replaceContentTypeIds, parentFieldId, results, params) => {
|
|
301
|
-
// Build variables from query config to use in our Delivery API Query
|
|
302
|
-
const previousIdsFilter = makeDerivedIdsFilterExpression(0, [[parentFieldId, results]]);
|
|
303
|
-
const query = searchQuery({
|
|
304
|
-
contentTypeIds: parentContentTypeIds,
|
|
305
|
-
idFilters: previousIdsFilter
|
|
306
|
-
});
|
|
307
|
-
query.fields = JSON.parse(params.fields || '[]');
|
|
308
|
-
console.log(JSON.stringify(query.toJSON()));
|
|
309
|
-
const parentResults = await App.cachedSearch.search(query, 0);
|
|
310
|
-
return mergeResults(results, Util.GetItems(parentResults), replaceContentTypeIds, parentFieldId);
|
|
311
|
-
};
|
|
312
|
-
|
|
101
|
+
}
|
|
313
102
|
const mergeResults = (results, parentResults, replaceContentTypeIds, linkFieldId) => results.map(r => {
|
|
314
103
|
if (replaceContentTypeIds.some(c => c === r.sys.contentTypeId)) {
|
|
315
104
|
const resolvedParent = parentResults === null || parentResults === void 0 ? void 0 : parentResults.find(e => {
|
|
@@ -333,30 +122,32 @@ const mergeResults = (results, parentResults, replaceContentTypeIds, linkFieldId
|
|
|
333
122
|
return r;
|
|
334
123
|
}).filter(r => r);
|
|
335
124
|
|
|
336
|
-
|
|
125
|
+
/* eslint-disable no-console */
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Builds our complete Delivery API Query object from a set of provided arguments
|
|
129
|
+
* @param queryParams
|
|
130
|
+
* @returns Delivery API Query
|
|
131
|
+
*/
|
|
132
|
+
const searchQuery = ({
|
|
337
133
|
assetTypes,
|
|
338
134
|
contentTypeIds,
|
|
135
|
+
customWhere,
|
|
339
136
|
fields,
|
|
340
137
|
filters,
|
|
341
|
-
idFilters,
|
|
342
|
-
sharedFilters,
|
|
138
|
+
idFilters = [],
|
|
139
|
+
sharedFilters = [],
|
|
343
140
|
pageSize,
|
|
344
|
-
pageIndex,
|
|
141
|
+
pageIndex = 0,
|
|
345
142
|
orderBy,
|
|
346
143
|
searchTerm,
|
|
347
144
|
versionStatus = 'published',
|
|
348
145
|
webpageTemplates,
|
|
349
146
|
weightedSearchFields
|
|
350
|
-
}
|
|
351
|
-
const expressions$1 = [...sagas.defaultExpressions(versionStatus),
|
|
352
|
-
// ...sharedFilters.map(sf =>
|
|
353
|
-
// Op.not(exp.fieldExpression(sf.key, true, 'exists')[0])
|
|
354
|
-
// ),
|
|
355
|
-
// ...exp.filterExpressions(idFilters)
|
|
356
|
-
// )
|
|
357
|
-
)), ...children.map(child => contensisCoreApi.Op.and(...sagas.contentTypeIdExpression(child.contentTypeIds, child.webpageTemplates, child.assetTypes), ...sagas.filterExpressions(child.sharedFilters), ...sagas.filterExpressions(child.idFilters)))), ...sagas.termExpressions(searchTerm, weightedSearchFields)];
|
|
147
|
+
}) => {
|
|
148
|
+
const expressions$1 = [...sagas.defaultExpressions(versionStatus), ...sagas.contentTypeIdExpression(contentTypeIds, webpageTemplates, assetTypes), ...sagas.customWhereExpressions(customWhere), ...sagas.filterExpressions(filters), ...sagas.filterExpressions(idFilters), ...((sharedFilters === null || sharedFilters === void 0 ? void 0 : sharedFilters.length) > 0 ? [contensisCoreApi.Op.or(...sagas.filterExpressions(sharedFilters, true))] : []), ...sagas.termExpressions(searchTerm || '', weightedSearchFields || [])];
|
|
358
149
|
const query = new contensisCoreApi.Query(...expressions$1);
|
|
359
|
-
query.orderBy = sagas.orderByExpression(orderBy);
|
|
150
|
+
query.orderBy = sagas.orderByExpression(orderBy || []);
|
|
360
151
|
|
|
361
152
|
if (fields && fields.length > 0) {
|
|
362
153
|
query.fields = fields;
|
|
@@ -368,38 +159,12 @@ const finalQuery = ({
|
|
|
368
159
|
query.pageSize = pageSize;
|
|
369
160
|
return query;
|
|
370
161
|
};
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
* @param f filters configuration from any level
|
|
376
|
-
* @param params request.query object from Express middleware
|
|
377
|
-
* @returns FilterExpression[] we can use to use with searchQuery function
|
|
378
|
-
*/
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
const makeFilterExpressions = (f, params) => Object.entries(f).map(([paramKey, filterConfig]) => {
|
|
382
|
-
var _params$paramKey;
|
|
383
|
-
|
|
384
|
-
const filterValues = (_params$paramKey = params[paramKey]) === null || _params$paramKey === void 0 ? void 0 : _params$paramKey.split(',');
|
|
385
|
-
return typeof filterValues !== 'undefined' ? {
|
|
386
|
-
key: typeof filterConfig === 'object' ? filterConfig.fieldId : filterConfig,
|
|
387
|
-
values: filterValues,
|
|
388
|
-
fieldOperator: typeof filterConfig === 'object' ? filterConfig.fieldOperator : 'equalTo',
|
|
389
|
-
logicOperator: typeof filterConfig === 'object' ? filterConfig.logicOperator : 'or'
|
|
390
|
-
} : null;
|
|
391
|
-
}).filter(o => o);
|
|
392
|
-
/**
|
|
393
|
-
* Builds our complete Delivery API Query object from a set of provided arguments
|
|
394
|
-
* @param queryParams
|
|
395
|
-
* @returns Delivery API Query
|
|
396
|
-
*/
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
const searchQuery = ({
|
|
162
|
+
const appendSearchQueryFilters = (query, idFilters) => {
|
|
163
|
+
query.where.addRange(sagas.filterExpressions(idFilters));
|
|
164
|
+
};
|
|
165
|
+
const finalQuery = ({
|
|
400
166
|
assetTypes,
|
|
401
167
|
contentTypeIds,
|
|
402
|
-
customWhere,
|
|
403
168
|
fields,
|
|
404
169
|
filters,
|
|
405
170
|
idFilters,
|
|
@@ -411,10 +176,16 @@ const searchQuery = ({
|
|
|
411
176
|
versionStatus = 'published',
|
|
412
177
|
webpageTemplates,
|
|
413
178
|
weightedSearchFields
|
|
414
|
-
}) => {
|
|
415
|
-
const expressions$1 = [...sagas.defaultExpressions(versionStatus), ...sagas.contentTypeIdExpression(contentTypeIds, webpageTemplates, assetTypes), ...sagas.
|
|
179
|
+
}, children) => {
|
|
180
|
+
const expressions$1 = [...sagas.defaultExpressions(versionStatus), contensisCoreApi.Op.or(contensisCoreApi.Op.and(...sagas.contentTypeIdExpression(contentTypeIds, webpageTemplates, assetTypes), ...sagas.filterExpressions(filters), ...sagas.filterExpressions(idFilters || []), ...(sharedFilters !== null && sharedFilters !== void 0 && sharedFilters.length ? [contensisCoreApi.Op.or(...sagas.filterExpressions(sharedFilters || []) // Op.and(
|
|
181
|
+
// ...sharedFilters.map(sf =>
|
|
182
|
+
// Op.not(exp.fieldExpression(sf.key, true, 'exists')[0])
|
|
183
|
+
// ),
|
|
184
|
+
// ...exp.filterExpressions(idFilters)
|
|
185
|
+
// )
|
|
186
|
+
)] : [])), ...children.map(child => contensisCoreApi.Op.and(...sagas.contentTypeIdExpression(child.contentTypeIds, child.webpageTemplates, child.assetTypes), ...sagas.filterExpressions(child.sharedFilters || []), ...sagas.filterExpressions(child.idFilters || [])))), ...sagas.termExpressions(searchTerm || '', weightedSearchFields || [])];
|
|
416
187
|
const query = new contensisCoreApi.Query(...expressions$1);
|
|
417
|
-
query.orderBy = sagas.orderByExpression(orderBy);
|
|
188
|
+
query.orderBy = sagas.orderByExpression(orderBy || []);
|
|
418
189
|
|
|
419
190
|
if (fields && fields.length > 0) {
|
|
420
191
|
query.fields = fields;
|
|
@@ -422,50 +193,489 @@ const searchQuery = ({
|
|
|
422
193
|
// (query as any).includeDeleted = true;
|
|
423
194
|
|
|
424
195
|
|
|
425
|
-
query.pageIndex = pageIndex;
|
|
196
|
+
query.pageIndex = pageIndex || 0;
|
|
426
197
|
query.pageSize = pageSize;
|
|
427
198
|
return query;
|
|
428
199
|
};
|
|
429
200
|
/**
|
|
430
|
-
*
|
|
201
|
+
* Create a filter expression from a provided filters configuration object
|
|
202
|
+
* and populate them based on the presence of that key in params, filter
|
|
203
|
+
* out any filter keys that do not have a value set in params
|
|
204
|
+
* @param f filters configuration from any level
|
|
205
|
+
* @param params request.query object from Express middleware
|
|
206
|
+
* @returns FilterExpression[] we can use to use with searchQuery function
|
|
431
207
|
*/
|
|
432
208
|
|
|
209
|
+
const makeFilterExpressions = (f, params) => {
|
|
210
|
+
const expressions = [];
|
|
433
211
|
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
if (fieldId) {
|
|
437
|
-
return entries.map(e => {
|
|
438
|
-
var _e$fieldId, _e$fieldId2, _e$fieldId2$sys;
|
|
212
|
+
for (const [paramKey, filterConfig] of Object.entries(f)) {
|
|
213
|
+
var _params$paramKey;
|
|
439
214
|
|
|
440
|
-
|
|
441
|
-
|
|
215
|
+
const filterValues = (_params$paramKey = params[paramKey]) === null || _params$paramKey === void 0 ? void 0 : _params$paramKey.split(',');
|
|
216
|
+
if (typeof filterValues !== 'undefined') expressions.push({
|
|
217
|
+
key: typeof filterConfig === 'object' ? filterConfig.fieldId : filterConfig,
|
|
218
|
+
values: filterValues,
|
|
219
|
+
fieldOperator: typeof filterConfig === 'object' && filterConfig.fieldOperator ? filterConfig.fieldOperator : 'equalTo',
|
|
220
|
+
logicOperator: typeof filterConfig === 'object' && filterConfig.logicOperator ? filterConfig.logicOperator : 'or'
|
|
221
|
+
});
|
|
222
|
+
}
|
|
442
223
|
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
224
|
+
return expressions;
|
|
225
|
+
};
|
|
226
|
+
const makeDerivedIdsFilterExpression = (prevFieldId, entries, ownIds = false, alwaysApplyFilter = false) => {
|
|
227
|
+
const previouslyDerivedIdsFilter = [];
|
|
228
|
+
const prevResultIds = Util.GetIds(entries);
|
|
229
|
+
if (prevFieldId && (prevResultIds === null || prevResultIds === void 0 ? void 0 : prevResultIds.length) > 0) previouslyDerivedIdsFilter.push({
|
|
230
|
+
key: ownIds ? 'sys.id' : `${prevFieldId}.sys.id`,
|
|
231
|
+
values: prevResultIds,
|
|
232
|
+
fieldOperator: 'in',
|
|
233
|
+
logicOperator: 'or'
|
|
234
|
+
});else if (alwaysApplyFilter) previouslyDerivedIdsFilter.push({
|
|
235
|
+
key: 'intended-dud',
|
|
236
|
+
values: ['1'],
|
|
237
|
+
fieldOperator: 'in',
|
|
238
|
+
logicOperator: 'or'
|
|
239
|
+
});
|
|
240
|
+
return previouslyDerivedIdsFilter;
|
|
241
|
+
};
|
|
242
|
+
const resolveParentEntries = async (parentContentTypeIds, replaceContentTypeIds, parentFieldId, results, params, debug) => {
|
|
243
|
+
// Build variables from query config to use in our Delivery API Query
|
|
244
|
+
const previousIdsFilter = makeDerivedIdsFilterExpression(parentFieldId, results);
|
|
245
|
+
const query = searchQuery({
|
|
246
|
+
contentTypeIds: parentContentTypeIds,
|
|
247
|
+
idFilters: previousIdsFilter
|
|
248
|
+
});
|
|
249
|
+
query.fields = params.fields ? [...JSON.parse(params.fields), parentFieldId] : [];
|
|
250
|
+
if (debug) console.log(`\nResolve parent entries query: \n${JSON.stringify(query.toJSON()).substring(0, 1000)}`);
|
|
251
|
+
const parentResults = await App.cachedSearch.searchUsingPost(query, Number(params.linkDepth || 0), params.projectId);
|
|
252
|
+
return mergeResults(results, Util.GetItems(parentResults), replaceContentTypeIds, parentFieldId);
|
|
253
|
+
};
|
|
447
254
|
|
|
448
|
-
|
|
449
|
-
var _e$sys;
|
|
255
|
+
/* eslint-disable no-console */
|
|
450
256
|
|
|
451
|
-
|
|
257
|
+
class QueryLevelResults {
|
|
258
|
+
constructor({
|
|
259
|
+
level: _level,
|
|
260
|
+
contentTypeIds,
|
|
261
|
+
linkFields,
|
|
262
|
+
filters,
|
|
263
|
+
sharedFilters,
|
|
264
|
+
returnEntries,
|
|
265
|
+
resolveFirstParent,
|
|
266
|
+
params: _params = {},
|
|
267
|
+
parent: _parent,
|
|
268
|
+
debug = false
|
|
269
|
+
}) {
|
|
270
|
+
this.level = void 0;
|
|
271
|
+
this.contentTypeIds = void 0;
|
|
272
|
+
this.linkFieldIds = void 0;
|
|
273
|
+
this.linkFields = void 0;
|
|
274
|
+
this.filters = void 0;
|
|
275
|
+
this.sharedFilters = void 0;
|
|
276
|
+
this.returnEntries = void 0;
|
|
277
|
+
this.resolveFirstParent = void 0;
|
|
278
|
+
this.validatedLinks = [];
|
|
279
|
+
this.parent = void 0;
|
|
280
|
+
this.children = [];
|
|
281
|
+
this.runFirstQuery = void 0;
|
|
282
|
+
this.runFinalQuery = void 0;
|
|
283
|
+
this.params = {};
|
|
284
|
+
this.debug = void 0;
|
|
285
|
+
this.firstQuery = new contensisDeliveryApi.Query();
|
|
286
|
+
this.firstResults = {};
|
|
287
|
+
this.finalQuery = new contensisDeliveryApi.Query();
|
|
288
|
+
this.finalResults = {};
|
|
289
|
+
|
|
290
|
+
this.AddChild = ({
|
|
291
|
+
child
|
|
292
|
+
}) => {
|
|
293
|
+
this.children.push(child);
|
|
294
|
+
};
|
|
295
|
+
|
|
296
|
+
this.RunFirstQuery = async () => {
|
|
297
|
+
const {
|
|
298
|
+
firstQuery: query,
|
|
299
|
+
params,
|
|
300
|
+
parent,
|
|
301
|
+
runFirstQuery
|
|
302
|
+
} = this;
|
|
303
|
+
|
|
304
|
+
if (parent !== null && parent !== void 0 && parent.validatedLinks.length) {
|
|
305
|
+
// add any idFilters derived from parent query results
|
|
306
|
+
appendSearchQueryFilters(query, makeFilterExpressions(Object.fromEntries(parent.validatedLinks.map(vl => [vl.linkFieldId, {
|
|
307
|
+
fieldId: `sys.id`
|
|
308
|
+
}])), Object.fromEntries(parent.validatedLinks.map(vl => [vl.linkFieldId, vl.entryIds.join(',') || `no ids from parent ${parent.level}`]))));
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
if (runFirstQuery) {
|
|
312
|
+
if (this.debug) console.log(`\nLevel ${this.level} - First query: \n${JSON.stringify(query.toJSON()).substring(0, 1000)}`);
|
|
313
|
+
this.firstResults = await App.cachedSearch.searchUsingPost(query, 0, params.projectId); // mapResultsToValidatedLinks
|
|
314
|
+
|
|
315
|
+
for (const linkFieldId of this.linkFieldIds) {
|
|
316
|
+
this.validatedLinks.push({
|
|
317
|
+
contentTypeId: this.linkFields[linkFieldId].contentTypeId || '',
|
|
318
|
+
linkFieldId,
|
|
319
|
+
entryIds: Util.GetIds(this.firstResults.items, linkFieldId)
|
|
320
|
+
});
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
};
|
|
324
|
+
|
|
325
|
+
this.RunFinalQuery = async () => {
|
|
326
|
+
const {
|
|
327
|
+
level,
|
|
328
|
+
children,
|
|
329
|
+
finalQuery: query,
|
|
330
|
+
params,
|
|
331
|
+
runFinalQuery
|
|
332
|
+
} = this;
|
|
333
|
+
|
|
334
|
+
if (!children.some(c => c.returnEntries)) {
|
|
335
|
+
const firstChild = children === null || children === void 0 ? void 0 : children[0]; // add any idFilters derived from child query results
|
|
336
|
+
|
|
337
|
+
if (firstChild) appendSearchQueryFilters(query, makeFilterExpressions(Object.fromEntries(firstChild.validatedLinks.map(vl => [vl.linkFieldId, {
|
|
338
|
+
fieldId: `${vl.linkFieldId}.sys.id`
|
|
339
|
+
}])), Object.fromEntries(firstChild.validatedLinks.map(vl => [vl.linkFieldId, vl.entryIds.join(',') || `no ids from child ${firstChild.level}`]))));
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
if (level === 0 && this.returnEntries) {
|
|
343
|
+
// This is the final query to be run and response returned to the caller
|
|
344
|
+
// Only this bit cares about linkDepth, fields and pagination parameters
|
|
345
|
+
query.fields = JSON.parse(params.fields || '[]');
|
|
346
|
+
query.pageSize = params.pageSize;
|
|
347
|
+
query.pageIndex = params.pageIndex; // query.orderBy = params.orderBy;
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
if (runFinalQuery) {
|
|
351
|
+
if (this.debug) console.log(`\nLevel ${this.level} - Final query: \n${JSON.stringify(query.toJSON()).substring(0, 1000)}`);
|
|
352
|
+
this.finalResults = await App.cachedSearch.searchUsingPost(query, Number(params.linkDepth) || 0, params.projectId);
|
|
353
|
+
if (this.parent) this.parent.runFinalQuery = true; // mapResultsToValidatedLinks
|
|
354
|
+
|
|
355
|
+
for (const linkFieldId of ((_this$parent = this.parent) === null || _this$parent === void 0 ? void 0 : _this$parent.linkFieldIds) || []) {
|
|
356
|
+
var _this$parent, _this$parent2;
|
|
357
|
+
|
|
358
|
+
this.validatedLinks.push({
|
|
359
|
+
contentTypeId: ((_this$parent2 = this.parent) === null || _this$parent2 === void 0 ? void 0 : _this$parent2.linkFields[linkFieldId].contentTypeId) || '',
|
|
360
|
+
linkFieldId,
|
|
361
|
+
entryIds: Util.GetIds(this.finalResults.items)
|
|
362
|
+
});
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
};
|
|
366
|
+
|
|
367
|
+
this.GetResultsEntries = () => {
|
|
368
|
+
var _finalResults$items;
|
|
369
|
+
|
|
370
|
+
const {
|
|
371
|
+
finalResults,
|
|
372
|
+
firstResults
|
|
373
|
+
} = this;
|
|
374
|
+
return finalResults !== null && finalResults !== void 0 && (_finalResults$items = finalResults.items) !== null && _finalResults$items !== void 0 && _finalResults$items.length ? finalResults.items : firstResults.items;
|
|
375
|
+
};
|
|
376
|
+
|
|
377
|
+
this.GetResults = () => {
|
|
378
|
+
const {
|
|
379
|
+
finalResults,
|
|
380
|
+
firstResults
|
|
381
|
+
} = this;
|
|
382
|
+
return typeof (finalResults === null || finalResults === void 0 ? void 0 : finalResults.totalCount) !== 'undefined' ? finalResults : firstResults;
|
|
383
|
+
};
|
|
384
|
+
|
|
385
|
+
this.level = _level;
|
|
386
|
+
this.contentTypeIds = contentTypeIds;
|
|
387
|
+
this.linkFields = linkFields;
|
|
388
|
+
this.linkFieldIds = Object.keys(linkFields).map(fId => fId);
|
|
389
|
+
this.filters = filters;
|
|
390
|
+
this.sharedFilters = sharedFilters;
|
|
391
|
+
this.returnEntries = typeof returnEntries === 'undefined' ? _level === 0 : returnEntries;
|
|
392
|
+
this.resolveFirstParent = resolveFirstParent || false;
|
|
393
|
+
this.params = _params;
|
|
394
|
+
this.parent = _parent;
|
|
395
|
+
this.debug = debug;
|
|
396
|
+
this.runFirstQuery = Object.keys(_params).some(p => Object.keys(filters).includes(p) || Object.keys(sharedFilters).includes(p));
|
|
397
|
+
this.runFinalQuery = Object.keys(_params).some(p => Object.keys(filters).includes(p) || Object.keys(sharedFilters).includes(p));
|
|
398
|
+
this.firstQuery = searchQuery({
|
|
399
|
+
contentTypeIds,
|
|
400
|
+
filters: makeFilterExpressions(filters, _params),
|
|
401
|
+
sharedFilters: makeFilterExpressions(sharedFilters, _params),
|
|
402
|
+
// idFilters: parent?.validatedLinks
|
|
403
|
+
// ? makeFilterExpressions(parent.validatedLinks, params)
|
|
404
|
+
// : [], // these dont exist yet
|
|
405
|
+
fields: ['sys.id', ...this.linkFieldIds],
|
|
406
|
+
pageSize: 2000,
|
|
407
|
+
searchTerm: _params.term,
|
|
408
|
+
versionStatus: _params.versionStatus
|
|
409
|
+
});
|
|
410
|
+
this.finalQuery = searchQuery({
|
|
411
|
+
contentTypeIds,
|
|
412
|
+
filters: makeFilterExpressions(filters, _params),
|
|
413
|
+
sharedFilters: makeFilterExpressions(sharedFilters, _params),
|
|
414
|
+
fields: JSON.parse(_params.fields || '[]'),
|
|
415
|
+
pageIndex: _level === 0 ? Number(_params.pageIndex) : 0,
|
|
416
|
+
pageSize: _level === 0 ? Number(_params.pageSize) : 2000,
|
|
417
|
+
searchTerm: _params.term,
|
|
418
|
+
versionStatus: _params.versionStatus
|
|
452
419
|
});
|
|
453
420
|
}
|
|
454
421
|
|
|
455
|
-
|
|
456
|
-
return this.GetResults(result) ? result.items : [];
|
|
457
|
-
}
|
|
422
|
+
}
|
|
458
423
|
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
}
|
|
424
|
+
/* eslint-disable no-console */
|
|
425
|
+
|
|
426
|
+
class LinkDepthSearchService {
|
|
427
|
+
constructor({
|
|
428
|
+
contentTypeId: _contentTypeId = '',
|
|
429
|
+
filters: _filters = {},
|
|
430
|
+
sharedFilters: _sharedFilters = {},
|
|
431
|
+
linkFields: _linkFields = {},
|
|
432
|
+
params: _params,
|
|
433
|
+
debug = false
|
|
434
|
+
}) {
|
|
435
|
+
this.contentTypeIds = void 0;
|
|
436
|
+
this.filters = void 0;
|
|
437
|
+
this.sharedFilters = void 0;
|
|
438
|
+
this.linkFields = void 0;
|
|
439
|
+
this.params = void 0;
|
|
440
|
+
this.debug = void 0;
|
|
441
|
+
this.queryLevels = void 0;
|
|
442
|
+
|
|
443
|
+
this.DoSearch = async () => {
|
|
444
|
+
// Run queries "top-down" through each level of `linkField`
|
|
445
|
+
for (const queryLevel of this.queryLevels) {
|
|
446
|
+
await queryLevel.RunFirstQuery();
|
|
447
|
+
} // Run queries "bottom-up" through each level of `linkField`
|
|
448
|
+
|
|
449
|
+
|
|
450
|
+
for (const queryLevel of [...this.queryLevels].reverse()) {
|
|
451
|
+
await queryLevel.RunFinalQuery();
|
|
452
|
+
} // Run a final query that will aggregate the results from all levels
|
|
453
|
+
// adding all levels to the query that have `returnEntries` set true
|
|
454
|
+
|
|
455
|
+
|
|
456
|
+
return await this.RunFinalQueries();
|
|
457
|
+
};
|
|
458
|
+
|
|
459
|
+
this.RunFinalQueries = async () => {
|
|
460
|
+
const finalQueryLevels = this.queryLevels.filter(ql => ql.level > 0 && ql.returnEntries || ql.level === 0 && ql.returnEntries !== false); // Decide if we need a further final query if any child level(s) have had `returnEntries` set to true
|
|
461
|
+
|
|
462
|
+
if (finalQueryLevels.length > 1 || finalQueryLevels.length === 1 && finalQueryLevels[0].level !== 0) {
|
|
463
|
+
var _params$orderBy;
|
|
464
|
+
|
|
465
|
+
// Build final query
|
|
466
|
+
const {
|
|
467
|
+
contentTypeIds,
|
|
468
|
+
filters,
|
|
469
|
+
sharedFilters,
|
|
470
|
+
params
|
|
471
|
+
} = this;
|
|
472
|
+
const derivedIds = finalQueryLevels[0].children.filter(ql => !ql.returnEntries).map(ql => ql.validatedLinks).flat() || [];
|
|
473
|
+
const derivedIdFilters = derivedIds.map(vl => makeFilterExpressions({
|
|
474
|
+
[vl.linkFieldId]: {
|
|
475
|
+
fieldId: `${vl.linkFieldId}.sys.id`
|
|
476
|
+
}
|
|
477
|
+
}, {
|
|
478
|
+
[vl.linkFieldId]: vl.entryIds.join(',') || 'no results for filter'
|
|
479
|
+
})).flat() || []; // This is the final query to be run and response returned to the caller
|
|
480
|
+
// Only this bit cares about linkDepth, fields and pagination parameters
|
|
481
|
+
|
|
482
|
+
const query = finalQuery({
|
|
483
|
+
contentTypeIds,
|
|
484
|
+
filters: makeFilterExpressions(filters, params),
|
|
485
|
+
sharedFilters: makeFilterExpressions(sharedFilters, params),
|
|
486
|
+
idFilters: derivedIdFilters,
|
|
487
|
+
fields: params.fields ? [...JSON.parse(params.fields), ...finalQueryLevels.map(l => {
|
|
488
|
+
var _l$parent;
|
|
489
|
+
|
|
490
|
+
return ((_l$parent = l.parent) === null || _l$parent === void 0 ? void 0 : _l$parent.linkFieldIds) || [];
|
|
491
|
+
}).flat()] : [],
|
|
492
|
+
orderBy: (_params$orderBy = params.orderBy) === null || _params$orderBy === void 0 ? void 0 : _params$orderBy.split(','),
|
|
493
|
+
pageIndex: Number(params.pageIndex) || 0,
|
|
494
|
+
pageSize: typeof Number(params.pageSize) === 'number' ? Number(params.pageSize) : 25,
|
|
495
|
+
searchTerm: params.term,
|
|
496
|
+
versionStatus: params.versionStatus
|
|
497
|
+
}, (finalQueryLevels === null || finalQueryLevels === void 0 ? void 0 : finalQueryLevels[0].children.filter(ql => ql.returnEntries).map(ql => {
|
|
498
|
+
var _ql$parent, _ql$parent2;
|
|
499
|
+
|
|
500
|
+
const entriesAtLevel = ql.GetResultsEntries() || ((_ql$parent = ql.parent) === null || _ql$parent === void 0 ? void 0 : _ql$parent.GetResultsEntries());
|
|
501
|
+
const previousIdsFilter = ql.returnEntries || !!ql.children.some(qc => qc.returnEntries) ? (_ql$parent2 = ql.parent) === null || _ql$parent2 === void 0 ? void 0 : _ql$parent2.linkFieldIds.map(fieldId => makeDerivedIdsFilterExpression(fieldId, entriesAtLevel, true, ql.runFinalQuery)).flat() : [];
|
|
502
|
+
return {
|
|
503
|
+
contentTypeIds: ql.contentTypeIds,
|
|
504
|
+
filters: makeFilterExpressions(ql.filters, params),
|
|
505
|
+
sharedFilters: makeFilterExpressions(ql.sharedFilters, params),
|
|
506
|
+
idFilters: previousIdsFilter
|
|
507
|
+
};
|
|
508
|
+
})) || []);
|
|
509
|
+
if (this.debug) console.log(`\nFinal query: ${derivedIds.reduce((accumulator, object) => accumulator + object.entryIds.length, 0)} derived ids \n${JSON.stringify(query.toJSON()).substring(0, 1000)}`);
|
|
510
|
+
const finalQueryResult = await App.cachedSearch.searchUsingPost(query, Number(params.linkDepth) || 0, params.projectId); // Resolve any parent entries
|
|
511
|
+
|
|
512
|
+
const resolveParentLevels = finalQueryLevels.filter(ql => ql.resolveFirstParent);
|
|
513
|
+
let entries = finalQueryResult.items;
|
|
514
|
+
|
|
515
|
+
for (const resolveParents of resolveParentLevels) {
|
|
516
|
+
var _resolveParents$paren, _resolveParents$paren2;
|
|
517
|
+
|
|
518
|
+
entries = await resolveParentEntries(((_resolveParents$paren = resolveParents.parent) === null || _resolveParents$paren === void 0 ? void 0 : _resolveParents$paren.contentTypeIds) || [], resolveParents.contentTypeIds, ((_resolveParents$paren2 = resolveParents.parent) === null || _resolveParents$paren2 === void 0 ? void 0 : _resolveParents$paren2.linkFieldIds[0]) || 'unknown', finalQueryResult.items, // or entries?
|
|
519
|
+
this.params, this.debug);
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
return { ...finalQueryResult,
|
|
523
|
+
items: entries
|
|
524
|
+
};
|
|
525
|
+
} else {
|
|
526
|
+
var _this$queryLevels$fin;
|
|
527
|
+
|
|
528
|
+
if (this.debug) console.log(`\nNo further queries required\n`);
|
|
529
|
+
return (_this$queryLevels$fin = this.queryLevels.find(ql => ql.level === 0)) === null || _this$queryLevels$fin === void 0 ? void 0 : _this$queryLevels$fin.GetResults();
|
|
530
|
+
}
|
|
531
|
+
};
|
|
532
|
+
|
|
533
|
+
this.InitQueryLevels = () => {
|
|
534
|
+
const createChildQueryLevels = (linkFields, parentQueryLevel, level = 1) => {
|
|
535
|
+
return Object.entries(linkFields).map(([, {
|
|
536
|
+
contentTypeId = '',
|
|
537
|
+
filters = {},
|
|
538
|
+
linkFields = {},
|
|
539
|
+
resolveFirstParent,
|
|
540
|
+
returnEntries,
|
|
541
|
+
sharedFilters = {}
|
|
542
|
+
}]) => {
|
|
543
|
+
const thisLevel = new QueryLevelResults({
|
|
544
|
+
level,
|
|
545
|
+
contentTypeIds: Array.isArray(contentTypeId) ? contentTypeId : [contentTypeId],
|
|
546
|
+
filters: Object.fromEntries(Object.entries(filters).map(([fKey, fVal]) => [fKey, typeof fVal === 'string' ? {
|
|
547
|
+
fieldId: fVal
|
|
548
|
+
} : fVal])),
|
|
549
|
+
sharedFilters: Object.fromEntries(Object.entries(sharedFilters).map(([fKey, fVal]) => [fKey, typeof fVal === 'string' ? {
|
|
550
|
+
fieldId: fVal
|
|
551
|
+
} : fVal])),
|
|
552
|
+
linkFields,
|
|
553
|
+
parent: parentQueryLevel,
|
|
554
|
+
params,
|
|
555
|
+
resolveFirstParent,
|
|
556
|
+
returnEntries,
|
|
557
|
+
debug: this.debug
|
|
558
|
+
});
|
|
559
|
+
parentQueryLevel.AddChild({
|
|
560
|
+
child: thisLevel
|
|
561
|
+
});
|
|
562
|
+
return [thisLevel, ...createChildQueryLevels(linkFields, thisLevel, level + 1)];
|
|
563
|
+
}).flat();
|
|
564
|
+
};
|
|
565
|
+
|
|
566
|
+
const {
|
|
567
|
+
contentTypeIds,
|
|
568
|
+
filters,
|
|
569
|
+
sharedFilters,
|
|
570
|
+
linkFields,
|
|
571
|
+
params
|
|
572
|
+
} = this;
|
|
573
|
+
const firstLevel = new QueryLevelResults({
|
|
574
|
+
level: 0,
|
|
575
|
+
contentTypeIds,
|
|
576
|
+
filters: Object.fromEntries(Object.entries(filters).map(([fKey, fVal]) => [fKey, typeof fVal === 'string' ? {
|
|
577
|
+
fieldId: fVal
|
|
578
|
+
} : fVal])),
|
|
579
|
+
sharedFilters: Object.fromEntries(Object.entries(sharedFilters).map(([fKey, fVal]) => [fKey, typeof fVal === 'string' ? {
|
|
580
|
+
fieldId: fVal
|
|
581
|
+
} : fVal])),
|
|
582
|
+
linkFields,
|
|
583
|
+
params,
|
|
584
|
+
debug: this.debug
|
|
585
|
+
});
|
|
586
|
+
const queryLevels = [firstLevel, ...createChildQueryLevels(linkFields, firstLevel)]; // return queryLevels;
|
|
587
|
+
// If we are only returning entries from level 0
|
|
588
|
+
// we can skip running the first query and finalQuery will suffice
|
|
589
|
+
|
|
590
|
+
if (queryLevels.find(ql => ql.returnEntries && ql.level !== 0)) return queryLevels;else return queryLevels.map(ql => {
|
|
591
|
+
ql.runFirstQuery = false; // ql.runFinalQuery = false;
|
|
592
|
+
|
|
593
|
+
return ql;
|
|
594
|
+
});
|
|
595
|
+
};
|
|
596
|
+
|
|
597
|
+
this.contentTypeIds = Array.isArray(_contentTypeId) ? _contentTypeId : [_contentTypeId];
|
|
598
|
+
this.filters = _filters;
|
|
599
|
+
this.sharedFilters = _sharedFilters;
|
|
600
|
+
this.linkFields = _linkFields;
|
|
601
|
+
this.params = _params;
|
|
602
|
+
this.debug = debug;
|
|
603
|
+
this.queryLevels = this.InitQueryLevels();
|
|
465
604
|
}
|
|
466
605
|
|
|
467
606
|
}
|
|
468
607
|
|
|
608
|
+
/**
|
|
609
|
+
* Make a LinkDepth api at the uri specified in middlewareConfig.
|
|
610
|
+
* The api supports a GET request and specified filters are supplied as query-string parameters.
|
|
611
|
+
* The response should be a normal Delivery API response.
|
|
612
|
+
* @param app Express app instance
|
|
613
|
+
* @param middlewareConfig Middleware configuration that represents the content types we want to search within, any filters that are required and any linkFields we wish to search within to derive a set of search results from the entries that contain the linkFields. Each key inside of linkFields represents another "linkDepth" of entries and we can specify all the same contentTypeId, filters, and linkFields of their own. There is no currently no limit on how deep these linkFields can go
|
|
614
|
+
* @returns Returns nothing if uri, contentTypeId or linkFields is not set in middlewareConfig
|
|
615
|
+
*/
|
|
616
|
+
const makeLinkDepthApi = (app, middlewareConfig) => {
|
|
617
|
+
const {
|
|
618
|
+
uri,
|
|
619
|
+
contentTypeId,
|
|
620
|
+
linkFields
|
|
621
|
+
} = middlewareConfig;
|
|
622
|
+
if (!contentTypeId || !linkFields || !uri) return;
|
|
623
|
+
app.get(uri, makeLinkDepthMiddleware(middlewareConfig));
|
|
624
|
+
};
|
|
625
|
+
/** Create a content type hierarchy from supplied config and produces
|
|
626
|
+
* a RequestHandler function to serve our Express middleware */
|
|
627
|
+
|
|
628
|
+
|
|
629
|
+
const makeLinkDepthMiddleware = ({
|
|
630
|
+
contentTypeId,
|
|
631
|
+
filters = {},
|
|
632
|
+
sharedFilters = {},
|
|
633
|
+
linkFields,
|
|
634
|
+
debug
|
|
635
|
+
}) => {
|
|
636
|
+
try {
|
|
637
|
+
// The runtime express request handler
|
|
638
|
+
const linkDepthMiddleware = async (req, res) => {
|
|
639
|
+
try {
|
|
640
|
+
// Short cache duration copied from canterbury project
|
|
641
|
+
setCachingHeaders.setCachingHeaders(res, {
|
|
642
|
+
cacheControl: 'private',
|
|
643
|
+
surrogateControl: '10'
|
|
644
|
+
}); // Gather all params from the request, we will use them at the right query levels later
|
|
645
|
+
|
|
646
|
+
const params = Object.fromEntries([...Object.entries(req.params), ...Object.entries(req.query)].map(([k, v]) => [k, v === null || v === void 0 ? void 0 : v.toString()]));
|
|
647
|
+
const result = await new LinkDepthSearchService({
|
|
648
|
+
contentTypeId,
|
|
649
|
+
linkFields,
|
|
650
|
+
filters,
|
|
651
|
+
sharedFilters,
|
|
652
|
+
params,
|
|
653
|
+
debug
|
|
654
|
+
}).DoSearch();
|
|
655
|
+
res.json(result);
|
|
656
|
+
} catch (error) {
|
|
657
|
+
// This is a runtime error encountered when processing a given request
|
|
658
|
+
console.error(error);
|
|
659
|
+
res.statusCode = 500;
|
|
660
|
+
res.json(error);
|
|
661
|
+
}
|
|
662
|
+
};
|
|
663
|
+
|
|
664
|
+
return linkDepthMiddleware;
|
|
665
|
+
} catch (error) {
|
|
666
|
+
// This will be an error building the middleware
|
|
667
|
+
// we can only serve what the error was as the request handler instead
|
|
668
|
+
console.error(error);
|
|
669
|
+
|
|
670
|
+
const errorMiddleware = async (req, res) => {
|
|
671
|
+
res.statusCode = 500;
|
|
672
|
+
res.json(JSON.stringify(error));
|
|
673
|
+
};
|
|
674
|
+
|
|
675
|
+
return errorMiddleware;
|
|
676
|
+
}
|
|
677
|
+
};
|
|
678
|
+
|
|
469
679
|
const servers$1 = SERVERS;
|
|
470
680
|
/* global SERVERS */
|
|
471
681
|
|
|
@@ -638,6 +848,8 @@ const staticAssets = (app, {
|
|
|
638
848
|
}));
|
|
639
849
|
};
|
|
640
850
|
|
|
851
|
+
var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
|
|
852
|
+
|
|
641
853
|
/**
|
|
642
854
|
* Removes all key-value entries from the list cache.
|
|
643
855
|
*
|
|
@@ -2806,9 +3018,9 @@ var getNative$1 = _getNative,
|
|
|
2806
3018
|
root$2 = _root;
|
|
2807
3019
|
|
|
2808
3020
|
/* Built-in method references that are verified to be native. */
|
|
2809
|
-
var Set$
|
|
3021
|
+
var Set$1 = getNative$1(root$2, 'Set');
|
|
2810
3022
|
|
|
2811
|
-
var _Set = Set$
|
|
3023
|
+
var _Set = Set$1;
|
|
2812
3024
|
|
|
2813
3025
|
var getNative = _getNative,
|
|
2814
3026
|
root$1 = _root;
|
|
@@ -2821,7 +3033,7 @@ var _WeakMap = WeakMap$1;
|
|
|
2821
3033
|
var DataView = _DataView,
|
|
2822
3034
|
Map = _Map,
|
|
2823
3035
|
Promise$1 = _Promise,
|
|
2824
|
-
Set
|
|
3036
|
+
Set = _Set,
|
|
2825
3037
|
WeakMap = _WeakMap,
|
|
2826
3038
|
baseGetTag = _baseGetTag,
|
|
2827
3039
|
toSource = _toSource;
|
|
@@ -2839,7 +3051,7 @@ var dataViewTag$2 = '[object DataView]';
|
|
|
2839
3051
|
var dataViewCtorString = toSource(DataView),
|
|
2840
3052
|
mapCtorString = toSource(Map),
|
|
2841
3053
|
promiseCtorString = toSource(Promise$1),
|
|
2842
|
-
setCtorString = toSource(Set
|
|
3054
|
+
setCtorString = toSource(Set),
|
|
2843
3055
|
weakMapCtorString = toSource(WeakMap);
|
|
2844
3056
|
|
|
2845
3057
|
/**
|
|
@@ -2855,7 +3067,7 @@ var getTag$3 = baseGetTag;
|
|
|
2855
3067
|
if ((DataView && getTag$3(new DataView(new ArrayBuffer(1))) != dataViewTag$2) ||
|
|
2856
3068
|
(Map && getTag$3(new Map) != mapTag$3) ||
|
|
2857
3069
|
(Promise$1 && getTag$3(Promise$1.resolve()) != promiseTag) ||
|
|
2858
|
-
(Set
|
|
3070
|
+
(Set && getTag$3(new Set) != setTag$3) ||
|
|
2859
3071
|
(WeakMap && getTag$3(new WeakMap) != weakMapTag$1)) {
|
|
2860
3072
|
getTag$3 = function(value) {
|
|
2861
3073
|
var result = baseGetTag(value),
|