UNPKG

@unito/integration-sdk

Version:

Integration SDK

61 lines (50 loc) 1.77 kB
import { OperatorType, OperatorTypes } from '@unito/integration-api'; import { Request, Response, NextFunction } from 'express'; declare global { // eslint-disable-next-line @typescript-eslint/no-namespace namespace Express { interface Locals { filters: Filter[]; } } } /** * Represents one filter parsed from the filters query param. * * Given a filters query param containing: * `filters=[...],name=John,[...]` * * Filter for `name=John` will be: * `{ field: 'name', operator: 'EQUAL', values: ['John'] }` */ export type Filter = { field: string; operator: OperatorType; // Without the schema of the item, // we can't determine the types of the values (number, boolean, etc). values: string[] | undefined; }; // The operators are ordered by their symbol length, in descending order. // This is necessary because the symbol of an operator can be // a subset of the symbol of another operator. // // For example, the symbol "=" (EQUAL) is a subset of the symbol "!=" (NOT_EQUAL). const ORDERED_OPERATORS = Object.values(OperatorTypes).sort((o1, o2) => o2.length - o1.length); function extractFilters(req: Request, res: Response, next: NextFunction) { const rawFilters = req.query.filter; res.locals.filters = []; if (typeof rawFilters === 'string') { for (const rawFilter of rawFilters.split(',')) { for (const operator of ORDERED_OPERATORS) { if (rawFilter.includes(operator)) { const [field, valuesRaw] = rawFilter.split(operator, 2); const values = valuesRaw ? valuesRaw.split('|').map(decodeURIComponent) : []; res.locals.filters.push({ field: field!, operator, values }); break; } } } } next(); } export default extractFilters;