|
import { NextFetchEvent, NextRequest } from 'next/server'; |
|
|
|
interface BuildMiddlewareDependenciesOptions { |
|
cookies?: Record<string, string>; |
|
params?: Record<string, string>; |
|
route: string; |
|
} |
|
|
|
type BuildMiddlewareDependencies = ( |
|
options: BuildMiddlewareDependenciesOptions |
|
) => { |
|
url: URL; |
|
event: NextFetchEvent; |
|
request: NextRequest; |
|
}; |
|
|
|
/** thanks to @jaredgorski |
|
we didn't implemented support to catch all routes, |
|
such as `[...slug]`, because we didn't need that |
|
*/ |
|
const hydrateNextRouteWithQuery = ( |
|
route: string, |
|
query: BaseRouterQuery = {} |
|
): string => { |
|
return Object.keys(query).reduce((routeStr, param) => { |
|
return routeStr.replace(`[${param}]`, query[param] as string); |
|
}, route); |
|
}; |
|
|
|
const buildUrl = ({ |
|
params = {}, |
|
route, |
|
}: Pick<BuildMiddlewareDependenciesOptions, 'params' | 'route'>): URL => { |
|
const hydratedRoute = hydrateNextRouteWithQuery(route, params); |
|
|
|
const url = new URL('https://domain.fake' + hydratedRoute); |
|
|
|
Object.entries(params).forEach(([key, value]) => { |
|
url.searchParams.set(key, value); |
|
}); |
|
|
|
return url; |
|
}; |
|
|
|
const buildHeaders = ({ |
|
cookies = {}, |
|
}: Pick<BuildMiddlewareDependenciesOptions, 'cookies'>) => { |
|
const stringifiedCookies = Object.entries(cookies) |
|
.map(([key, value]) => `${key}=${value}`) |
|
.join(';'); |
|
|
|
const headers = new Headers(); |
|
headers.set('cookie', stringifiedCookies); |
|
|
|
return headers; |
|
}; |
|
|
|
export const buildMiddlewareDependencies: BuildMiddlewareDependencies = ({ |
|
cookies = {}, |
|
params = {}, |
|
route, |
|
}) => { |
|
const url = buildUrl({ params, route }); |
|
const headers = buildHeaders({ cookies }); |
|
|
|
const request = new NextRequest(url.href, { |
|
page: { name: route, params }, |
|
headers, |
|
}); |
|
|
|
const event = new NextFetchEvent({ request, page: url.pathname }); |
|
|
|
return { |
|
event, |
|
request, |
|
url, |
|
}; |
|
}; |