Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/new-shirts-bake.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@solidjs/start": minor
---

refactor middleware. mainly fix onResponse
37 changes: 12 additions & 25 deletions packages/start/src/middleware/index.ts
Original file line number Diff line number Diff line change
@@ -1,53 +1,40 @@
// @refresh skip

import type { H3Event, Middleware } from "h3";
import { H3Event, type Middleware, onResponse } from "h3";
import { getFetchEvent } from "../server/fetchEvent.ts";
import type { FetchEvent } from "../server/types.ts";

/** Function responsible for receiving an observable [operation]{@link Operation} and returning a [result]{@link OperationResult}. */
export type MiddlewareFn = (event: FetchEvent) => unknown;

export type MiddlewareFn = (event: FetchEvent) => Promise<unknown> | unknown;
/** This composes an array of Exchanges into a single ExchangeIO function */

export type RequestMiddleware = (
event: FetchEvent,
) => Response | Promise<Response> | void | Promise<void> | Promise<void | Response>;

// copy-pasted from h3/dist/index.d.ts
type EventHandlerResponse<T = any> = T | Promise<T>;
type ResponseMiddlewareResponseParam = { body?: Awaited<EventHandlerResponse> };
// `unknown` because h3 allows any response type like string, json, etc. not just Response
export type RequestMiddleware = (event: FetchEvent) => unknown;

export type ResponseMiddleware = (
event: FetchEvent,
response: ResponseMiddlewareResponseParam,
) => Response | Promise<Response> | void | Promise<void>;
response: Response,
) => ReturnType<Parameters<typeof onResponse>[0]>;

function wrapRequestMiddleware(onRequest: RequestMiddleware) {
function wrapRequestMiddleware(onRequestFn: RequestMiddleware) {
return async (h3Event: H3Event) => {
// h3 onRequest doesn't allow returning a response, but we will for backwards compatibility with start v1
const fetchEvent = getFetchEvent(h3Event);
const response = await onRequest(fetchEvent);
const response = await onRequestFn(fetchEvent);
if (response) return response;
};
}

function wrapResponseMiddleware(onBeforeResponse: ResponseMiddleware): Middleware {
return async (h3Event, next) => {
const resp = await next();

return onResponse(async (response, h3Event) => {
const fetchEvent = getFetchEvent(h3Event);
const mwResponse = await onBeforeResponse(fetchEvent, {
body: (resp as any)?.body,
});
const mwResponse = await onBeforeResponse(fetchEvent, response.clone());
Comment thread
katywings marked this conversation as resolved.
if (mwResponse) return mwResponse;
};
});
}

export function createMiddleware(
args:
| {
/** @deprecated Use H3 `Middleware` */
onRequest?: RequestMiddleware | RequestMiddleware[] | undefined;
/** @deprecated Use H3 `Middleware` */
onBeforeResponse?: ResponseMiddleware | ResponseMiddleware[] | undefined;
}
| Middleware[],
Expand Down
Loading