Skip to content
Merged
Show file tree
Hide file tree
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
7 changes: 6 additions & 1 deletion src/app.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,12 @@ declare global {
// interface Error {}
// interface PageData {}
// interface PageState {}
// interface Platform {}
interface Platform {
env: {
/** Secrets Store binding in deployed Workers; a plain string in local dev and prerender. */
SERVER_API_TOKEN?: string | { get(): Promise<string> };
};
}
namespace Superforms {
type Message = { type: "error" | "success"; text: string };
}
Expand Down
47 changes: 14 additions & 33 deletions src/lib/shared/api/mutator/custom-instance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { env as envPrivate } from "$env/dynamic/private";
import { env as envPublic } from "$env/dynamic/public";

const { PUBLIC_SERVER_API_URL } = envPublic;
const { SERVER_API_TOKEN } = envPrivate;

// NOTE: Supports cases where `content-type` is other than `json`
const getBody = <T>(c: Response | Request): Promise<T> => {
Expand All @@ -25,50 +24,32 @@ const getUrl = (contextUrl: string): string => {
return requestUrl.toString();
};

// NOTE: Add headers
const getHeaders = (headers?: HeadersInit): HeadersInit => {
// NOTE: Returns null when called outside of a request (e.g. at build time)
const tryGetRequestEvent = () => {
try {
const { request } = getRequestEvent();

// Convert the request Headers object to a plain object
const requestHeadersObj: Record<string, string> = {};
request.headers.forEach((value, key) => {
requestHeadersObj[key] = value;
});

const mergedHeaders: HeadersInit = {
...requestHeadersObj,
...headers,
"X-API-Token": SERVER_API_TOKEN
};

return mergedHeaders;
return getRequestEvent();
} catch {
return {
...headers,
"X-API-Token": SERVER_API_TOKEN
};
return null;
}
};

export const customFetch = async <T>(url: string, options: RequestInit): Promise<T> => {
let fetchFunction = fetch;
try {
const event = getRequestEvent();
fetchFunction = event.fetch;
} catch {
// Ignore this, we just won't have access to the request for this call
}
const event = tryGetRequestEvent();

const requestUrl = getUrl(url);
const requestHeaders = getHeaders(options.headers);
// Deployed Workers get a Secrets Store binding; local dev and prerender get a plain string
const token = event?.platform?.env.SERVER_API_TOKEN ?? envPrivate.SERVER_API_TOKEN;
const serverApiToken = typeof token === "string" ? token : await token.get();

const requestInit: RequestInit = {
...options,
headers: requestHeaders
headers: {
...(event ? Object.fromEntries(event.request.headers) : {}),
...options.headers,
"X-API-Token": serverApiToken
}
};

const response = await fetchFunction(requestUrl, requestInit);
const response = await (event?.fetch ?? fetch)(getUrl(url), requestInit);
const data = await getBody<T>(response);

return { status: response.status, data, headers: response.headers } as T;
Expand Down
18 changes: 16 additions & 2 deletions wrangler.jsonc
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,14 @@
"vars": {
"PUBLIC_SERVER_API_URL": "https://sky.shiiyu.moe/api/",
"PUBLIC_API_URL": "https://sky.shiiyu.moe/api/"
}
},
"secrets_store_secrets": [
{
"binding": "SERVER_API_TOKEN",
"store_id": "1a9462229b034bc78858f53bc58fb477",
"secret_name": "skycrypt-server-api-key"
}
]
},
"development": {
"name": "skycrypt-embed",
Expand All @@ -60,7 +67,14 @@
"vars": {
"PUBLIC_SERVER_API_URL": "https://sky.shiiyu.moe/api/",
"PUBLIC_API_URL": "https://sky.shiiyu.moe/api/"
}
},
"secrets_store_secrets": [
{
"binding": "SERVER_API_TOKEN",
"store_id": "739b83a68daf486ea3ec077b812048b4",
"secret_name": "skycrypt-server-api-key"
}
]
}
}
}
Loading