Compare commits

..

8 Commits

22 changed files with 66 additions and 105 deletions
-2
View File
@@ -15,7 +15,6 @@ describe("AppServer", () => {
}, },
mcp: { mcp: {
enabled: false, enabled: false,
path: "/api/system/mcp",
}, },
}); });
} }
@@ -37,7 +36,6 @@ describe("AppServer", () => {
}, },
mcp: { mcp: {
enabled: false, enabled: false,
path: "/api/system/mcp",
}, },
}); });
} }
+7 -7
View File
@@ -3,7 +3,7 @@
"type": "module", "type": "module",
"sideEffects": false, "sideEffects": false,
"bin": "./dist/cli/index.js", "bin": "./dist/cli/index.js",
"version": "0.17.0", "version": "0.16.1",
"description": "Lightweight Firebase/Supabase alternative built to run anywhere — incl. Next.js, React Router, Astro, Cloudflare, Bun, Node, AWS Lambda & more.", "description": "Lightweight Firebase/Supabase alternative built to run anywhere — incl. Next.js, React Router, Astro, Cloudflare, Bun, Node, AWS Lambda & more.",
"homepage": "https://bknd.io", "homepage": "https://bknd.io",
"repository": { "repository": {
@@ -39,11 +39,11 @@
"test:adapters": "bun test src/adapter/**/*.adapter.spec.ts --bail", "test:adapters": "bun test src/adapter/**/*.adapter.spec.ts --bail",
"test:coverage": "ALL_TESTS=1 bun test --bail --coverage", "test:coverage": "ALL_TESTS=1 bun test --bail --coverage",
"test:vitest:coverage": "vitest run --coverage", "test:vitest:coverage": "vitest run --coverage",
"test:e2e": "VITE_DB_URL=:memory: playwright test", "test:e2e": "playwright test",
"test:e2e:adapters": "VITE_DB_URL=:memory: bun run e2e/adapters.ts", "test:e2e:adapters": "bun run e2e/adapters.ts",
"test:e2e:ui": "VITE_DB_URL=:memory: playwright test --ui", "test:e2e:ui": "playwright test --ui",
"test:e2e:debug": "VITE_DB_URL=:memory: playwright test --debug", "test:e2e:debug": "playwright test --debug",
"test:e2e:report": "VITE_DB_URL=:memory: playwright show-report", "test:e2e:report": "playwright show-report",
"docs:build-assets": "bun internal/docs.build-assets.ts" "docs:build-assets": "bun internal/docs.build-assets.ts"
}, },
"license": "FSL-1.1-MIT", "license": "FSL-1.1-MIT",
@@ -65,7 +65,7 @@
"hono": "4.8.3", "hono": "4.8.3",
"json-schema-library": "10.0.0-rc7", "json-schema-library": "10.0.0-rc7",
"json-schema-to-ts": "^3.1.1", "json-schema-to-ts": "^3.1.1",
"jsonv-ts": "0.8.2", "jsonv-ts": "^0.8.1",
"kysely": "0.27.6", "kysely": "0.27.6",
"lodash-es": "^4.17.21", "lodash-es": "^4.17.21",
"oauth4webapi": "^2.11.1", "oauth4webapi": "^2.11.1",
+1 -2
View File
@@ -293,10 +293,9 @@ export class App<C extends Connection = Connection, Options extends AppOptions =
if (!this.mcp) { if (!this.mcp) {
throw new Error("MCP is not enabled"); throw new Error("MCP is not enabled");
} }
const mcpPath = this.modules.get("server").config.mcp.path;
return new McpClient({ return new McpClient({
url: "http://localhost" + mcpPath, url: "http://localhost/mcp",
fetch: this.server.request, fetch: this.server.request,
}); });
} }
+1 -1
View File
@@ -15,7 +15,7 @@ export {
export { constants } from "./config"; export { constants } from "./config";
export { StorageR2Adapter, registerMedia } from "./storage/StorageR2Adapter"; export { StorageR2Adapter, registerMedia } from "./storage/StorageR2Adapter";
export { registries } from "bknd"; export { registries } from "bknd";
export { devFsVitePlugin, devFsWrite } from "./vite"; export { devFsPlugin, devFsWrite } from "./vite";
// for compatibility with old code // for compatibility with old code
export function d1<DB extends D1Database | D1DatabaseSession = D1Database>( export function d1<DB extends D1Database | D1DatabaseSession = D1Database>(
+10 -2
View File
@@ -1,5 +1,13 @@
import { mark, stripMark, $console, s, objectEach, transformObject, McpServer } from "bknd/utils"; import {
import { DebugLogger } from "core/utils/DebugLogger"; mark,
stripMark,
$console,
s,
objectEach,
transformObject,
McpServer,
DebugLogger,
} from "bknd/utils";
import { Guard } from "auth/authorize/Guard"; import { Guard } from "auth/authorize/Guard";
import { env } from "core/env"; import { env } from "core/env";
import { BkndError } from "core/errors"; import { BkndError } from "core/errors";
-1
View File
@@ -24,7 +24,6 @@ export const serverConfigSchema = $object(
}), }),
mcp: s.strictObject({ mcp: s.strictObject({
enabled: s.boolean({ default: false }), enabled: s.boolean({ default: false }),
path: s.string({ default: "/api/system/mcp" }),
}), }),
}, },
{ {
+3 -4
View File
@@ -60,9 +60,8 @@ export class SystemController extends Controller {
register(app: App) { register(app: App) {
app.server.route("/api/system", this.getController()); app.server.route("/api/system", this.getController());
const config = app.modules.get("server").config;
if (!config.mcp.enabled) { if (!this.app.modules.get("server").config.mcp.enabled) {
return; return;
} }
@@ -85,7 +84,7 @@ export class SystemController extends Controller {
const level = consoleMap[message.params.level]; const level = consoleMap[message.params.level];
if (!level) return; if (!level) return;
$console[level]("MCP notification", message.params.message ?? message.params); $console[level](message.params.message);
} }
}); });
@@ -98,7 +97,7 @@ export class SystemController extends Controller {
explainEndpoint: true, explainEndpoint: true,
}, },
endpoint: { endpoint: {
path: config.mcp.path as any, path: "/mcp",
// @ts-ignore // @ts-ignore
_init: isNode() ? { duplex: "half" } : {}, _init: isNode() ? { duplex: "half" } : {},
}, },
+2 -3
View File
@@ -20,9 +20,8 @@ const style = {
basicChildStyle: "pl-5 ml-1 border-l border-muted hover:border-primary/20", basicChildStyle: "pl-5 ml-1 border-l border-muted hover:border-primary/20",
container: "ml-[-10px]", container: "ml-[-10px]",
label: "text-primary/90 font-bold font-mono mr-2", label: "text-primary/90 font-bold font-mono mr-2",
stringValue: stringValue: "text-emerald-600 dark:text-emerald-500 font-mono select-text",
"text-emerald-600 dark:text-emerald-500 font-mono select-text text-wrap whitespace-wrap break-words", numberValue: "text-sky-500 dark:text-sky-400 font-mono",
numberValue: "text-sky-500 dark:text-sky-400 font-mono select-text",
nullValue: "text-zinc-400 font-mono", nullValue: "text-zinc-400 font-mono",
undefinedValue: "text-zinc-400 font-mono", undefinedValue: "text-zinc-400 font-mono",
otherValue: "text-zinc-400 font-mono", otherValue: "text-zinc-400 font-mono",
-8
View File
@@ -13,14 +13,6 @@ const Warning = ({ className, ...props }: IconProps) => (
/> />
); );
const Err = ({ className, ...props }: IconProps) => (
<TbAlertCircle
{...props}
className={twMerge("dark:text-red-300 text-red-700 cursor-help", className)}
/>
);
export const Icon = { export const Icon = {
Warning, Warning,
Err,
}; };
+2 -14
View File
@@ -1,6 +1,6 @@
import { useClickOutside, useHotkeys } from "@mantine/hooks"; import { useClickOutside, useHotkeys } from "@mantine/hooks";
import { IconChevronDown, IconChevronUp } from "@tabler/icons-react"; import { IconChevronDown, IconChevronUp } from "@tabler/icons-react";
import { transformObject, clampNumber } from "bknd/utils"; import { clampNumber } from "core/utils/numbers";
import { throttle } from "lodash-es"; import { throttle } from "lodash-es";
import { ScrollArea } from "radix-ui"; import { ScrollArea } from "radix-ui";
import { import {
@@ -19,21 +19,9 @@ import { appShellStore } from "ui/store";
import { useLocation } from "wouter"; import { useLocation } from "wouter";
export function Root({ children }: { children: React.ReactNode }) { export function Root({ children }: { children: React.ReactNode }) {
const sidebarWidths = appShellStore((store) => store.sidebars);
const style = transformObject(sidebarWidths, (value) => value.width);
return ( return (
<AppShellProvider> <AppShellProvider>
<div <div id="app-shell" data-shell="root" className="flex flex-1 flex-col select-none h-dvh">
id="app-shell"
data-shell="root"
className="flex flex-1 flex-col select-none h-dvh"
style={Object.fromEntries(
Object.entries(style).map(([key, value]) => [
`--sidebar-width-${key}`,
`${value}px`,
]),
)}
>
{children} {children}
</div> </div>
</AppShellProvider> </AppShellProvider>
+1 -1
View File
@@ -74,7 +74,7 @@
@apply bg-background text-primary overflow-hidden h-dvh w-dvw; @apply bg-background text-primary overflow-hidden h-dvh w-dvw;
::selection { ::selection {
@apply bg-primary/15; @apply bg-muted;
} }
input { input {
+1 -1
View File
@@ -1,7 +1,7 @@
import * as React from "react"; import * as React from "react";
import * as ReactDOM from "react-dom/client"; import * as ReactDOM from "react-dom/client";
import Admin from "./Admin"; import Admin from "./Admin";
//import "./main.css"; import "./main.css";
import "./styles.css"; import "./styles.css";
function render() { function render() {
@@ -1,16 +0,0 @@
import { McpClient, type McpClientConfig } from "jsonv-ts/mcp";
import { useBknd } from "ui/client/bknd";
const clients = new Map<string, McpClient>();
export function getClient(opts: McpClientConfig) {
if (!clients.has(JSON.stringify(opts))) {
clients.set(JSON.stringify(opts), new McpClient(opts));
}
return clients.get(JSON.stringify(opts))!;
}
export function useMcpClient() {
const { config } = useBknd();
return getClient({ url: window.location.origin + config.server.mcp.path });
}
+1 -2
View File
@@ -17,7 +17,6 @@ export default function ToolsMcp() {
const setFeature = useMcpStore((state) => state.setFeature); const setFeature = useMcpStore((state) => state.setFeature);
const content = useMcpStore((state) => state.content); const content = useMcpStore((state) => state.content);
const openSidebar = appShellStore((store) => store.toggleSidebar("default")); const openSidebar = appShellStore((store) => store.toggleSidebar("default"));
const mcpPath = config.server.mcp.path;
if (!config.server.mcp.enabled) { if (!config.server.mcp.enabled) {
return ( return (
@@ -40,7 +39,7 @@ export default function ToolsMcp() {
<TbWorld /> <TbWorld />
<div className="min-w-0 flex-1"> <div className="min-w-0 flex-1">
<span className="block truncate text-sm font-mono leading-none"> <span className="block truncate text-sm font-mono leading-none">
{window.location.origin + mcpPath} {window.location.origin + "/mcp"}
</span> </span>
</div> </div>
</div> </div>
+8 -24
View File
@@ -1,5 +1,5 @@
import { useCallback, useEffect, useRef, useState, useTransition } from "react"; import { useCallback, useEffect, useRef, useState, useTransition } from "react";
import { getTemplate } from "./utils"; import { getClient, getTemplate } from "./utils";
import { useMcpStore } from "./state"; import { useMcpStore } from "./state";
import { AppShell } from "ui/layouts/AppShell"; import { AppShell } from "ui/layouts/AppShell";
import { TbHistory, TbHistoryOff, TbRefresh } from "react-icons/tb"; import { TbHistory, TbHistoryOff, TbRefresh } from "react-icons/tb";
@@ -10,11 +10,9 @@ import { Field, Form } from "ui/components/form/json-schema-form";
import { Button } from "ui/components/buttons/Button"; import { Button } from "ui/components/buttons/Button";
import * as Formy from "ui/components/form/Formy"; import * as Formy from "ui/components/form/Formy";
import { appShellStore } from "ui/store"; import { appShellStore } from "ui/store";
import { Icon } from "ui/components/display/Icon";
import { useMcpClient } from "./hooks/use-mcp-client";
export function Sidebar({ open, toggle }) { export function Sidebar({ open, toggle }) {
const client = useMcpClient(); const client = getClient();
const closeSidebar = appShellStore((store) => store.closeSidebar("default")); const closeSidebar = appShellStore((store) => store.closeSidebar("default"));
const tools = useMcpStore((state) => state.tools); const tools = useMcpStore((state) => state.tools);
const setTools = useMcpStore((state) => state.setTools); const setTools = useMcpStore((state) => state.setTools);
@@ -22,18 +20,11 @@ export function Sidebar({ open, toggle }) {
const content = useMcpStore((state) => state.content); const content = useMcpStore((state) => state.content);
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
const [query, setQuery] = useState<string>(""); const [query, setQuery] = useState<string>("");
const [error, setError] = useState<string | null>(null);
const handleRefresh = useCallback(async () => { const handleRefresh = useCallback(async () => {
setLoading(true); setLoading(true);
setError(null); const res = await client.listTools();
try { if (res) setTools(res.tools);
const res = await client.listTools();
if (res) setTools(res.tools);
} catch (e) {
console.error(e);
setError(String(e));
}
setLoading(false); setLoading(false);
}, []); }, []);
@@ -48,7 +39,6 @@ export function Sidebar({ open, toggle }) {
toggle={toggle} toggle={toggle}
renderHeaderRight={() => ( renderHeaderRight={() => (
<div className="flex flex-row gap-2 items-center"> <div className="flex flex-row gap-2 items-center">
{error && <Icon.Err title={error} className="size-5 pointer-events-auto" />}
<span className="flex-inline bg-primary/10 px-2 py-1.5 rounded-xl text-sm font-mono leading-none"> <span className="flex-inline bg-primary/10 px-2 py-1.5 rounded-xl text-sm font-mono leading-none">
{tools.length} {tools.length}
</span> </span>
@@ -98,7 +88,7 @@ export function Content() {
const [result, setResult] = useState<object | null>(null); const [result, setResult] = useState<object | null>(null);
const historyVisible = useMcpStore((state) => state.historyVisible); const historyVisible = useMcpStore((state) => state.historyVisible);
const setHistoryVisible = useMcpStore((state) => state.setHistoryVisible); const setHistoryVisible = useMcpStore((state) => state.setHistoryVisible);
const client = useMcpClient(); const client = getClient();
const jsonViewerTabsRef = useRef<JsonViewerTabsRef>(null); const jsonViewerTabsRef = useRef<JsonViewerTabsRef>(null);
const hasInputSchema = const hasInputSchema =
content?.inputSchema && Object.keys(content.inputSchema.properties ?? {}).length > 0; content?.inputSchema && Object.keys(content.inputSchema.properties ?? {}).length > 0;
@@ -139,7 +129,7 @@ export function Content() {
return ( return (
<Form <Form
className="flex flex-grow flex-col min-w-0 max-w-screen" className="flex flex-grow flex-col max-w-screen"
key={content.name} key={content.name}
schema={{ schema={{
title: "InputSchema", title: "InputSchema",
@@ -180,12 +170,7 @@ export function Content() {
</AppShell.SectionHeaderTitle> </AppShell.SectionHeaderTitle>
</AppShell.SectionHeader> </AppShell.SectionHeader>
<div className="flex flex-grow flex-row w-vw"> <div className="flex flex-grow flex-row w-vw">
<div <div className="flex flex-grow flex-col w-full">
className="flex flex-grow flex-col max-w-full"
style={{
width: "calc(100% - var(--sidebar-width-right) - 1px)",
}}
>
<AppShell.Scrollable> <AppShell.Scrollable>
<div key={JSON.stringify(content)} className="flex flex-col py-4 px-5 gap-4"> <div key={JSON.stringify(content)} className="flex flex-col py-4 px-5 gap-4">
<p className="text-primary/80">{content?.description}</p> <p className="text-primary/80">{content?.description}</p>
@@ -234,9 +219,8 @@ const History = () => {
<JsonViewer <JsonViewer
key={`${item.type}-${i}`} key={`${item.type}-${i}`}
json={item.data} json={item.data}
title={item.type.substring(0, 3)} title={item.type}
expand={2} expand={2}
showCopy
/> />
))} ))}
</div> </div>
+12
View File
@@ -1,5 +1,17 @@
import { McpClient, type McpClientConfig } from "jsonv-ts/mcp";
import { Draft2019 } from "json-schema-library"; import { Draft2019 } from "json-schema-library";
const clients = new Map<string, McpClient>();
export function getClient(
{ url, ...opts }: McpClientConfig = { url: window.location.origin + "/mcp" },
) {
if (!clients.has(String(url))) {
clients.set(String(url), new McpClient({ url, ...opts }));
}
return clients.get(String(url))!;
}
export function getTemplate(schema: object) { export function getTemplate(schema: object) {
if (!schema || schema === undefined || schema === null) return undefined; if (!schema || schema === undefined || schema === null) return undefined;
+3 -3
View File
@@ -15,7 +15,7 @@
}, },
"app": { "app": {
"name": "bknd", "name": "bknd",
"version": "0.17.0-rc.1", "version": "0.16.1",
"bin": "./dist/cli/index.js", "bin": "./dist/cli/index.js",
"dependencies": { "dependencies": {
"@cfworker/json-schema": "^4.1.1", "@cfworker/json-schema": "^4.1.1",
@@ -35,7 +35,7 @@
"hono": "4.8.3", "hono": "4.8.3",
"json-schema-library": "10.0.0-rc7", "json-schema-library": "10.0.0-rc7",
"json-schema-to-ts": "^3.1.1", "json-schema-to-ts": "^3.1.1",
"jsonv-ts": "0.8.2", "jsonv-ts": "^0.8.1",
"kysely": "0.27.6", "kysely": "0.27.6",
"lodash-es": "^4.17.21", "lodash-es": "^4.17.21",
"oauth4webapi": "^2.11.1", "oauth4webapi": "^2.11.1",
@@ -2516,7 +2516,7 @@
"jsonpointer": ["jsonpointer@5.0.1", "", {}, "sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ=="], "jsonpointer": ["jsonpointer@5.0.1", "", {}, "sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ=="],
"jsonv-ts": ["jsonv-ts@0.8.2", "", { "optionalDependencies": { "hono": "*" }, "peerDependencies": { "typescript": "^5.0.0" } }, "sha512-1Z7+maCfoGGqBPu5vN8rU9gIsW7OatYmn+STBTPkybbtNqeMzAoJDDrXHjsZ89x5dPH9W+OgMpNLtN0ouwiMYg=="], "jsonv-ts": ["jsonv-ts@0.8.1", "", { "optionalDependencies": { "hono": "*" }, "peerDependencies": { "typescript": "^5.0.0" } }, "sha512-kqt1OHZ4WM92PDAxySZeGGzccZr6q5YdKpM8c7QWkwGoaa1azwTG5lV9SN3PT4kVgI0OYFDr3OGkgCszLQ+WPw=="],
"jsonwebtoken": ["jsonwebtoken@9.0.2", "", { "dependencies": { "jws": "^3.2.2", "lodash.includes": "^4.3.0", "lodash.isboolean": "^3.0.3", "lodash.isinteger": "^4.0.4", "lodash.isnumber": "^3.0.3", "lodash.isplainobject": "^4.0.6", "lodash.isstring": "^4.0.1", "lodash.once": "^4.0.0", "ms": "^2.1.1", "semver": "^7.5.4" } }, "sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ=="], "jsonwebtoken": ["jsonwebtoken@9.0.2", "", { "dependencies": { "jws": "^3.2.2", "lodash.includes": "^4.3.0", "lodash.isboolean": "^3.0.3", "lodash.isinteger": "^4.0.4", "lodash.isnumber": "^3.0.3", "lodash.isplainobject": "^4.0.6", "lodash.isstring": "^4.0.1", "lodash.once": "^4.0.0", "ms": "^2.1.1", "semver": "^7.5.4" } }, "sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ=="],
@@ -29,15 +29,15 @@ const app = createApp();
app.emgr.onEvent(AppEvents.AppRequest, async (event) => { app.emgr.onEvent(AppEvents.AppRequest, async (event) => {
// ^? AppRequest // ^? AppRequest
console.log("Request received", event.params.request.url); console.log("Request received", event.request.url);
}); });
app.emgr.on("app-request", async (event) => { app.emgr.on("app-request", async (event) => {
console.log("Request received", event.params.request.url); console.log("Request received", event.request.url);
}); });
app.emgr.onAny(async (event, name) => { app.emgr.onAny(async (event) => {
console.log("Event received", event, name); console.log("Event received", event.slug);
}); });
``` ```
@@ -49,7 +49,7 @@ import { AppEvents } from "bknd";
export default { export default {
onBuilt: (app) => { onBuilt: (app) => {
app.emgr.onEvent(AppEvents.AppRequest, async (event) => { app.emgr.onEvent(AppEvents.AppRequest, async (event) => {
console.log("Request received", event.params.request.url); console.log("Request received", event.request.url);
}); });
}, },
}; };
@@ -63,7 +63,7 @@ By default, listeners are registered as `async` listeners, meaning that the list
app.emgr.onEvent( app.emgr.onEvent(
AppEvents.AppRequest, AppEvents.AppRequest,
async (event) => { async (event) => {
console.log("Request received", event.params.request.url); console.log("Request received", event.request.url);
}, },
{ mode: "sync" }, { mode: "sync" },
); );
@@ -108,7 +108,7 @@ import { config } from "@/bknd";
import { serve } from "bknd/adapter/nextjs"; import { serve } from "bknd/adapter/nextjs";
// optionally, you can set the runtime to edge for better performance // optionally, you can set the runtime to edge for better performance
// export const runtime = "edge"; export const runtime = "edge";
const handler = serve({ const handler = serve({
...config, ...config,
@@ -24,7 +24,7 @@ bknd includes a fully featured MCP server that can be used to interact with the
<source src="/content/mcp/v0.17_mcp_o.mp4" type="video/mp4" /> <source src="/content/mcp/v0.17_mcp_o.mp4" type="video/mp4" />
</video> </video>
Once enabled, you can access the MCP UI at `/mcp`, or choose "MCP" from the top right user menu. Once enabled, you can access the MCP UI at `/mcp` or choose "MCP" from the top right user menu.
## Enable MCP ## Enable MCP
@@ -54,7 +54,7 @@ The implementation is closely following the [MCP spec 2025-06-18](https://modelc
import { McpClient } from "bknd/utils"; import { McpClient } from "bknd/utils";
const client = new McpClient({ const client = new McpClient({
url: "http://localhost:1337/api/system/mcp", url: "http://localhost:1337/mcp",
}); });
``` ```
@@ -128,7 +128,7 @@ Pasting the following config into your Cursor `~/.cursor/mcp.json` file is the r
{ {
"mcpServers": { "mcpServers": {
"bknd": { "bknd": {
"url": "http://localhost:1337/api/system/mcp" "url": "http://localhost:1337/mcp"
} }
} }
} }
@@ -155,7 +155,7 @@ Add this to your VS Code MCP config. See [VS Code MCP docs](https://code.visuals
"servers": { "servers": {
"bknd": { "bknd": {
"type": "http", "type": "http",
"url": "http://localhost:1337/api/system/mcp" "url": "http://localhost:1337/mcp"
} }
} }
} }
@@ -188,7 +188,7 @@ When using the Streamable HTTP transport, you can pass the `Authorization` heade
```typescript ```typescript
const client = new McpClient({ const client = new McpClient({
url: "http://localhost:1337/api/system/mcp", url: "http://localhost:1337/mcp",
headers: { headers: {
Authorization: `Bearer ${token}`, Authorization: `Bearer ${token}`,
}, },
+1 -1
View File
@@ -5,7 +5,7 @@
* We're using separate files, so that "wrangler" doesn't get bundled with your worker. * We're using separate files, so that "wrangler" doesn't get bundled with your worker.
*/ */
import { withPlatformProxy } from "bknd/adapter/cloudflare/proxy"; import { withPlatformProxy } from "bknd/adapter/cloudflare";
import config from "./config.ts"; import config from "./config.ts";
export default withPlatformProxy(config); export default withPlatformProxy(config);
+1 -1
View File
@@ -2,7 +2,7 @@ import type { CloudflareBkndConfig } from "bknd/adapter/cloudflare";
import { syncTypes } from "bknd/plugins"; import { syncTypes } from "bknd/plugins";
import { writeFile } from "node:fs/promises"; import { writeFile } from "node:fs/promises";
const isDev = import.meta.env && !import.meta.env.PROD; const isDev = !import.meta.env.PROD;
export default { export default {
d1: { d1: {