( contract: C, request: NextRequest, context: TContext, options?: ParseRequestOptions )
| 230 | } |
| 231 | |
| 232 | export async function parseRequest<C extends AnyApiRouteContract, TContext>( |
| 233 | contract: C, |
| 234 | request: NextRequest, |
| 235 | context: TContext, |
| 236 | options?: ParseRequestOptions |
| 237 | ): Promise< |
| 238 | { success: true; data: ParsedRequest<C> } | { success: false; response: NextResponse<unknown> } |
| 239 | > { |
| 240 | const rawParams = await parseContextParams(context) |
| 241 | const rawQuery = searchParamsToObject(request.nextUrl.searchParams) |
| 242 | const rawHeaders = headersToObject(request.headers) |
| 243 | |
| 244 | let body: unknown |
| 245 | if (shouldReadJsonBody(contract)) { |
| 246 | const parsedBody = await parseJsonBody(request, options?.invalidJson, options?.maxBodyBytes) |
| 247 | if (!parsedBody.success) { |
| 248 | return options?.invalidJsonResponse && parsedBody.reason === 'invalid_json' |
| 249 | ? { success: false, response: options.invalidJsonResponse() } |
| 250 | : parsedBody |
| 251 | } |
| 252 | body = parsedBody.data |
| 253 | } |
| 254 | |
| 255 | const params = contract.params |
| 256 | ? validateRequestSchema(contract.params, rawParams, options) |
| 257 | : undefined |
| 258 | if (params && !params.success) return params |
| 259 | |
| 260 | const query = contract.query |
| 261 | ? validateRequestSchema(contract.query, rawQuery, options) |
| 262 | : undefined |
| 263 | if (query && !query.success) return query |
| 264 | |
| 265 | const headers = contract.headers |
| 266 | ? validateRequestSchema(contract.headers, rawHeaders, options) |
| 267 | : undefined |
| 268 | if (headers && !headers.success) return headers |
| 269 | |
| 270 | const parsedBody = contract.body ? validateRequestSchema(contract.body, body, options) : undefined |
| 271 | if (parsedBody && !parsedBody.success) return parsedBody |
| 272 | |
| 273 | return { |
| 274 | success: true, |
| 275 | data: { |
| 276 | params: params?.data as ContractParams<C>, |
| 277 | query: query?.data as ContractQuery<C>, |
| 278 | headers: headers?.data as ContractHeaders<C>, |
| 279 | body: parsedBody?.data as ContractBody<C>, |
| 280 | }, |
| 281 | } |
| 282 | } |
| 283 | |
| 284 | function validateRequestSchema<S extends ApiSchema>( |
| 285 | schema: S, |
no test coverage detected