cli: automatically register local adapter

This commit is contained in:
dswbx
2024-12-10 15:50:41 +01:00
parent 5cca911e9d
commit b7ec4982dc
9 changed files with 75 additions and 36 deletions

View File

@@ -6,14 +6,25 @@ import type { Serve, ServeOptions } from "bun";
import { serveStatic } from "hono/bun"; import { serveStatic } from "hono/bun";
let app: App; let app: App;
export async function createApp(_config: Partial<CreateAppConfig> = {}, distPath?: string) { export type ExtendedAppCreateConfig = Partial<CreateAppConfig> & {
distPath?: string;
onBuilt?: (app: App) => Promise<void>;
buildOptions?: Parameters<App["build"]>[0];
};
export async function createApp({
distPath,
onBuilt,
buildOptions,
...config
}: ExtendedAppCreateConfig) {
const root = path.resolve(distPath ?? "./node_modules/bknd/dist", "static"); const root = path.resolve(distPath ?? "./node_modules/bknd/dist", "static");
if (!app) { if (!app) {
app = App.create(_config); app = App.create(config);
app.emgr.on( app.emgr.onEvent(
"app-built", App.Events.AppBuiltEvent,
async () => { async () => {
app.modules.server.get( app.modules.server.get(
"/*", "/*",
@@ -22,20 +33,18 @@ export async function createApp(_config: Partial<CreateAppConfig> = {}, distPath
}) })
); );
app.registerAdminController(); app.registerAdminController();
await onBuilt?.(app);
}, },
"sync" "sync"
); );
await app.build(); await app.build(buildOptions);
} }
return app; return app;
} }
export type BunAdapterOptions = Omit<ServeOptions, "fetch"> & export type BunAdapterOptions = Omit<ServeOptions, "fetch"> & ExtendedAppCreateConfig;
CreateAppConfig & {
distPath?: string;
};
export function serve({ export function serve({
distPath, distPath,
@@ -44,13 +53,23 @@ export function serve({
plugins, plugins,
options, options,
port = 1337, port = 1337,
onBuilt,
buildOptions,
...serveOptions ...serveOptions
}: BunAdapterOptions = {}) { }: BunAdapterOptions = {}) {
Bun.serve({ Bun.serve({
...serveOptions, ...serveOptions,
port, port,
fetch: async (request: Request) => { fetch: async (request: Request) => {
const app = await createApp({ connection, initialConfig, plugins, options }, distPath); const app = await createApp({
connection,
initialConfig,
plugins,
options,
onBuilt,
buildOptions,
distPath
});
return app.fetch(request); return app.fetch(request);
} }
}); });

View File

@@ -8,6 +8,8 @@ export type NodeAdapterOptions = CreateAppConfig & {
port?: number; port?: number;
hostname?: string; hostname?: string;
listener?: Parameters<typeof honoServe>[1]; listener?: Parameters<typeof honoServe>[1];
onBuilt?: (app: App) => Promise<void>;
buildOptions?: Parameters<App["build"]>[0];
}; };
export function serve({ export function serve({
@@ -15,6 +17,8 @@ export function serve({
port = 1337, port = 1337,
hostname, hostname,
listener, listener,
onBuilt,
buildOptions = {},
...config ...config
}: NodeAdapterOptions = {}) { }: NodeAdapterOptions = {}) {
const root = path.relative( const root = path.relative(
@@ -31,8 +35,8 @@ export function serve({
if (!app) { if (!app) {
app = App.create(config); app = App.create(config);
app.emgr.on( app.emgr.onEvent(
"app-built", App.Events.AppBuiltEvent,
async () => { async () => {
app.modules.server.get( app.modules.server.get(
"/*", "/*",
@@ -41,11 +45,12 @@ export function serve({
}) })
); );
app.registerAdminController(); app.registerAdminController();
await onBuilt?.(app);
}, },
"sync" "sync"
); );
await app.build(); await app.build(buildOptions);
} }
return app.fetch(req); return app.fetch(req);

View File

@@ -8,8 +8,8 @@ function createApp(config: BkndConfig, env: any) {
} }
function setAppBuildListener(app: App, config: BkndConfig, html?: string) { function setAppBuildListener(app: App, config: BkndConfig, html?: string) {
app.emgr.on( app.emgr.onEvent(
"app-built", App.Events.AppBuiltEvent,
async () => { async () => {
await config.onBuilt?.(app); await config.onBuilt?.(app);
if (config.setAdminHtml) { if (config.setAdminHtml) {

View File

@@ -220,6 +220,7 @@ export class Authenticator<Strategies extends Record<string, Strategy> = Record<
} }
private async getAuthCookie(c: Context): Promise<string | undefined> { private async getAuthCookie(c: Context): Promise<string | undefined> {
try {
const secret = this.config.jwt.secret; const secret = this.config.jwt.secret;
const token = await getSignedCookie(c, secret, "auth"); const token = await getSignedCookie(c, secret, "auth");
@@ -229,6 +230,13 @@ export class Authenticator<Strategies extends Record<string, Strategy> = Record<
} }
return token; return token;
} catch (e: any) {
if (e instanceof Error) {
console.error("[Error:getAuthCookie]", e.message);
}
return undefined;
}
} }
async requestCookieRefresh(c: Context) { async requestCookieRefresh(c: Context) {

View File

@@ -1,8 +1,10 @@
import type { Config } from "@libsql/client/node"; import type { Config } from "@libsql/client/node";
import { App, type CreateAppConfig } from "App"; import { App, type CreateAppConfig } from "App";
import type { BkndConfig } from "adapter"; import type { BkndConfig } from "adapter";
import { StorageLocalAdapter } from "adapter/node";
import type { CliCommand } from "cli/types"; import type { CliCommand } from "cli/types";
import { Option } from "commander"; import { Option } from "commander";
import { registries } from "modules/registries";
import { import {
PLATFORMS, PLATFORMS,
type Platform, type Platform,
@@ -37,6 +39,12 @@ export const run: CliCommand = (program) => {
.action(action); .action(action);
}; };
// automatically register local adapter
const local = StorageLocalAdapter.prototype.getName();
if (!registries.media.has(local)) {
registries.media.register(local, StorageLocalAdapter);
}
type MakeAppConfig = { type MakeAppConfig = {
connection?: CreateAppConfig["connection"]; connection?: CreateAppConfig["connection"];
server?: { platform?: Platform }; server?: { platform?: Platform };
@@ -47,8 +55,8 @@ type MakeAppConfig = {
async function makeApp(config: MakeAppConfig) { async function makeApp(config: MakeAppConfig) {
const app = App.create({ connection: config.connection }); const app = App.create({ connection: config.connection });
app.emgr.on( app.emgr.onEvent(
"app-built", App.Events.AppBuiltEvent,
async () => { async () => {
await attachServeStatic(app, config.server?.platform ?? "node"); await attachServeStatic(app, config.server?.platform ?? "node");
app.registerAdminController(); app.registerAdminController();
@@ -68,8 +76,8 @@ export async function makeConfigApp(config: BkndConfig, platform?: Platform) {
const appConfig = typeof config.app === "function" ? config.app(process.env) : config.app; const appConfig = typeof config.app === "function" ? config.app(process.env) : config.app;
const app = App.create(appConfig); const app = App.create(appConfig);
app.emgr.on( app.emgr.onEvent(
"app-built", App.Events.AppBuiltEvent,
async () => { async () => {
await attachServeStatic(app, platform ?? "node"); await attachServeStatic(app, platform ?? "node");
app.registerAdminController(); app.registerAdminController();

View File

@@ -69,7 +69,8 @@ export class SchemaObject<Schema extends TObject> {
forceParse: true, forceParse: true,
skipMark: this.isForceParse() skipMark: this.isForceParse()
}); });
const updatedConfig = noEmit ? valid : await this.onBeforeUpdate(this._config, valid); // regardless of "noEmit" this should always be triggered
const updatedConfig = await this.onBeforeUpdate(this._config, valid);
this._value = updatedConfig; this._value = updatedConfig;
this._config = Object.freeze(updatedConfig); this._config = Object.freeze(updatedConfig);

View File

@@ -41,6 +41,10 @@ export class Registry<
return this.items[name]; return this.items[name];
} }
has(name: keyof Items): boolean {
return name in this.items;
}
all() { all() {
return this.items; return this.items;
} }

View File

@@ -1,17 +1,11 @@
import { readFile, readdir, stat, unlink, writeFile } from "node:fs/promises"; import { readFile, readdir, stat, unlink, writeFile } from "node:fs/promises";
import { type Static, Type, parse } from "core/utils"; import { type Static, Type, parse } from "core/utils";
import type { import type { FileBody, FileListObject, FileMeta, StorageAdapter } from "../../Storage";
FileBody,
FileListObject,
FileMeta,
FileUploadPayload,
StorageAdapter
} from "../../Storage";
import { guessMimeType } from "../../mime-types"; import { guessMimeType } from "../../mime-types";
export const localAdapterConfig = Type.Object( export const localAdapterConfig = Type.Object(
{ {
path: Type.String() path: Type.String({ default: "./" })
}, },
{ title: "Local" } { title: "Local" }
); );

View File

@@ -20,8 +20,8 @@ export default {
async fetch(request: Request) { async fetch(request: Request) {
const app = App.create({ connection }); const app = App.create({ connection });
app.emgr.on( app.emgr.onEvent(
"app-built", App.Events.AppBuiltEvent,
async () => { async () => {
app.registerAdminController({ forceDev: true }); app.registerAdminController({ forceDev: true });
app.module.server.client.get("/assets/*", serveStatic({ root: "./" })); app.module.server.client.get("/assets/*", serveStatic({ root: "./" }));