@sap-cloud-sdk/odata-common
Version:
SAP Cloud SDK for JavaScript common functions of OData client generator and OpenAPI clint generator.
159 lines • 7.73 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.createGetFilter = createGetFilter;
const moment_1 = __importDefault(require("moment"));
const util_1 = require("@sap-cloud-sdk/util");
const filter_1 = require("../filter");
const selectable_1 = require("../selectable");
/**
* Creates a getFilter function using the OData v2 or OData v4 URI converter.
* The concrete filter getters are initiated in odata/v2/uri-conversion/odata-uri.ts and odata/v4/uri-conversion/odata-uri.ts.
* @param uriConverter - URI converter for v2 or v4.
* @returns The filter getter. See interface {@link GetFilter}
* @internal
*/
function createGetFilter(uriConverter) {
/**
* Get an object containing the given filter as query parameter, or an empty object if none was given.
* @typeParam EntityT - Type of the entity to filter on.
* @param filter - The filter to transform to a query parameter.
* @param entityApi - Entity API for building the filter.
* @returns An object containing the query parameter with encoding or an empty object.
*/
function getFilter(filter, entityApi) {
if (typeof filter !== 'undefined') {
const filterExpression = getODataFilterExpression(filter, [], entityApi);
if (filterExpression) {
return {
filter: encodeURIComponent(filterExpression)
};
}
}
return {};
}
function getODataFilterExpression(filter, parentFieldNames = [], targetEntityApi, lambdaExpressionLevel = 0) {
if ((0, filter_1.isFilterList)(filter)) {
return getODataFilterExpressionForFilterList(filter, parentFieldNames, targetEntityApi, lambdaExpressionLevel);
}
if ((0, filter_1.isFilterLink)(filter)) {
return getODataFilterExpressionForFilterLink(filter, parentFieldNames, lambdaExpressionLevel);
}
if ((0, filter_1.isFilter)(filter)) {
return getODataFilterExpressionForFilter(filter, parentFieldNames, targetEntityApi);
}
if ((0, filter_1.isBooleanFilterFunction)(filter)) {
return filterFunctionToString(filter, parentFieldNames);
}
if ((0, filter_1.isUnaryFilter)(filter)) {
return getODataFilterExpressionForUnaryFilter(filter, parentFieldNames, targetEntityApi);
}
if ((0, filter_1.isFilterLambdaExpression)(filter)) {
return getODataFilterExpressionForFilterLambdaExpression(filter, parentFieldNames, targetEntityApi, lambdaExpressionLevel);
}
if (filter instanceof selectable_1.OneToManyLink) {
return getODataFilterExpressionForFilterLink(filter._filters, parentFieldNames, lambdaExpressionLevel);
}
throw new Error(`Could not construct query parameters from filter. Filter is not valid: ${JSON.stringify(filter)}`);
}
function retrieveField(filterField, targetEntityApi, filterEdmType) {
// In case of complex types there will be a property name as part of the filter.field
const [fieldName] = filterField.split('/');
const field = targetEntityApi.schema[(0, util_1.upperCaseSnakeCase)(fieldName)];
if (field instanceof selectable_1.ComplexTypeField) {
return Object.values(field)
.filter(pField => pField?.fieldPath) // Filter for ComplexTypePropertyFields only
.find(pField => pField.fieldPath() === filterField);
}
// In case of custom field we infer then the returned field from the filter edmType property
return field || { edmType: filterEdmType };
}
function filterFunctionToString(filterFunction, parentFieldNames = []) {
const params = filterFunction.parameters
.map(param => filterFunctionParameterToString(param, parentFieldNames))
.join(',');
return `${filterFunction.functionName}(${params})`;
}
function filterFunctionParameterToString(param, parentFieldNames) {
if (typeof param === 'number') {
return param.toString();
}
if (typeof param === 'string') {
return uriConverter(param, 'Edm.String');
}
if (param instanceof filter_1.FilterFunction) {
return filterFunctionToString(param, parentFieldNames);
}
if (moment_1.default.isMoment(param)) {
return uriConverter(param, 'Edm.DateTimeOffset');
}
if (Array.isArray(param)) {
return `[${param
.map(p => filterFunctionParameterToString(p, parentFieldNames))
.join(',')}]`;
}
return [...parentFieldNames, param._fieldName].join('/');
}
function convertFilterValue(value, edmType) {
return Array.isArray(value)
? `[${value.map(v => uriConverter(v, edmType)).join(',')}]`
: uriConverter(value, edmType);
}
function getODataFilterExpressionForUnaryFilter(filter, parentFieldNames, targetEntityApi) {
return `${filter.operator} (${getODataFilterExpression(filter.singleOperand, parentFieldNames, targetEntityApi)})`;
}
function getODataFilterExpressionForFilterLambdaExpression(filter, parentFieldNames, targetEntityApi, lambdaExpressionLevel) {
const alias = `a${lambdaExpressionLevel}`;
const filterExp = getODataFilterExpression(filter.filters, [alias], targetEntityApi, lambdaExpressionLevel + 1);
return `${parentFieldNames.join('/')}/${filter.lambdaOperator}(${alias}:${filterExp})`;
}
function getODataFilterExpressionForFilterList(filter, parentFieldNames, targetEntityApi, lambdaExpressionLevel) {
let andExp = filter.andFilters
.map(subFilter => getODataFilterExpression(subFilter, parentFieldNames, targetEntityApi, lambdaExpressionLevel))
.filter(f => !!f)
.join(' and ');
andExp = andExp ? `(${andExp})` : andExp;
let orExp = filter.orFilters
.map(subFilter => getODataFilterExpression(subFilter, parentFieldNames, targetEntityApi, lambdaExpressionLevel))
.filter(f => !!f)
.join(' or ');
orExp = orExp ? `(${orExp})` : orExp;
const exp = [];
if (andExp) {
exp.push(andExp);
}
if (orExp) {
exp.push(orExp);
}
return exp.join(' and ');
}
function getODataFilterExpressionForFilterLink(filter, parentFieldNames, lambdaExpressionLevel) {
let linkExp = filter.filters
.map(subFilter => getODataFilterExpression(subFilter, [...parentFieldNames, filter.link._fieldName], filter.link._linkedEntityApi, lambdaExpressionLevel))
.filter(f => !!f)
.join(' and ');
linkExp = linkExp ? `(${linkExp})` : linkExp;
return linkExp;
}
function getODataFilterExpressionForFilter(filter, parentFieldNames, targetEntityApi) {
if (typeof filter.field === 'string') {
const field = retrieveField(filter.field, targetEntityApi, filter.edmType);
return [
[...parentFieldNames, filter.field].join('/'),
filter.operator,
convertFilterValue(filter.value, field.edmType)
].join(' ');
}
return [
filterFunctionToString(filter.field, parentFieldNames),
filter.operator,
convertFilterValue(filter.value, filter.edmType)
].join(' ');
}
return {
getFilter
};
}
//# sourceMappingURL=get-filter.js.map