@webiny/api-headless-cms-ddb-es
Version:
DynamoDB and Elasticsearch storage operations plugin for Headless CMS API.
175 lines (171 loc) • 5.59 kB
JavaScript
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.createExecFiltering = void 0;
var _error = _interopRequireDefault(require("@webiny/error"));
var _search = require("../plugins/search");
var _operator = require("../plugins/operator");
var _initialQuery = require("../initialQuery");
var _apiElasticsearch = require("@webiny/api-elasticsearch");
var _values = require("./values");
var _populated = require("./populated");
var _applyFiltering = require("./applyFiltering");
var _CmsEntryFilterPlugin = require("../../../../plugins/CmsEntryFilterPlugin");
var _assignMinimumShouldMatchToQuery = require("../assignMinimumShouldMatchToQuery");
const createExecFiltering = params => {
const {
fields,
plugins,
model
} = params;
/**
* We need the search plugins as key -> plugin value, so it is easy to find plugin we need, without iterating through array.
*/
const searchPlugins = (0, _search.createSearchPluginList)({
plugins
});
/**
* We need the operator plugins, which we execute on our where conditions.
*/
const operatorPlugins = (0, _operator.createOperatorPluginList)({
plugins,
locale: model.locale
});
const applyFiltering = (0, _applyFiltering.createApplyFiltering)({
operatorPlugins,
searchPlugins
});
const filteringPlugins = plugins.byType(_CmsEntryFilterPlugin.CmsEntryFilterPlugin.type).reduce((collection, plugin) => {
collection[plugin.fieldType] = plugin;
return collection;
}, {});
const getFilterPlugin = type => {
const plugin = filteringPlugins[type] || filteringPlugins["*"];
if (plugin) {
return plugin;
}
throw new _error.default(`There is no filtering plugin for the given field type "${type}".`, "FILTERING_PLUGIN_ERROR", {
type
});
};
const execFiltering = params => {
const {
where: initialWhere,
query
} = params;
/**
* No point in continuing if no "where" conditions exist.
*/
const keys = Object.keys(initialWhere);
if (keys.length === 0) {
return;
}
const where = {
...initialWhere
};
for (const key in where) {
const value = where[key];
/**
* We always skip if no value is defined.
* Only skip undefined value, null is valid.
*/
if (value === undefined) {
continue;
}
//
/**
* When we are running with AND, the "value" MUST be an array.
*/else if (key === "AND") {
const childWhereList = (0, _values.getWhereValues)(value, "AND");
const childQuery = (0, _initialQuery.createBaseQuery)();
for (const childWhere of childWhereList) {
execFiltering({
query: childQuery,
where: childWhere
});
}
const childQueryBool = (0, _populated.getPopulated)(childQuery);
if (Object.keys(childQueryBool).length === 0) {
continue;
}
query.filter.push({
bool: childQueryBool
});
continue;
}
//
/**
* When we are running with OR, the "value" must be an array.
*/else if (key === "OR") {
const childWhereList = (0, _values.getWhereValues)(value, "OR");
/**
* Each of the conditions MUST produce it's own should section.
*/
const should = [];
for (const childWhere of childWhereList) {
const childQuery = (0, _initialQuery.createBaseQuery)();
execFiltering({
query: childQuery,
where: childWhere
});
const childQueryBool = (0, _populated.getPopulated)(childQuery);
if (Object.keys(childQueryBool).length === 0) {
continue;
}
should.push({
bool: childQueryBool
});
}
if (should.length === 0) {
continue;
}
query.should.push(...should);
/**
* If there are any should, minimum to have is 1.
* Of course, do not override if it's already set.
*/
(0, _assignMinimumShouldMatchToQuery.assignMinimumShouldMatchToQuery)({
query
});
continue;
}
const {
field: whereFieldId,
operator
} = (0, _apiElasticsearch.parseWhereKey)(key);
let fieldId = whereFieldId;
/**
* TODO This will be required until the storage operations receive the fieldId instead of field storageId.
* TODO For this to work without field searching, we need to refactor how the query looks like.
*
* Storage operations should NEVER receive an field storageId, only alias - fieldId.
*/
const cmsModelField = model.fields.find(f => f.fieldId === fieldId);
if (!cmsModelField && !fields[fieldId]) {
throw new _error.default(`There is no CMS Model Field "${fieldId}".`);
} else if (cmsModelField) {
fieldId = cmsModelField.fieldId;
}
const field = fields[fieldId];
if (!field) {
throw new _error.default(`There is no field "${fieldId}".`, "EXEC_FILTERING_ERROR");
}
const filterPlugin = getFilterPlugin(field.type);
filterPlugin.exec({
applyFiltering,
getFilterPlugin,
key,
value,
operator,
field,
fields,
query
});
}
};
return execFiltering;
};
exports.createExecFiltering = createExecFiltering;
//# sourceMappingURL=exec.js.map