(fieldDef: FieldDef, value: string, op: FilterOperationType)
| 2517 | } |
| 2518 | |
| 2519 | private makeFilterValue(fieldDef: FieldDef, value: string, op: FilterOperationType): any { |
| 2520 | // TODO: inequality filters? |
| 2521 | if (fieldDef.relation) { |
| 2522 | // relation filter is converted to an ID filter |
| 2523 | const info = this.getModelInfo(fieldDef.type)!; |
| 2524 | if (fieldDef.array) { |
| 2525 | // filtering a to-many relation, imply 'some' operator |
| 2526 | const values = value.split(',').filter((i) => i); |
| 2527 | const filterValue = |
| 2528 | values.length > 1 |
| 2529 | ? { OR: values.map((v) => this.makeIdFilter(info.idFields, v, false)) } |
| 2530 | : this.makeIdFilter(info.idFields, value, false); |
| 2531 | return { some: filterValue }; |
| 2532 | } else { |
| 2533 | const values = value.split(',').filter((i) => i); |
| 2534 | if (values.length > 1) { |
| 2535 | return { OR: values.map((v) => this.makeIdFilter(info.idFields, v, false)) }; |
| 2536 | } else { |
| 2537 | return { is: this.makeIdFilter(info.idFields, value, false) }; |
| 2538 | } |
| 2539 | } |
| 2540 | } else { |
| 2541 | if (op === 'between') { |
| 2542 | const parts = value.split(',').map((v) => this.coerce(fieldDef, v)); |
| 2543 | if (parts.length !== 2) { |
| 2544 | throw new InvalidValueError(`"between" expects exactly 2 comma-separated values`); |
| 2545 | } |
| 2546 | return { between: [parts[0]!, parts[1]!] }; |
| 2547 | } |
| 2548 | const coerced = this.coerce(fieldDef, value); |
| 2549 | switch (op) { |
| 2550 | case 'icontains': |
| 2551 | return { contains: coerced, mode: 'insensitive' }; |
| 2552 | case 'hasSome': |
| 2553 | case 'hasEvery': { |
| 2554 | const values = value |
| 2555 | .split(',') |
| 2556 | .filter((i) => i) |
| 2557 | .map((v) => this.coerce(fieldDef, v)); |
| 2558 | return { [op]: values }; |
| 2559 | } |
| 2560 | case 'isEmpty': |
| 2561 | if (value !== 'true' && value !== 'false') { |
| 2562 | throw new InvalidValueError(`Not a boolean: ${value}`); |
| 2563 | } |
| 2564 | return { isEmpty: value === 'true' ? true : false }; |
| 2565 | default: |
| 2566 | if (op === undefined) { |
| 2567 | if (fieldDef.attributes?.some((attr) => attr.name === '@json')) { |
| 2568 | // handle JSON value equality filter |
| 2569 | return { equals: coerced }; |
| 2570 | } |
| 2571 | |
| 2572 | // regular filter, split value by comma |
| 2573 | const values = value |
| 2574 | .split(',') |
| 2575 | .filter((i) => i) |
| 2576 | .map((v) => this.coerce(fieldDef, v)); |
no test coverage detected