diff --git a/app/src/adapter/bun/bun.adapter.ts b/app/src/adapter/bun/bun.adapter.ts index ae14be5..05079e2 100644 --- a/app/src/adapter/bun/bun.adapter.ts +++ b/app/src/adapter/bun/bun.adapter.ts @@ -6,14 +6,25 @@ import type { Serve, ServeOptions } from "bun"; import { serveStatic } from "hono/bun"; let app: App; -export async function createApp(_config: Partial = {}, distPath?: string) { +export type ExtendedAppCreateConfig = Partial & { + distPath?: string; + onBuilt?: (app: App) => Promise; + buildOptions?: Parameters[0]; +}; + +export async function createApp({ + distPath, + onBuilt, + buildOptions, + ...config +}: ExtendedAppCreateConfig) { const root = path.resolve(distPath ?? "./node_modules/bknd/dist", "static"); if (!app) { - app = App.create(_config); + app = App.create(config); - app.emgr.on( - "app-built", + app.emgr.onEvent( + App.Events.AppBuiltEvent, async () => { app.modules.server.get( "/*", @@ -22,20 +33,18 @@ export async function createApp(_config: Partial = {}, distPath }) ); app.registerAdminController(); + await onBuilt?.(app); }, "sync" ); - await app.build(); + await app.build(buildOptions); } return app; } -export type BunAdapterOptions = Omit & - CreateAppConfig & { - distPath?: string; - }; +export type BunAdapterOptions = Omit & ExtendedAppCreateConfig; export function serve({ distPath, @@ -44,13 +53,23 @@ export function serve({ plugins, options, port = 1337, + onBuilt, + buildOptions, ...serveOptions }: BunAdapterOptions = {}) { Bun.serve({ ...serveOptions, port, 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); } }); diff --git a/app/src/adapter/node/node.adapter.ts b/app/src/adapter/node/node.adapter.ts index 47d4c97..6cd6ab1 100644 --- a/app/src/adapter/node/node.adapter.ts +++ b/app/src/adapter/node/node.adapter.ts @@ -8,6 +8,8 @@ export type NodeAdapterOptions = CreateAppConfig & { port?: number; hostname?: string; listener?: Parameters[1]; + onBuilt?: (app: App) => Promise; + buildOptions?: Parameters[0]; }; export function serve({ @@ -15,6 +17,8 @@ export function serve({ port = 1337, hostname, listener, + onBuilt, + buildOptions = {}, ...config }: NodeAdapterOptions = {}) { const root = path.relative( @@ -31,8 +35,8 @@ export function serve({ if (!app) { app = App.create(config); - app.emgr.on( - "app-built", + app.emgr.onEvent( + App.Events.AppBuiltEvent, async () => { app.modules.server.get( "/*", @@ -41,11 +45,12 @@ export function serve({ }) ); app.registerAdminController(); + await onBuilt?.(app); }, "sync" ); - await app.build(); + await app.build(buildOptions); } return app.fetch(req); diff --git a/app/src/adapter/vite/vite.adapter.ts b/app/src/adapter/vite/vite.adapter.ts index 6faaefe..448f50d 100644 --- a/app/src/adapter/vite/vite.adapter.ts +++ b/app/src/adapter/vite/vite.adapter.ts @@ -8,8 +8,8 @@ function createApp(config: BkndConfig, env: any) { } function setAppBuildListener(app: App, config: BkndConfig, html?: string) { - app.emgr.on( - "app-built", + app.emgr.onEvent( + App.Events.AppBuiltEvent, async () => { await config.onBuilt?.(app); if (config.setAdminHtml) { diff --git a/app/src/auth/authenticate/Authenticator.ts b/app/src/auth/authenticate/Authenticator.ts index 426023b..46fa586 100644 --- a/app/src/auth/authenticate/Authenticator.ts +++ b/app/src/auth/authenticate/Authenticator.ts @@ -220,15 +220,23 @@ export class Authenticator = Record< } private async getAuthCookie(c: Context): Promise { - const secret = this.config.jwt.secret; + try { + const secret = this.config.jwt.secret; + + const token = await getSignedCookie(c, secret, "auth"); + if (typeof token !== "string") { + await deleteCookie(c, "auth", this.cookieOptions); + return undefined; + } + + return token; + } catch (e: any) { + if (e instanceof Error) { + console.error("[Error:getAuthCookie]", e.message); + } - const token = await getSignedCookie(c, secret, "auth"); - if (typeof token !== "string") { - await deleteCookie(c, "auth", this.cookieOptions); return undefined; } - - return token; } async requestCookieRefresh(c: Context) { diff --git a/app/src/cli/commands/run/run.ts b/app/src/cli/commands/run/run.ts index 7ad9568..2e1fb32 100644 --- a/app/src/cli/commands/run/run.ts +++ b/app/src/cli/commands/run/run.ts @@ -1,8 +1,10 @@ import type { Config } from "@libsql/client/node"; import { App, type CreateAppConfig } from "App"; import type { BkndConfig } from "adapter"; +import { StorageLocalAdapter } from "adapter/node"; import type { CliCommand } from "cli/types"; import { Option } from "commander"; +import { registries } from "modules/registries"; import { PLATFORMS, type Platform, @@ -37,6 +39,12 @@ export const run: CliCommand = (program) => { .action(action); }; +// automatically register local adapter +const local = StorageLocalAdapter.prototype.getName(); +if (!registries.media.has(local)) { + registries.media.register(local, StorageLocalAdapter); +} + type MakeAppConfig = { connection?: CreateAppConfig["connection"]; server?: { platform?: Platform }; @@ -47,8 +55,8 @@ type MakeAppConfig = { async function makeApp(config: MakeAppConfig) { const app = App.create({ connection: config.connection }); - app.emgr.on( - "app-built", + app.emgr.onEvent( + App.Events.AppBuiltEvent, async () => { await attachServeStatic(app, config.server?.platform ?? "node"); 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 app = App.create(appConfig); - app.emgr.on( - "app-built", + app.emgr.onEvent( + App.Events.AppBuiltEvent, async () => { await attachServeStatic(app, platform ?? "node"); app.registerAdminController(); diff --git a/app/src/core/object/SchemaObject.ts b/app/src/core/object/SchemaObject.ts index c70ef28..aad5b14 100644 --- a/app/src/core/object/SchemaObject.ts +++ b/app/src/core/object/SchemaObject.ts @@ -69,7 +69,8 @@ export class SchemaObject { forceParse: true, 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._config = Object.freeze(updatedConfig); diff --git a/app/src/core/registry/Registry.ts b/app/src/core/registry/Registry.ts index 1fc78bb..b895f51 100644 --- a/app/src/core/registry/Registry.ts +++ b/app/src/core/registry/Registry.ts @@ -41,6 +41,10 @@ export class Registry< return this.items[name]; } + has(name: keyof Items): boolean { + return name in this.items; + } + all() { return this.items; } diff --git a/app/src/media/storage/adapters/StorageLocalAdapter/StorageLocalAdapter.ts b/app/src/media/storage/adapters/StorageLocalAdapter/StorageLocalAdapter.ts index f6c1bb1..f483eeb 100644 --- a/app/src/media/storage/adapters/StorageLocalAdapter/StorageLocalAdapter.ts +++ b/app/src/media/storage/adapters/StorageLocalAdapter/StorageLocalAdapter.ts @@ -1,17 +1,11 @@ import { readFile, readdir, stat, unlink, writeFile } from "node:fs/promises"; import { type Static, Type, parse } from "core/utils"; -import type { - FileBody, - FileListObject, - FileMeta, - FileUploadPayload, - StorageAdapter -} from "../../Storage"; +import type { FileBody, FileListObject, FileMeta, StorageAdapter } from "../../Storage"; import { guessMimeType } from "../../mime-types"; export const localAdapterConfig = Type.Object( { - path: Type.String() + path: Type.String({ default: "./" }) }, { title: "Local" } ); diff --git a/app/vite.dev.ts b/app/vite.dev.ts index bed5beb..6050997 100644 --- a/app/vite.dev.ts +++ b/app/vite.dev.ts @@ -20,8 +20,8 @@ export default { async fetch(request: Request) { const app = App.create({ connection }); - app.emgr.on( - "app-built", + app.emgr.onEvent( + App.Events.AppBuiltEvent, async () => { app.registerAdminController({ forceDev: true }); app.module.server.client.get("/assets/*", serveStatic({ root: "./" }));