(req, res, next)
| 164 | class ValidationError extends Error {} |
| 165 | |
| 166 | const validationMiddleware = (req, res, next) => { |
| 167 | const params = [ |
| 168 | { key: 'query' }, |
| 169 | { |
| 170 | key: 'version', |
| 171 | default_: 'dotcom', |
| 172 | validate: (v) => { |
| 173 | if (versionAliases[v] || allVersions[v]) return true |
| 174 | const valid = [...Object.keys(versionAliases), ...Object.keys(allVersions)] |
| 175 | throw new ValidationError(`'${v}' not in ${valid}`) |
| 176 | }, |
| 177 | }, |
| 178 | { key: 'language', default_: 'en', validate: (v) => v in languages }, |
| 179 | { |
| 180 | key: 'size', |
| 181 | default_: DEFAULT_SIZE, |
| 182 | cast: (v) => parseInt(v, 10), |
| 183 | validate: (v) => v >= 0 && v <= MAX_SIZE, |
| 184 | }, |
| 185 | { |
| 186 | key: 'page', |
| 187 | default_: DEFAULT_PAGE, |
| 188 | cast: (v) => parseInt(v, 10), |
| 189 | validate: (v) => v >= 1 && v <= MAX_PAGE, |
| 190 | }, |
| 191 | { key: 'sort', default_: DEFAULT_SORT, validate: (v) => POSSIBLE_SORTS.includes(v) }, |
| 192 | { |
| 193 | key: 'highlights', |
| 194 | default_: DEFAULT_HIGHLIGHT_FIELDS, |
| 195 | cast: (v) => (Array.isArray(v) ? v : [v]), |
| 196 | validate: (v) => { |
| 197 | for (const highlight of v) { |
| 198 | if (!POSSIBLE_HIGHLIGHT_FIELDS.includes(highlight)) { |
| 199 | throw new ValidationError(`highlight value '${highlight}' is not valid`) |
| 200 | } |
| 201 | } |
| 202 | return true |
| 203 | }, |
| 204 | }, |
| 205 | { key: 'autocomplete', default_: false, cast: toBoolean }, |
| 206 | { key: 'debug', default_: process.env.NODE_ENV === 'development', cast: toBoolean }, |
| 207 | ] |
| 208 | |
| 209 | const search = {} |
| 210 | for (const { key, default_, cast, validate } of params) { |
| 211 | let value = req.query[key] |
| 212 | if (!value || (typeof value === 'string' && !value.trim())) { |
| 213 | if (default_ === undefined) { |
| 214 | // no value and no default, bad! |
| 215 | return res.status(400).json({ error: `No truthy value for key '${key}'` }) |
| 216 | } |
| 217 | value = default_ |
| 218 | } |
| 219 | if (cast) { |
| 220 | value = cast(value) |
| 221 | } |
| 222 | try { |
| 223 | if (validate && !validate(value)) { |
nothing calls this directly
no test coverage detected