UNPKG

bknd

Version:

Lightweight Firebase/Supabase alternative built to run anywhere — incl. Next.js, React Router, Astro, Cloudflare, Bun, Node, AWS Lambda & more.

132 lines (131 loc) 3.8 kB
// src/adapter/index.ts import { config as $config, App, Connection, guessMimeType, registries as $registries } from "bknd"; import { $console } from "bknd/utils"; async function makeConfig(config, args) { let additionalConfig = {}; const { app, ...rest } = config; if (app) { if (typeof app === "function") { if (!args) { throw new Error("args is required when config.app is a function"); } additionalConfig = await app(args); } else { additionalConfig = app; } } return { ...rest, ...additionalConfig }; } async function createAdapterApp(config = {}, args) { await config.beforeBuild?.(void 0, $registries); const appConfig = await makeConfig(config, args); if (!appConfig.connection || !Connection.isConnection(appConfig.connection)) { let connection; if (Connection.isConnection(config.connection)) { connection = config.connection; } else { const sqlite = (await import("bknd/adapter/sqlite")).sqlite; const conf = appConfig.connection ?? { url: "file:data.db" }; connection = sqlite(conf); $console.info(`Using ${connection.name} connection`, conf.url); } appConfig.connection = connection; } return { app: App.create(appConfig), config: appConfig }; } async function createFrameworkApp(config = {}, args) { const { app, config: appConfig } = await createAdapterApp(config, args); if (!app.isBuilt()) { if (config.onBuilt) { app.emgr.onEvent( App.Events.AppBuiltEvent, async () => { await appConfig.onBuilt?.(app); }, "sync" ); } await appConfig.beforeBuild?.(app, $registries); await app.build(config.buildConfig); } return app; } async function createRuntimeApp({ serveStatic, adminOptions, ...config } = {}, args) { const { app, config: appConfig } = await createAdapterApp(config, args); if (!app.isBuilt()) { app.emgr.onEvent( App.Events.AppBuiltEvent, async () => { if (serveStatic) { const [path, handler] = Array.isArray(serveStatic) ? serveStatic : [$config.server.assets_path + "*", serveStatic]; app.modules.server.get(path, handler); } await appConfig.onBuilt?.(app); if (adminOptions !== false) { app.registerAdminController(adminOptions); } }, "sync" ); await appConfig.beforeBuild?.(app, $registries); await app.build(config.buildConfig); } return app; } function serveStaticViaImport(opts) { let files; const pkg = opts?.package ?? "bknd"; return async (c, next) => { if (!files) { const manifest = opts?.manifest || (await import( /* @vite-ignore */ `${pkg}/dist/manifest.json`, { with: { type: "json" } } )).default; files = Object.values(manifest).flatMap((asset) => [asset.file, ...asset.css || []]); } const path = c.req.path.substring(1); if (files.includes(path)) { try { const url = `${pkg}/static/${path}${opts?.appendRaw ? "?raw" : ""}`; const content = await import( /* @vite-ignore */ url, { with: { type: "text" } } ).then((m) => m.default); if (content) { return c.body(content, { headers: { "Content-Type": guessMimeType(path), "Cache-Control": "public, max-age=31536000, immutable" } }); } } catch (e) { console.error(`Error serving static file "${path}":`, String(e)); return c.text("File not found", 404); } } await next(); }; } export { createAdapterApp, createFrameworkApp, createRuntimeApp, makeConfig, serveStaticViaImport };