Skip to content
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

refactor(app): extract handler returned response handling #473

Merged
merged 4 commits into from
Aug 1, 2023
Merged
Changes from all 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
112 changes: 59 additions & 53 deletions src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ export function use(

export function createAppEventHandler(stack: Stack, options: AppOptions) {
const spacing = options.debug ? 2 : undefined;

return eventHandler(async (event) => {
// Keep original incoming url accessable
event.node.req.originalUrl =
Expand Down Expand Up @@ -135,63 +136,17 @@ export function createAppEventHandler(stack: Stack, options: AppOptions) {
// 4. Handle request
const val = await layer.handler(event);

// 5. Try to handle return value
const handledVal =
val !== undefined && handleHandlerResponse(event, val, spacing);
if (handledVal !== false) {
return handledVal;
}

// Already handled
if (event.handled) {
return;
}

// Empty Content
if (val === null) {
event.node.res.statusCode = 204;
return send(event);
}

if (val) {
// Web Response
if (isWebResponse(val)) {
return sendWebResponse(event, val);
}

// Stream
if (isStream(val)) {
return sendStream(event, val);
}

// Buffer
if (val.buffer) {
return send(event, val);
}

// Blob
if (val.arrayBuffer && typeof val.arrayBuffer === "function") {
return send(
event,
Buffer.from(await (val as Blob).arrayBuffer()),
val.type
);
}

// Error
if (val instanceof Error) {
throw createError(val);
}
}

const valType = typeof val;

// HTML String
if (valType === "string") {
return send(event, val, MIMES.html);
}

// JSON Response
if (
valType === "object" ||
valType === "boolean" ||
valType === "number"
) {
return send(event, JSON.stringify(val, undefined, spacing), MIMES.json);
}
}
if (!event.handled) {
throw createError({
Expand Down Expand Up @@ -222,3 +177,54 @@ function normalizeLayer(input: InputLayer) {
handler,
} as Layer;
}

function handleHandlerResponse(event: H3Event, val: any, jsonSpace?: number) {
// Empty Content
if (val === null) {
event.node.res.statusCode = 204;
return send(event);
}

if (val) {
// Web Response
if (isWebResponse(val)) {
return sendWebResponse(event, val);
}

// Stream
if (isStream(val)) {
return sendStream(event, val);
}

// Buffer
if (val.buffer) {
return send(event, val);
}

// Blob
if (val.arrayBuffer && typeof val.arrayBuffer === "function") {
return (val as Blob).arrayBuffer().then((arrayBuffer) => {
return send(event, Buffer.from(arrayBuffer), val.type);
});
}

// Error
if (val instanceof Error) {
throw createError(val);
}
}

const valType = typeof val;

// HTML String
if (valType === "string") {
return send(event, val, MIMES.html);
}

// JSON Response
if (valType === "object" || valType === "boolean" || valType === "number") {
return send(event, JSON.stringify(val, undefined, jsonSpace), MIMES.json);
}

return false;
}