Files
directus/packages/shared/src/utils/inject-function-results.ts
Rijk van Zanten 90f5b0a471 Add functions support to the app + add count function (#12488)
* Rename date functions to fn, add json_array_length for pg

* Add json count to mssql

* Add json array count support to other vendors

* Add UI for selecting API functions

* Make it not break

* Render functions in filter preview better

* Include functions in field altering

* Add schema access to database helper

* Allow filtering against o2m/m2m/m2a count

* Add data function execution helpers in utils

* Fix type issue

* Inject function results in validate step

* Render field keys with function names translated

* Allow selecting nested/functions in field validation step

* Make sure number comparisons are treated as numbers

* Add check if instanceof date when casting to a Number

* Prevent selecting foreign keys for junction sort (#12463)

* [SDK] Add further request options to `items` functions (#12503)

* add possibility to set further options to the request

* fix options type

* add typings to interface

* add test if headers are passed thourght

* create reusable options param

* set higher priority to options param

* Small stylistic cleanup

Co-authored-by: Azri Kahar <42867097+azrikahar@users.noreply.github.com>
Co-authored-by: ian <licitdev@gmail.com>
Co-authored-by: Jürg Hunziker <juerg.hunziker@gmail.com>
2022-03-31 16:56:26 -04:00

47 lines
1.5 KiB
TypeScript

import { cloneDeep, get, isPlainObject, set } from 'lodash';
import { REGEX_BETWEEN_PARENS } from '../constants';
import { FieldFunction } from '../types';
import { Filter } from '../types/filter';
import { functions } from './functions';
/**
* Inject function output fields into a given payload for accurate validation
*
* @param payload Any data payload
* @param filter A single level filter rule to verify against
*
* @example
* ```js
* const input = { date: '2022-03-29T11:37:56Z' };
* const filter = { 'year(date)': { _eq: 2022 }}
* const output = applyFunctions(input, filter);
* // { date: '2022-03-29T11:37:56Z', 'year(date)': 2022 }
* ```
*/
export function injectFunctionResults(payload: Record<string, any>, filter: Filter) {
const newInput = cloneDeep(payload);
processFilterLevel(filter);
return newInput;
function processFilterLevel(filter: Filter, parentPath?: string) {
for (const [key, value] of Object.entries(filter)) {
const path = parentPath ? parentPath + '.' + key : key;
if (key.startsWith('_') === false && isPlainObject(value)) {
processFilterLevel(value, path);
}
if (key.includes('(') && key.includes(')')) {
const functionName = key.split('(')[0] as FieldFunction;
const fieldKey = key.match(REGEX_BETWEEN_PARENS)?.[1];
if (!fieldKey || !functionName) continue;
const currentValuePath = parentPath ? parentPath + '.' + fieldKey : fieldKey;
const currentValue = get(newInput, currentValuePath);
set(newInput, path, functions[functionName](currentValue));
}
}
}
}