|
import { $ } from "@builder.io/qwik"; |
|
import type { RequestEventAction } from "@builder.io/qwik-city"; |
|
import { server$ } from "@builder.io/qwik-city"; |
|
interface CookieOption { |
|
[key: string]: string; |
|
} |
|
interface Cookie { |
|
name: string | undefined; |
|
value: string | undefined; |
|
options: CookieOption[] | undefined; |
|
} |
|
export const parseCookies = $((setCookieHeader: string): Cookie[] => { |
|
const rawCookieStrings = setCookieHeader.split(/,(?=\s[a-zA-Z]+=)/); |
|
const parsedCookies: Cookie[] = rawCookieStrings.map((cookieString) => { |
|
const cookieComponents = cookieString.split(";"); |
|
const rawNameAndValue = cookieComponents.shift(); |
|
if (rawNameAndValue) { |
|
const nameAndValue = rawNameAndValue.split("="); |
|
const cookieName = nameAndValue.shift()?.trim(); |
|
const cookieValue = nameAndValue.shift()?.trim(); |
|
if (cookieName && cookieValue) { |
|
const cookieOptions: CookieOption[] = cookieComponents.map( |
|
(optionString) => { |
|
const optionComponents = optionString.split("="); |
|
const optionName = optionComponents.shift()?.trim(); |
|
const optionValue = optionComponents.shift()?.trim(); |
|
if (optionName && optionValue) { |
|
return { [optionName]: optionValue }; |
|
} else { |
|
return {}; |
|
} |
|
}, |
|
); |
|
return { name: cookieName, value: cookieValue, options: cookieOptions }; |
|
} |
|
} |
|
return { name: undefined, value: undefined, options: undefined }; |
|
}); |
|
return parsedCookies; |
|
}); |
|
export const sendPost = server$( |
|
async ( |
|
url: string, |
|
path: string, |
|
data: any, |
|
includeCookies: string[], |
|
event: RequestEventAction, |
|
) => { |
|
const cookies = includeCookies.reduce((acc, curr) => { |
|
const cookie = event.cookie.get(curr)?.value; |
|
if (cookie) { |
|
acc[curr] = cookie; |
|
} |
|
return acc; |
|
}, {} as any); |
|
const joinCookies = Object.entries(cookies) |
|
.map(([key, value]) => `${key}=${value}`) |
|
.join("; "); |
|
const request = await fetch(url + path, { |
|
method: "POST", |
|
headers: { |
|
Cookie: joinCookies, |
|
"Content-Type": "application/json", |
|
}, |
|
body: JSON.stringify(data), |
|
credentials: "include", |
|
}); |
|
const setCookies = await parseCookies( |
|
request.headers.get("set-cookie") || "", |
|
); |
|
setCookies.forEach((c) => { |
|
if (c.name && c.value) { |
|
const e = c.options ? c.options.find((o) => "Expires" in o) : null; |
|
if (c.name && c.value) { |
|
event.cookie.set(c.name, c.value, { |
|
expires: e && e.Expires ? new Date(e.Expires) : undefined, |
|
httpOnly: true, |
|
path: "/", |
|
sameSite: "strict", |
|
secure: false, |
|
}); |
|
} |
|
} |
|
}); |
|
return await request.json(); |
|
}, |
|
); |
|
export const PostRequest = server$( |
|
async (path: string, data: any, event: RequestEventAction) => { |
|
return await sendPost( |
|
"http://localhost:3000", |
|
path, |
|
data, |
|
["session"], |
|
event, |
|
); |
|
}, |
|
); |