UNPKG

@opra/common

Version:
138 lines (137 loc) 4.67 kB
import { FilterRules } from '../../filter/filter-rules.js'; import { DATATYPE_METADATA } from '../constants.js'; import { FIELD_PATH_PATTERN } from '../data-type/complex-type-base.js'; import { EnumType } from '../data-type/enum-type.js'; import { FilterType } from '../data-type/extended-types/index.js'; import { HttpOperation } from '../http/http-operation.js'; /** Implementation **/ HttpOperation.Entity = {}; /** * * @param typ */ export function getDataTypeName(typ) { if (typeof typ === 'string') return typ; const metadata = Reflect.getMetadata(DATATYPE_METADATA, typ); if (!metadata) throw new TypeError(`Type (${typ}) is not decorated with any datatype decorators`); if (metadata?.name) return metadata.name; throw new TypeError(`You should provide named data type but embedded one found`); } /** * */ export function createKeyParamDecorator(decorator, decoratorChain) { return (name, prmOptions) => { const paramMeta = typeof prmOptions === 'string' || typeof prmOptions === 'function' ? { name, location: 'path', type: prmOptions, keyParam: true, } : { ...prmOptions, name, location: 'path', keyParam: true, }; decorator.PathParam(name, paramMeta); decoratorChain.push((meta) => { if (!meta.path?.includes(':' + name)) meta.path = (meta.path || '') + '@:' + name; meta.mergePath = true; }); return decorator; }; } /** * */ export function createSortFieldsDecorator(decorator, decoratorChain) { return (...varargs) => { const defObj = typeof varargs[0] === 'object' ? varargs[0] : varargs.reduce((acc, k) => { const a = k.split(':'); acc[a[0]] = a[1] || a[0]; return acc; }, {}); const fieldsMap = Object.keys(defObj).reduce((acc, k) => { const m1 = FIELD_PATH_PATTERN.exec(k); const m2 = FIELD_PATH_PATTERN.exec(defObj[k]); if (m1 && m2) { acc[m1[2]] = m2[2]; } return acc; }, {}); const prmEnum = Object.keys(defObj).reduce((acc, k) => { const m = FIELD_PATH_PATTERN.exec(k); if (m) { if (m[1] != '-') acc[m[2]] = m[2]; if (m[1] != '+') acc['-' + m[2]] = '-' + m[2]; } return acc; }, {}); decoratorChain.push((operationMeta) => { const compositionOptions = (operationMeta.compositionOptions = operationMeta.compositionOptions || {}); compositionOptions.sortFields = fieldsMap; }); decorator.QueryParam('sort', { description: 'Determines sort fields', type: EnumType(prmEnum), isArray: true, arraySeparator: ',', parser: (v) => v.map(x => { const m = FIELD_PATH_PATTERN.exec(x); return m ? (m[1] || '') + fieldsMap[m[2]] : x; }), }); return decorator; }; } /** * */ export function createFilterDecorator(decorator, decoratorChain, dataType) { let filterRules = Reflect.getMetadata('FilterRules', decorator); if (!filterRules) { filterRules = new FilterRules(); Reflect.defineMetadata('FilterRules', filterRules, decorator); } let filterType = Reflect.getMetadata('FilterType', decorator); if (!filterType) { filterType = new FilterType({ dataType }); filterType.rules = {}; Reflect.defineMetadata('FilterType', filterType, decorator); } return (field, arg0) => { const filterOptions = (Array.isArray(arg0) ? { operators: arg0 } : typeof arg0 === 'string' ? { operators: arg0.split(/\s*,\s*/), } : arg0) || {}; filterOptions.operators = filterOptions.operators || ['=', '!=']; if (field.includes(':')) { const a = field.split(':'); field = a[0]; filterOptions.mappedField = a[1]; } decoratorChain.push(() => { filterRules.set(field, filterOptions); filterType.rules = filterRules.toJSON(); }); decorator.QueryParam('filter', { type: filterType, description: 'Determines filter fields', }); return decorator; }; }