@lucidcms/cloudflare-adapter
Version:
The official Cloudflare Worker adapter for Lucid CMS
208 lines (198 loc) • 6.88 kB
JavaScript
import { serve } from "@hono/node-server";
import { Hono } from "hono";
import { build } from "rolldown";
import lucid from "@lucidcms/core";
import { getVitePaths, stripAdapterExportPlugin, stripImportsPlugin } from "@lucidcms/core/helpers";
import { unlink, writeFile } from "node:fs/promises";
import { getPlatformProxy } from "wrangler";
import { serveStatic } from "@hono/node-server/serve-static";
import { relative } from "node:path";
import { readFileSync } from "node:fs";
//#region src/constants.ts
const ADAPTER_KEY = "cloudflare";
const LUCID_VERSION = "0.x.x";
var constants_default = {
CONFIG_FILE: "lucid.config.js",
ENTRY_FILE: "server.js"
};
//#endregion
//#region src/adapter.ts
const cloudflareAdapter = (options) => {
let platformProxy;
return {
key: ADAPTER_KEY,
lucid: LUCID_VERSION,
getEnvVars: async () => {
platformProxy = await getPlatformProxy(options?.platformProxy);
return platformProxy.env;
},
cli: {
serve: async (config, logger) => {
const startTime = process.hrtime();
logger.serverStarting("Cloudflare");
const cloudflareApp = new Hono();
cloudflareApp.use("*", async (c, next) => {
c.env = Object.assign(c.env, platformProxy.env);
c.set("cf", platformProxy.cf);
c.set("caches", platformProxy.caches);
c.set("ctx", {
waitUntil: platformProxy?.ctx.waitUntil,
passThroughOnException: platformProxy?.ctx.passThroughOnException
});
await next();
});
const app = await lucid.createApp({
config,
app: cloudflareApp,
hono: { extensions: [async (app$1, con) => {
const paths = getVitePaths(con);
app$1.use("/*", serveStatic({ rewriteRequestPath: (path) => {
const relativeClientDist = relative(process.cwd(), paths.publicDist);
return `${relativeClientDist}${path}`;
} }));
app$1.get("/admin", (c) => {
const html = readFileSync(paths.clientDistHtml, "utf-8");
return c.html(html);
});
app$1.get("/admin/*", (c) => {
const html = readFileSync(paths.clientDistHtml, "utf-8");
return c.html(html);
});
}] }
});
const server = serve({
fetch: app.fetch,
port: options?.server?.port ?? 6543,
hostname: options?.server?.hostname
});
server.on("listening", () => {
const address = server.address();
logger.serverStarted(address, startTime);
});
return async () => {
return new Promise((resolve, reject) => {
server.close((error) => {
if (error) reject(error);
else resolve();
});
});
};
},
build: async (_, options$1, logger) => {
const startTime = logger.appBuildStart("Cloudflare");
try {
const entryOutput = `${options$1.outputPath}/${constants_default.ENTRY_FILE}`;
const relativePath = relative(options$1.outputPath, options$1.configPath);
const importPath = relativePath.replace(/\.ts$/, ".js");
const configIsTs = options$1.configPath.endsWith(".ts");
const tempEntryFile = `${options$1.outputPath}/temp-entry.${configIsTs ? "ts" : "js"}`;
const entry = `
import config from "./${importPath}";
import lucid from "@lucidcms/core";
import { processConfig } from "@lucidcms/core/helpers";
import emailTemplates from './email-templates.json' with { type: 'json' };
export default {
async fetch(request, env, ctx) {
const resolved = await processConfig(config(env, {
emailTemplates: emailTemplates,
}));
const app = await lucid.createApp({
config: resolved,
hono: {
middleware: [
async (app, config) => {
app.use("*", async (c, next) => {
c.env = Object.assign(c.env, env);
c.set("cf", env.cf);
c.set("caches", env.caches);
c.set("ctx", {
waitUntil: ctx.waitUntil,
passThroughOnException: ctx.passThroughOnException,
});
await next();
})
}
],
extensions: [
async (app, config) => {
app.get("/admin/*", async (c) => {
const url = new URL(c.req.url);
const indexRequestUrl = url.origin + "/admin/index.html";
const indexRequest = new Request(indexRequestUrl);
const indexAsset = await c.env.ASSETS.fetch(indexRequest);
return new Response(indexAsset.body, {
status: indexAsset.status,
headers: indexAsset.headers,
});
});
},
],
}
});
return app.fetch(request, env, ctx);
},
async scheduled(controller, env, ctx) {
const runCronService = async () => {
const resolved = await processConfig(config(env));
const cronJobs = lucid.setupCronJobs({
config: resolved,
});
await cronJobs.register();
};
ctx.waitUntil(runCronService());
},
};`;
await writeFile(tempEntryFile, entry);
await build({
input: tempEntryFile,
output: {
file: entryOutput,
format: "esm",
minify: true,
inlineDynamicImports: true
},
treeshake: true,
platform: "node",
plugins: [
{
name: "import-meta-polyfill",
renderChunk(code) {
return code.replace(/import\.meta\.url/g, "\"file:///server.js\"");
}
},
stripAdapterExportPlugin("cloudflareAdapter"),
stripImportsPlugin("cloudflare-adapter", [
"wrangler",
"@hono/node-server",
"@hono/node-server/serve-static",
"rolldown"
])
],
external: ["sharp", "ws"]
});
await unlink(tempEntryFile);
logger.appBuildComplete(startTime);
} catch (error) {
logger.buildFailed(error);
throw error;
}
}
}
};
};
var adapter_default = cloudflareAdapter;
//#endregion
//#region src/define-config.ts
const defineConfig = (factory) => {
return (env, meta) => {
const lucidConfig = factory(env, meta);
return {
...lucidConfig,
preRenderedEmailTemplates: meta?.emailTemplates ? Object.fromEntries(Object.entries(meta?.emailTemplates).map(([key, value]) => [key, value.html])) : void 0
};
};
};
var define_config_default = defineConfig;
//#endregion
export { adapter_default as cloudflareAdapter, define_config_default as defineConfig };
//# sourceMappingURL=index.js.map