-
-
Notifications
You must be signed in to change notification settings - Fork 574
feat: custom request predicate function #2541
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 12 commits
1a2110f
ba63e46
d0253f8
b01417f
570692b
157b54c
dc0efc7
c5b9eb2
3388f96
6f8d5fa
d820b6e
5763c33
1e9a8e3
8b00de3
da1f44c
06f01e9
4452a33
dc60641
9ffca63
b37a5e0
fd5cd0f
c3f89aa
7dd1046
54f0481
98ff915
61d5a99
7cb1fb6
4baba5c
18dfcc9
8ea8e27
4765f98
af5b4d6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -52,6 +52,13 @@ export type HttpRequestResolverExtras<Params extends PathParams> = { | |
| cookies: Record<string, string> | ||
| } | ||
|
|
||
| export type HttpCustomPredicate = (args: { | ||
| request: Request | ||
| cookies: Record<string, string> | ||
| }) => boolean | Promise<boolean> | ||
|
||
|
|
||
| export type HttpRequestPath = Path | HttpCustomPredicate | ||
|
|
||
| /** | ||
| * Request handler for HTTP requests. | ||
| * Provides request matching based on method and URL. | ||
|
|
@@ -61,11 +68,15 @@ export class HttpHandler extends RequestHandler< | |
| HttpRequestParsedResult, | ||
| HttpRequestResolverExtras<any> | ||
| > { | ||
| private customPredicate?: HttpCustomPredicate | ||
|
|
||
| constructor( | ||
| method: HttpHandlerMethod, | ||
| path: Path, | ||
| resolver: ResponseResolver<HttpRequestResolverExtras<any>, any, any>, | ||
| options?: RequestHandlerOptions, | ||
| options?: RequestHandlerOptions & { | ||
| predicate?: HttpCustomPredicate | ||
| }, | ||
| ) { | ||
| super({ | ||
| info: { | ||
|
|
@@ -76,14 +87,14 @@ export class HttpHandler extends RequestHandler< | |
| resolver, | ||
| options, | ||
| }) | ||
|
|
||
| this.customPredicate = options?.predicate | ||
| this.checkRedundantQueryParameters() | ||
| } | ||
|
|
||
| private checkRedundantQueryParameters() { | ||
| const { method, path } = this.info | ||
|
|
||
| if (path instanceof RegExp) { | ||
| if (!path || path instanceof RegExp) { | ||
| return | ||
| } | ||
|
|
||
|
|
@@ -111,11 +122,9 @@ export class HttpHandler extends RequestHandler< | |
| resolutionContext?: ResponseResolutionContext | ||
| }) { | ||
| const url = new URL(args.request.url) | ||
| const match = matchRequestUrl( | ||
| url, | ||
| this.info.path, | ||
| args.resolutionContext?.baseUrl, | ||
| ) | ||
| const match = this.info.path | ||
| ? matchRequestUrl(url, this.info.path, args.resolutionContext?.baseUrl) | ||
| : { matches: false, params: {} } | ||
| const cookies = getAllRequestCookies(args.request) | ||
|
|
||
| return { | ||
|
|
@@ -124,7 +133,22 @@ export class HttpHandler extends RequestHandler< | |
| } | ||
| } | ||
|
|
||
| predicate(args: { request: Request; parsedResult: HttpRequestParsedResult }) { | ||
| async predicate(args: { | ||
| request: Request | ||
| parsedResult: HttpRequestParsedResult | ||
| resolutionContext?: ResponseResolutionContext | ||
| }) { | ||
| if (this.customPredicate) { | ||
| // Clone the request to avoid locking its body stream. | ||
| // The body can only be read once, so cloning allows both | ||
| // the predicate and resolver to access it independently. | ||
| const clonedRequest = args.request.clone() | ||
|
|
||
| return await this.customPredicate({ | ||
| request: clonedRequest, | ||
| cookies: args.parsedResult.cookies, | ||
| }) | ||
| } | ||
kettanaito marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| const hasMatchingMethod = this.matchMethod(args.request.method) | ||
| const hasMatchingUrl = args.parsedResult.match.matches | ||
| return hasMatchingMethod && hasMatchingUrl | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -7,8 +7,9 @@ import { | |
| HttpMethods, | ||
| HttpHandler, | ||
| HttpRequestResolverExtras, | ||
| HttpRequestPath, | ||
| } from './handlers/HttpHandler' | ||
| import type { Path, PathParams } from './utils/matching/matchRequestUrl' | ||
| import type { PathParams } from './utils/matching/matchRequestUrl' | ||
|
|
||
| export type HttpRequestHandler = < | ||
| Params extends PathParams<keyof Params> = PathParams, | ||
|
|
@@ -18,7 +19,7 @@ export type HttpRequestHandler = < | |
| // returns plain "Response" and the one returning "HttpResponse" | ||
| // to enforce a stricter response body type. | ||
| ResponseBodyType extends DefaultBodyType = undefined, | ||
| RequestPath extends Path = Path, | ||
| RequestPath extends HttpRequestPath = HttpRequestPath, | ||
| >( | ||
| path: RequestPath, | ||
| resolver: HttpResponseResolver<Params, RequestBodyType, ResponseBodyType>, | ||
|
|
@@ -39,6 +40,12 @@ function createHttpHandler<Method extends HttpMethods | RegExp>( | |
| method: Method, | ||
| ): HttpRequestHandler { | ||
| return (path, resolver, options = {}) => { | ||
| if (typeof path === 'function') { | ||
|
||
| return new HttpHandler(method, '', resolver, { | ||
| ...options, | ||
| predicate: path, | ||
| }) | ||
| } | ||
| return new HttpHandler(method, path, resolver, options) | ||
| } | ||
| } | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.