This commit is contained in:
2026-02-17 03:53:59 +05:30
commit dcb19e0a2f
28 changed files with 2766 additions and 0 deletions

26
server/api/todo.post.ts Normal file
View File

@@ -0,0 +1,26 @@
import { getApi } from "../utils/bknd";
export default defineEventHandler(async (event) => {
const body = await readBody(event);
const { action, data } = body;
const api = await getApi({});
switch (action) {
case 'get':
const limit = 5;
const todos = await api.data.readMany("todos", { limit, sort: "-id" });
return { total: todos.body.meta.total, todos, limit };
case 'create':
return await api.data.createOne("todos", { title: data.title });
case 'delete':
return await api.data.deleteOne("todos", data.id);
case 'toggle':
return await api.data.updateOne("todos", data.id, { done: !data.done });
default:
throw createError({ statusCode: 400, statusMessage: "Invalid Action" });
}
});

7
server/api/user.get.ts Normal file
View File

@@ -0,0 +1,7 @@
import { getApi } from "../utils/bknd";
export default defineEventHandler(async (event) => {
const api = await getApi({ verify: true, headers: event.headers });
const user = api.getUser();
return { user };
});

44
server/middleware/bknd.ts Normal file
View File

@@ -0,0 +1,44 @@
import { type RuntimeBkndConfig } from "bknd/adapter";
import config from "../../bknd.config";
import { getApp } from "../utils/bknd";
function serve(config: RuntimeBkndConfig) {
return async (request: Request) => {
const app = await getApp(config, process.env);
return app.fetch(request);
};
}
export default defineEventHandler(async (event) => {
const request = toWebRequest(event);
const url = new URL(request.url);
const isMethodWithBody = ["POST", "PUT", "PATCH", "DELETE"].includes(
request.method,
);
const adminBasepath = config.adminOptions.adminBasepath;
// if (adminBasepath.endsWith("/")) adminBasepath.slice(0, -1);
if (
url.pathname.startsWith("/api") ||
url.pathname.startsWith(adminBasepath)
) {
if (url.pathname === adminBasepath + "/") {
url.pathname = url.pathname.slice(0, -1);
} else {
url.pathname = url.pathname.replaceAll("//", "/");
}
const modifiedRequest = new Request(url.toString(), {
method: request.method,
headers: request.headers as HeadersInit,
// @ts-expect-error - 'duplex' is required for streaming bodies in Node.js
duplex: isMethodWithBody ? "half" : undefined,
body: isMethodWithBody ? request.body : undefined,
});
const res = await serve(config)(modifiedRequest);
if (res && res.status !== 404) {
return res;
}
}
});

27
server/utils/bknd.ts Normal file
View File

@@ -0,0 +1,27 @@
import { createRuntimeApp, type RuntimeBkndConfig } from "bknd/adapter";
import bkndConfig from "../../bknd.config";
export async function getApp<Env = NodeJS.ProcessEnv>(
config: RuntimeBkndConfig<Env>,
args: Env = process.env as Env,
) {
return await createRuntimeApp(config, args);
}
export async function getApi({
headers,
verify,
}: {
verify?: boolean;
headers?: Headers;
}) {
const app = await getApp(bkndConfig, process.env);
if (verify) {
const api = app.getApi({ headers });
await api.verifyAuth();
return api;
}
return app.getApi();
}