( searchParams: URLSearchParams, allowedFields?: string[] )
| 119 | }; |
| 120 | |
| 121 | export const parseSearchParamsForSearch = ( |
| 122 | searchParams: URLSearchParams, |
| 123 | allowedFields?: string[] |
| 124 | ): Search => { |
| 125 | const { matchMode, matchValues, ...rest } = getSearchMetadata(searchParams, allowedFields); |
| 126 | |
| 127 | // Validate and generate result |
| 128 | const matches: SearchItem[] = []; |
| 129 | const result: Search = { |
| 130 | matches, |
| 131 | ...rest, |
| 132 | }; |
| 133 | |
| 134 | const getModeFor = (field: Optional<string>): SearchMatchMode => |
| 135 | // eslint-disable-next-line unicorn/no-useless-undefined |
| 136 | matchMode.get(field) ?? matchMode.get(undefined) ?? SearchMatchMode.Like; |
| 137 | |
| 138 | for (const [field, values] of matchValues.entries()) { |
| 139 | const mode = getModeFor(field); |
| 140 | |
| 141 | if (mode === SearchMatchMode.Exact) { |
| 142 | assertThat(values.every(Boolean), new TypeError('Search value cannot be empty.')); |
| 143 | } else { |
| 144 | assertThat( |
| 145 | values.length === 1, |
| 146 | new TypeError('Only one search value is allowed when search mode is not `exact`.') |
| 147 | ); |
| 148 | assertThat(values[0], new TypeError('Search value cannot be empty.')); |
| 149 | } |
| 150 | |
| 151 | matches.push({ mode, field, values }); |
| 152 | } |
| 153 | |
| 154 | return result; |
| 155 | }; |
| 156 | /* eslint-enable @silverhand/fp/no-mutating-methods */ |
| 157 | |
| 158 | const getJointModeSql = (mode: SearchJointMode) => { |
no test coverage detected