Nicholai 16cee69250 __Admin dashboard scaffolded with D1 database and R2 file uploads__
This commit implements the core admin dashboard functionality including NextAuth authentication, Cloudflare D1 database integration with complete schema, and Cloudflare R2 file upload system for portfolio images. Features include artist management, appointment scheduling, and data migration capabilities.
2025-09-17 16:08:34 -06:00

123 lines
4.7 KiB
JavaScript

/**
* Initialization for the workerd runtime.
*
* The file must be imported at the top level the worker.
*/
import { AsyncLocalStorage } from "node:async_hooks";
import process from "node:process";
import stream from "node:stream";
// @ts-expect-error: resolved by wrangler build
import * as nextEnvVars from "./next-env.mjs";
const cloudflareContextALS = new AsyncLocalStorage();
// Note: this symbol needs to be kept in sync with `src/api/get-cloudflare-context.ts`
Object.defineProperty(globalThis, Symbol.for("__cloudflare-context__"), {
get() {
return cloudflareContextALS.getStore();
},
});
/**
* Executes the handler with the Cloudflare context.
*/
export async function runWithCloudflareRequestContext(request, env, ctx, handler) {
init(request, env);
return cloudflareContextALS.run({ env, ctx, cf: request.cf }, handler);
}
let initialized = false;
/**
* Initializes the runtime on the first call,
* no-op on subsequent invocations.
*/
function init(request, env) {
if (initialized) {
return;
}
initialized = true;
const url = new URL(request.url);
initRuntime();
populateProcessEnv(url, env);
}
function initRuntime() {
// Some packages rely on `process.version` and `process.versions.node` (i.e. Jose@4)
// TODO: Remove when https://github.com/unjs/unenv/pull/493 is merged
Object.assign(process, { version: process.version || "v22.14.0" });
// @ts-expect-error Node type does not match workerd
Object.assign(process.versions, { node: "22.14.0", ...process.versions });
globalThis.__dirname ??= "";
globalThis.__filename ??= "";
// Some packages rely on `import.meta.url` but it is undefined in workerd
// For example it causes a bunch of issues, and will make even import crash with payload
import.meta.url ??= "file:///worker.js";
// Do not crash on cache not supported
// https://github.com/cloudflare/workerd/pull/2434
// compatibility flag "cache_option_enabled" -> does not support "force-cache"
const __original_fetch = globalThis.fetch;
globalThis.fetch = (input, init) => {
if (init) {
delete init.cache;
}
return __original_fetch(input, init);
};
const CustomRequest = class extends globalThis.Request {
constructor(input, init) {
if (init) {
delete init.cache;
// https://github.com/cloudflare/workerd/issues/2746
// https://github.com/cloudflare/workerd/issues/3245
Object.defineProperty(init, "body", {
// @ts-ignore
value: init.body instanceof stream.Readable ? ReadableStream.from(init.body) : init.body,
});
}
super(input, init);
}
};
Object.assign(globalThis, {
Request: CustomRequest,
__BUILD_TIMESTAMP_MS__,
__NEXT_BASE_PATH__,
__ASSETS_RUN_WORKER_FIRST__,
__TRAILING_SLASH__,
// The external middleware will use the convertTo function of the `edge` converter
// by default it will try to fetch the request, but since we are running everything in the same worker
// we need to use the request as is.
__dangerous_ON_edge_converter_returns_request: true,
});
}
/**
* Populate process.env with:
* - the environment variables and secrets from the cloudflare platform
* - the variables from Next .env* files
* - the origin resolver information
*/
function populateProcessEnv(url, env) {
for (const [key, value] of Object.entries(env)) {
if (typeof value === "string") {
process.env[key] = value;
}
}
const mode = env.NEXTJS_ENV ?? "production";
if (nextEnvVars[mode]) {
for (const key in nextEnvVars[mode]) {
process.env[key] ??= nextEnvVars[mode][key];
}
}
// Set the default Origin for the origin resolver.
// This is only needed for an external middleware bundle
process.env.OPEN_NEXT_ORIGIN = JSON.stringify({
default: {
host: url.hostname,
protocol: url.protocol.slice(0, -1),
port: url.port,
},
});
/* We need to set this environment variable to make redirects work properly in preview mode.
* Next sets this in standalone mode during `startServer`. Without this the protocol would always be `https` here:
* https://github.com/vercel/next.js/blob/6b1e48080e896e0d44a05fe009cb79d2d3f91774/packages/next/src/server/app-render/action-handler.ts#L307-L316
*/
process.env.__NEXT_PRIVATE_ORIGIN = url.origin;
// `__DEPLOYMENT_ID__` is a string (passed via ESBuild).
if (__DEPLOYMENT_ID__) {
process.env.DEPLOYMENT_ID = __DEPLOYMENT_ID__;
}
}