mirror of
https://github.com/bknd-io/bknd/
synced 2026-08-02 08:06:00 +00:00
Refactor: Rename api mode to headless
The 'api' mode is being renamed to 'headless' to better reflect its purpose: serving the API without the admin UI. This change aligns with the existing framework concept of a headless backend. The 'standalone' mode is renamed to 'admin' to indicate that it serves both the API and the admin UI.
This commit is contained in:
@@ -9,33 +9,33 @@ afterAll(enableConsoleLog);
|
|||||||
|
|
||||||
describe("universal adapter via createBknd", () => {
|
describe("universal adapter via createBknd", () => {
|
||||||
adapterTestSuite(bunTestRunner, {
|
adapterTestSuite(bunTestRunner, {
|
||||||
makeApp: (options, args) => createBknd({ mode: "api", options }, args).getApp(),
|
makeApp: (options, args) => createBknd({ mode: "headless", options }, args).getApp(),
|
||||||
makeHandler: (options, args) => createBknd({ mode: "api", options: options ?? {} }, args).serve(),
|
makeHandler: (options, args) => createBknd({ mode: "headless", options: options ?? {} }, args).serve(),
|
||||||
});
|
});
|
||||||
|
|
||||||
// ------------------------ MODE API ------------------------
|
// ------------------------ MODE HEADLESS ------------------------
|
||||||
test("caches app instance", async () => {
|
test("caches app instance", async () => {
|
||||||
const bknd = createBknd({ mode: "api", options: { connection: { url: ":memory:" } } });
|
const bknd = createBknd({ mode: "headless", options: { connection: { url: ":memory:" } } });
|
||||||
const app1 = await bknd.getApp();
|
const app1 = await bknd.getApp();
|
||||||
const app2 = await bknd.getApp();
|
const app2 = await bknd.getApp();
|
||||||
expect(app1).toBe(app2);
|
expect(app1).toBe(app2);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("getApi returns api", async () => {
|
test("getApi returns api", async () => {
|
||||||
const bknd = createBknd({ mode: "api", options: { connection: { url: ":memory:" } } });
|
const bknd = createBknd({ mode: "headless", options: { connection: { url: ":memory:" } } });
|
||||||
const api = await bknd.getApi();
|
const api = await bknd.getApi();
|
||||||
expect(api).toBeDefined();
|
expect(api).toBeDefined();
|
||||||
});
|
});
|
||||||
|
|
||||||
test("uses createFrameworkApp ", async () => {
|
test("uses createFrameworkApp in headless mode", async () => {
|
||||||
const bknd = createBknd({ mode: "api", options: { connection: { url: ":memory:" } } });
|
const bknd = createBknd({ mode: "headless", options: { connection: { url: ":memory:" } } });
|
||||||
const app = await bknd.getApp();
|
const app = await bknd.getApp();
|
||||||
expect(app).toBeDefined();
|
expect(app).toBeDefined();
|
||||||
expect(app.isBuilt()).toBe(true);
|
expect(app.isBuilt()).toBe(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("serve returns a fetch handler", async () => {
|
test("serve returns a fetch handler", async () => {
|
||||||
const bknd = createBknd({ mode: "api", options: { connection: { url: ":memory:" } } });
|
const bknd = createBknd({ mode: "headless", options: { connection: { url: ":memory:" } } });
|
||||||
const handler = bknd.serve();
|
const handler = bknd.serve();
|
||||||
const res = await handler(new Request("http://localhost:3000/api/system/config"));
|
const res = await handler(new Request("http://localhost:3000/api/system/config"));
|
||||||
expect(res.status).toBe(200);
|
expect(res.status).toBe(200);
|
||||||
@@ -43,29 +43,29 @@ describe("universal adapter via createBknd", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
// ------------------------ MODE STANDALONE ------------------------
|
// ------------------------ MODE ADMIN ------------------------
|
||||||
describe("universal adapter via createBknd in standalone mode", () => {
|
describe("universal adapter via createBknd in admin mode", () => {
|
||||||
adapterTestSuite(bunTestRunner, {
|
adapterTestSuite(bunTestRunner, {
|
||||||
makeApp: (options, args) => createBknd({ mode: "standalone", options }, args).getApp(),
|
makeApp: (options, args) => createBknd({ mode: "admin", options }, args).getApp(),
|
||||||
makeHandler: (options, args) => createBknd({ mode: "standalone", options: options ?? {} }, args).serve(),
|
makeHandler: (options, args) => createBknd({ mode: "admin", options: options ?? {} }, args).serve(),
|
||||||
});
|
});
|
||||||
|
|
||||||
test("caches app instance", async () => {
|
test("caches app instance", async () => {
|
||||||
const bknd = createBknd({ mode: "standalone", options: { connection: { url: ":memory:" } } });
|
const bknd = createBknd({ mode: "admin", options: { connection: { url: ":memory:" } } });
|
||||||
const app1 = await bknd.getApp();
|
const app1 = await bknd.getApp();
|
||||||
const app2 = await bknd.getApp();
|
const app2 = await bknd.getApp();
|
||||||
expect(app1).toBe(app2);
|
expect(app1).toBe(app2);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("getApi returns api", async () => {
|
test("getApi returns api", async () => {
|
||||||
const bknd = createBknd({ mode: "standalone", options: { connection: { url: ":memory:" } } });
|
const bknd = createBknd({ mode: "admin", options: { connection: { url: ":memory:" } } });
|
||||||
const api = await bknd.getApi();
|
const api = await bknd.getApi();
|
||||||
expect(api).toBeDefined();
|
expect(api).toBeDefined();
|
||||||
});
|
});
|
||||||
|
|
||||||
test("uses createRuntimeApp", async () => {
|
test("uses createRuntimeApp in admin mode", async () => {
|
||||||
const bknd = createBknd({
|
const bknd = createBknd({
|
||||||
mode: "standalone",
|
mode: "admin",
|
||||||
options: {
|
options: {
|
||||||
connection: { url: ":memory:" },
|
connection: { url: ":memory:" },
|
||||||
adminOptions: { adminBasepath: "/admin" },
|
adminOptions: { adminBasepath: "/admin" },
|
||||||
@@ -78,7 +78,7 @@ describe("universal adapter via createBknd in standalone mode", () => {
|
|||||||
|
|
||||||
test("serve returns a fetch handler", async () => {
|
test("serve returns a fetch handler", async () => {
|
||||||
const bknd = createBknd({
|
const bknd = createBknd({
|
||||||
mode: "standalone",
|
mode: "admin",
|
||||||
options: {
|
options: {
|
||||||
connection: { url: ":memory:" },
|
connection: { url: ":memory:" },
|
||||||
adminOptions: { adminBasepath: "/admin" },
|
adminOptions: { adminBasepath: "/admin" },
|
||||||
@@ -91,7 +91,7 @@ describe("universal adapter via createBknd in standalone mode", () => {
|
|||||||
|
|
||||||
test("check admin route", async () => {
|
test("check admin route", async () => {
|
||||||
const bknd = createBknd({
|
const bknd = createBknd({
|
||||||
mode: "standalone",
|
mode: "admin",
|
||||||
options: {
|
options: {
|
||||||
connection: { url: ":memory:" },
|
connection: { url: ":memory:" },
|
||||||
adminOptions: { adminBasepath: "/admin" },
|
adminOptions: { adminBasepath: "/admin" },
|
||||||
|
|||||||
@@ -9,11 +9,13 @@ import type { App } from "App";
|
|||||||
|
|
||||||
export type AdapterModeWithOptions<Env = Record<string, string | undefined>> =
|
export type AdapterModeWithOptions<Env = Record<string, string | undefined>> =
|
||||||
| {
|
| {
|
||||||
mode: "standalone";
|
/** Serves the API along with the admin UI and static assets */
|
||||||
|
mode: "admin";
|
||||||
options: RuntimeBkndConfig<Env>;
|
options: RuntimeBkndConfig<Env>;
|
||||||
}
|
}
|
||||||
| {
|
| {
|
||||||
mode: "api";
|
/** Serves the API only, without the admin UI — use when your framework handles rendering */
|
||||||
|
mode: "headless";
|
||||||
options: FrameworkBkndConfig<Env>;
|
options: FrameworkBkndConfig<Env>;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -24,7 +26,7 @@ export function createBknd<Env>(config: AdapterModeWithOptions<Env>, env?: Env)
|
|||||||
|
|
||||||
async function getApp(): Promise<App> {
|
async function getApp(): Promise<App> {
|
||||||
if (!appPromise) {
|
if (!appPromise) {
|
||||||
if (mode === "standalone") {
|
if (mode === "admin") {
|
||||||
if (options.adminOptions && !options.serveStatic) {
|
if (options.adminOptions && !options.serveStatic) {
|
||||||
$console.warn(
|
$console.warn(
|
||||||
"adminOptions provided without serveStatic — admin UI assets may not be served. " +
|
"adminOptions provided without serveStatic — admin UI assets may not be served. " +
|
||||||
@@ -59,10 +61,11 @@ export function createBknd<Env>(config: AdapterModeWithOptions<Env>, env?: Env)
|
|||||||
return { getApp, getApi, serve };
|
return { getApp, getApi, serve };
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Utility type to determine the config type based on mode,
|
/**
|
||||||
* Usage `Config<"standalone">` or `Config<"api">`
|
* Utility type to determine the config type based on mode,
|
||||||
*/
|
* Usage `Config<"standalone">` or `Config<"api">`
|
||||||
|
*/
|
||||||
export type Config<T extends AdapterModeWithOptions["mode"]> = Extract<
|
export type Config<T extends AdapterModeWithOptions["mode"]> = Extract<
|
||||||
Parameters<typeof createBknd>[0],
|
Parameters<typeof createBknd>[0],
|
||||||
{ mode: T }
|
{ mode: T }
|
||||||
>['options'];
|
>['options'];
|
||||||
|
|||||||
@@ -57,4 +57,4 @@ export default {
|
|||||||
assetsPath: "/admin/",
|
assetsPath: "/admin/",
|
||||||
logoReturnPath: "../..",
|
logoReturnPath: "../..",
|
||||||
},
|
},
|
||||||
} satisfies Config<"standalone">;
|
} satisfies Config<"admin">;
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { createBknd } from "bknd/adapter/universal";
|
|||||||
import bkndConfig from "../../bknd.config";
|
import bkndConfig from "../../bknd.config";
|
||||||
import type { EnvGetter } from "@builder.io/qwik-city/middleware/request-handler";
|
import type { EnvGetter } from "@builder.io/qwik-city/middleware/request-handler";
|
||||||
|
|
||||||
export const getApp = async (env?: EnvGetter) => createBknd({ mode: "standalone", options: bkndConfig }, env);
|
export const getApp = async (env?: EnvGetter) => createBknd({ mode: "admin", options: bkndConfig }, env);
|
||||||
|
|
||||||
export const handler = async (req: Request, env?: EnvGetter) => {
|
export const handler = async (req: Request, env?: EnvGetter) => {
|
||||||
return (await getApp(env)).serve()(req);
|
return (await getApp(env)).serve()(req);
|
||||||
|
|||||||
Reference in New Issue
Block a user