6a2c16a945
* Fix next-news inconsistent return type * Add failing test for static file rewrite * Revert "Fix next-news inconsistent return type" This reverts commit b66e76fb86061e45741c3c4bb9296a0874900f76. * Add failing test for double redirect * Fix bug in matcher when having multiple redirects * Remove custom traversal in favor of router handling it * Update next-server.ts * Update router.ts * Temporarily disable test * Don't deeply resolve redirects * Support combined parameters + query passing * Make sure params are correctly passed in * Add test for hash in route
70 lines
1.6 KiB
TypeScript
70 lines
1.6 KiB
TypeScript
import { IncomingMessage, ServerResponse } from 'http'
|
|
import { UrlWithParsedQuery } from 'url'
|
|
import pathMatch from './lib/path-match'
|
|
|
|
export const route = pathMatch()
|
|
|
|
export type Params = { [param: string]: any }
|
|
|
|
export type RouteMatch = (pathname: string | undefined) => false | Params
|
|
|
|
type RouteResult = {
|
|
finished: boolean
|
|
pathname?: string
|
|
}
|
|
|
|
export type Route = {
|
|
match: RouteMatch
|
|
type: string
|
|
statusCode?: number
|
|
name: string
|
|
fn: (
|
|
req: IncomingMessage,
|
|
res: ServerResponse,
|
|
params: Params,
|
|
parsedUrl: UrlWithParsedQuery
|
|
) => Promise<RouteResult> | RouteResult
|
|
}
|
|
|
|
export default class Router {
|
|
routes: Route[]
|
|
constructor(routes: Route[] = []) {
|
|
this.routes = routes
|
|
}
|
|
|
|
add(route: Route) {
|
|
this.routes.unshift(route)
|
|
}
|
|
|
|
async execute(
|
|
req: IncomingMessage,
|
|
res: ServerResponse,
|
|
parsedUrl: UrlWithParsedQuery
|
|
): Promise<boolean> {
|
|
let parsedUrlUpdated = parsedUrl
|
|
for (const route of this.routes) {
|
|
const newParams = route.match(parsedUrlUpdated.pathname)
|
|
|
|
// Check if the match function matched
|
|
if (newParams) {
|
|
// Combine parameters and querystring
|
|
if (route.type === 'rewrite' || route.type === 'redirect') {
|
|
parsedUrlUpdated.query = { ...parsedUrlUpdated.query, ...newParams }
|
|
}
|
|
|
|
const result = await route.fn(req, res, newParams, parsedUrlUpdated)
|
|
|
|
// The response was handled
|
|
if (result.finished) {
|
|
return true
|
|
}
|
|
|
|
if (result.pathname) {
|
|
parsedUrlUpdated.pathname = result.pathname
|
|
}
|
|
}
|
|
}
|
|
|
|
return false
|
|
}
|
|
}
|