Skip to content
Open
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
96 changes: 61 additions & 35 deletions boilerplate/fullstack/nuxt/server/utils/convertToRequest.ts
Original file line number Diff line number Diff line change
@@ -1,43 +1,69 @@
import { H3Event } from "h3";
import { H3Event, getRequestURL, getRequestHeaders, readRawBody, parseCookies } from "h3";
import { backendConfig } from "../backendConfigUtils";

const appInfo = backendConfig().appInfo;

interface ExtendedRequestInit extends RequestInit {
duplex?: string;
}

/**
* Converts an H3Event to a standard Request object compatible with SuperTokens
* This properly handles cookies and headers required for session management
*/
export default async function convertToRequest(event: H3Event): Promise<Request> {
const url = new URL(`${appInfo.apiDomain}${event._path}`);
const headers = new Headers(event.node.req.headers as Record<string, string>);
const method = (event.method || "GET").toUpperCase();

let body: ReadableStream | null = null;
if (method !== "GET" && method !== "HEAD") {
// Read the body only once and convert it into a format that can be used in the request.
const rawBody = await readBody(event);
if (typeof rawBody === "object") {
body = new ReadableStream({
start(controller) {
controller.enqueue(new TextEncoder().encode(JSON.stringify(rawBody)));
controller.close();
},
});
} else if (typeof rawBody === "string") {
body = new ReadableStream({
start(controller) {
controller.enqueue(new TextEncoder().encode(rawBody));
controller.close();
},
});
try {
// Get the full URL including query parameters
const requestURL = getRequestURL(event);
const url = new URL(`${appInfo.apiDomain}${requestURL.pathname}${requestURL.search}`);

// Create headers from the request
const requestHeaders = getRequestHeaders(event);
const headers = new Headers();

// Properly copy all headers
Object.entries(requestHeaders).forEach(([key, value]) => {
if (value !== undefined) {
headers.append(key, Array.isArray(value) ? value.join(", ") : String(value));
}
});

// Make sure the cookie header is set correctly for session management
// Using parseCookies from h3 to get all cookies from the request
const cookies = parseCookies(event);
if (Object.keys(cookies).length > 0) {
const cookieString = Object.entries(cookies)
.map(([name, value]) => `${name}=${value}`)
.join('; ');

// Set the Cookie header explicitly to ensure it's passed to SuperTokens
headers.set('Cookie', cookieString);
}
}

const request: ExtendedRequestInit = {
method,
headers,
body,
duplex: "half",
};
return new Request(url, request);
const method = (event.method || "GET").toUpperCase();

// Initialize options for the Request
const options: RequestInit = {
method,
headers,
// Ensure cookies are passed through
credentials: "include",
};

// Handle request body for non-GET/HEAD requests
if (method !== "GET" && method !== "HEAD") {
try {
// Use readRawBody instead of readBody to get the raw buffer
const rawBody = await readRawBody(event);
if (rawBody) {
// Create a simpler Blob-based body instead of using ReadableStream
options.body = new Blob([rawBody]);
}
} catch (error) {
console.error("Error reading request body:", error);
// Continue without body if there's an error reading it
}
}

return new Request(url.toString(), options);
} catch (error) {
console.error("Error creating Request object:", error);
throw new Error(`Failed to convert H3Event to Request: ${error instanceof Error ? error.message : 'Unknown error'}`);
}
}