mirror of
https://github.com/shishantbiswas/bknd.git
synced 2026-03-16 04:27:21 +00:00
added a few initial plugins
This commit is contained in:
@@ -51,6 +51,9 @@ describe("App tests", async () => {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
onBoot: async () => {
|
||||||
|
called.push("onBoot");
|
||||||
|
},
|
||||||
beforeBuild: async () => {
|
beforeBuild: async () => {
|
||||||
called.push("beforeBuild");
|
called.push("beforeBuild");
|
||||||
},
|
},
|
||||||
@@ -90,6 +93,7 @@ describe("App tests", async () => {
|
|||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
expect(called).toEqual([
|
expect(called).toEqual([
|
||||||
|
"onBoot",
|
||||||
"onServerInit",
|
"onServerInit",
|
||||||
"beforeBuild",
|
"beforeBuild",
|
||||||
"onServerInit",
|
"onServerInit",
|
||||||
|
|||||||
@@ -78,6 +78,7 @@ async function buildApi() {
|
|||||||
"src/core/utils/index.ts",
|
"src/core/utils/index.ts",
|
||||||
"src/data/index.ts",
|
"src/data/index.ts",
|
||||||
"src/media/index.ts",
|
"src/media/index.ts",
|
||||||
|
"src/plugins/index.ts",
|
||||||
],
|
],
|
||||||
outDir: "dist",
|
outDir: "dist",
|
||||||
external: [...external],
|
external: [...external],
|
||||||
|
|||||||
@@ -183,6 +183,11 @@
|
|||||||
"import": "./dist/media/index.js",
|
"import": "./dist/media/index.js",
|
||||||
"require": "./dist/media/index.js"
|
"require": "./dist/media/index.js"
|
||||||
},
|
},
|
||||||
|
"./plugins": {
|
||||||
|
"types": "./dist/types/plugins/index.d.ts",
|
||||||
|
"import": "./dist/plugins/index.js",
|
||||||
|
"require": "./dist/plugins/index.js"
|
||||||
|
},
|
||||||
"./adapter/cloudflare": {
|
"./adapter/cloudflare": {
|
||||||
"types": "./dist/types/adapter/cloudflare/index.d.ts",
|
"types": "./dist/types/adapter/cloudflare/index.d.ts",
|
||||||
"import": "./dist/adapter/cloudflare/index.js",
|
"import": "./dist/adapter/cloudflare/index.js",
|
||||||
@@ -231,6 +236,23 @@
|
|||||||
"./dist/styles.css": "./dist/ui/styles.css",
|
"./dist/styles.css": "./dist/ui/styles.css",
|
||||||
"./dist/manifest.json": "./dist/static/.vite/manifest.json"
|
"./dist/manifest.json": "./dist/static/.vite/manifest.json"
|
||||||
},
|
},
|
||||||
|
"typesVersions": {
|
||||||
|
"*": {
|
||||||
|
"data": ["./dist/types/data/index.d.ts"],
|
||||||
|
"core": ["./dist/types/core/index.d.ts"],
|
||||||
|
"utils": ["./dist/types/core/utils/index.d.ts"],
|
||||||
|
"cli": ["./dist/types/cli/index.d.ts"],
|
||||||
|
"media": ["./dist/types/media/index.d.ts"],
|
||||||
|
"plugins": ["./dist/types/plugins/index.d.ts"],
|
||||||
|
"adapter": ["./dist/types/adapter/index.d.ts"],
|
||||||
|
"adapter/cloudflare": ["./dist/types/adapter/cloudflare/index.d.ts"],
|
||||||
|
"adapter/vite": ["./dist/types/adapter/vite/index.d.ts"],
|
||||||
|
"adapter/nextjs": ["./dist/types/adapter/nextjs/index.d.ts"],
|
||||||
|
"adapter/react-router": ["./dist/types/adapter/react-router/index.d.ts"],
|
||||||
|
"adapter/bun": ["./dist/types/adapter/bun/index.d.ts"],
|
||||||
|
"adapter/node": ["./dist/types/adapter/node/index.d.ts"]
|
||||||
|
}
|
||||||
|
},
|
||||||
"publishConfig": {
|
"publishConfig": {
|
||||||
"access": "public"
|
"access": "public"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ export type AppPluginConfig = {
|
|||||||
onBuilt?: () => MaybePromise<void>;
|
onBuilt?: () => MaybePromise<void>;
|
||||||
onServerInit?: (server: Hono<ServerEnv>) => MaybePromise<void>;
|
onServerInit?: (server: Hono<ServerEnv>) => MaybePromise<void>;
|
||||||
onFirstBoot?: () => MaybePromise<void>;
|
onFirstBoot?: () => MaybePromise<void>;
|
||||||
|
onBoot?: () => MaybePromise<void>;
|
||||||
};
|
};
|
||||||
export type AppPlugin = (app: App) => AppPluginConfig;
|
export type AppPlugin = (app: App) => AppPluginConfig;
|
||||||
|
|
||||||
@@ -93,6 +94,7 @@ export class App {
|
|||||||
private options?: AppOptions,
|
private options?: AppOptions,
|
||||||
) {
|
) {
|
||||||
this.plugins = (options?.plugins ?? []).map((plugin) => plugin(this));
|
this.plugins = (options?.plugins ?? []).map((plugin) => plugin(this));
|
||||||
|
this.runPlugins("onBoot");
|
||||||
this.modules = new ModuleManager(connection, {
|
this.modules = new ModuleManager(connection, {
|
||||||
...(options?.manager ?? {}),
|
...(options?.manager ?? {}),
|
||||||
initial: _initialConfig,
|
initial: _initialConfig,
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import { D1Connection, type D1ConnectionConfig } from "./connection/D1Connection";
|
import { D1Connection, type D1ConnectionConfig } from "./connection/D1Connection";
|
||||||
import { ImageOptimizationPlugin } from "./plugins/image-optimization.plugin";
|
|
||||||
|
|
||||||
export * from "./cloudflare-workers.adapter";
|
export * from "./cloudflare-workers.adapter";
|
||||||
export { makeApp, getFresh } from "./modes/fresh";
|
export { makeApp, getFresh } from "./modes/fresh";
|
||||||
@@ -14,9 +13,6 @@ export {
|
|||||||
type BindingMap,
|
type BindingMap,
|
||||||
} from "./bindings";
|
} from "./bindings";
|
||||||
export { constants } from "./config";
|
export { constants } from "./config";
|
||||||
export const plugins = {
|
|
||||||
imageOptimization: ImageOptimizationPlugin,
|
|
||||||
};
|
|
||||||
|
|
||||||
export function d1(config: D1ConnectionConfig) {
|
export function d1(config: D1ConnectionConfig) {
|
||||||
return new D1Connection(config);
|
return new D1Connection(config);
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ export class EntityTypescript {
|
|||||||
return this.em.entities.map((e) => e.toTypes());
|
return this.em.entities.map((e) => e.toTypes());
|
||||||
}
|
}
|
||||||
|
|
||||||
protected getTab(count = 1) {
|
getTab(count = 1) {
|
||||||
return this.options.indentChar.repeat(this.options.indentWidth).repeat(count);
|
return this.options.indentChar.repeat(this.options.indentWidth).repeat(count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -317,6 +317,7 @@ export class SystemController extends Controller {
|
|||||||
local: datetimeStringLocal(),
|
local: datetimeStringLocal(),
|
||||||
utc: datetimeStringUTC(),
|
utc: datetimeStringUTC(),
|
||||||
},
|
},
|
||||||
|
plugins: this.app.plugins.map((p) => p.name),
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -1,18 +1,18 @@
|
|||||||
import type { App, AppPlugin } from "bknd";
|
import type { App, AppPlugin } from "bknd";
|
||||||
|
|
||||||
export type ImageOptimizationPluginOptions = {
|
export type CloudflareImageOptimizationOptions = {
|
||||||
accessUrl?: string;
|
accessUrl?: string;
|
||||||
resolvePath?: string;
|
resolvePath?: string;
|
||||||
autoFormat?: boolean;
|
autoFormat?: boolean;
|
||||||
devBypass?: string;
|
devBypass?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export function ImageOptimizationPlugin({
|
export function cloudflareImageOptimization({
|
||||||
accessUrl = "/_plugin/image/optimize",
|
accessUrl = "/_plugin/image/optimize",
|
||||||
resolvePath = "/api/media/file",
|
resolvePath = "/api/media/file",
|
||||||
autoFormat = true,
|
autoFormat = true,
|
||||||
devBypass,
|
devBypass,
|
||||||
}: ImageOptimizationPluginOptions = {}): AppPlugin {
|
}: CloudflareImageOptimizationOptions = {}): AppPlugin {
|
||||||
const disallowedAccessUrls = ["/api", "/admin", "/_optimize"];
|
const disallowedAccessUrls = ["/api", "/admin", "/_optimize"];
|
||||||
if (disallowedAccessUrls.includes(accessUrl) || accessUrl.length < 2) {
|
if (disallowedAccessUrls.includes(accessUrl) || accessUrl.length < 2) {
|
||||||
throw new Error(`Disallowed accessUrl: ${accessUrl}`);
|
throw new Error(`Disallowed accessUrl: ${accessUrl}`);
|
||||||
18
app/src/plugins/dev/show-routes.plugin.ts
Normal file
18
app/src/plugins/dev/show-routes.plugin.ts
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
import type { App, AppPlugin } from "bknd";
|
||||||
|
import { showRoutes as showRoutesHono } from "hono/dev";
|
||||||
|
|
||||||
|
export type ShowRoutesOptions = {
|
||||||
|
once?: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
export function showRoutes({ once = false }: ShowRoutesOptions = {}): AppPlugin {
|
||||||
|
let shown = false;
|
||||||
|
return (app: App) => ({
|
||||||
|
name: "bknd-show-routes",
|
||||||
|
onBuilt: () => {
|
||||||
|
if (once && shown) return;
|
||||||
|
shown = true;
|
||||||
|
showRoutesHono(app.server);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
35
app/src/plugins/dev/sync-config.plugin.ts
Normal file
35
app/src/plugins/dev/sync-config.plugin.ts
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
import { App, type AppConfig, type AppPlugin } from "bknd";
|
||||||
|
|
||||||
|
export type SyncConfigOptions = {
|
||||||
|
enabled?: boolean;
|
||||||
|
includeSecrets?: boolean;
|
||||||
|
write: (config: AppConfig) => Promise<void>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export function syncConfig({
|
||||||
|
enabled = true,
|
||||||
|
includeSecrets = false,
|
||||||
|
write,
|
||||||
|
}: SyncConfigOptions): AppPlugin {
|
||||||
|
let firstBoot = true;
|
||||||
|
return (app: App) => ({
|
||||||
|
name: "bknd-sync-config",
|
||||||
|
onBuilt: async () => {
|
||||||
|
if (!enabled) return;
|
||||||
|
app.emgr.onEvent(
|
||||||
|
App.Events.AppConfigUpdatedEvent,
|
||||||
|
async () => {
|
||||||
|
await write?.(app.toJSON(includeSecrets));
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "sync-config",
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
if (firstBoot) {
|
||||||
|
firstBoot = false;
|
||||||
|
await write?.(app.toJSON(true));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
31
app/src/plugins/dev/sync-types.plugin.ts
Normal file
31
app/src/plugins/dev/sync-types.plugin.ts
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
import { App, type AppPlugin } from "bknd";
|
||||||
|
import { EntityTypescript } from "data/entities/EntityTypescript";
|
||||||
|
|
||||||
|
export type SyncTypesOptions = {
|
||||||
|
enabled?: boolean;
|
||||||
|
write: (et: EntityTypescript) => Promise<void>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export function syncTypes({ enabled = true, write }: SyncTypesOptions): AppPlugin {
|
||||||
|
let firstBoot = true;
|
||||||
|
return (app: App) => ({
|
||||||
|
name: "bknd-sync-types",
|
||||||
|
onBuilt: async () => {
|
||||||
|
if (!enabled) return;
|
||||||
|
app.emgr.onEvent(
|
||||||
|
App.Events.AppConfigUpdatedEvent,
|
||||||
|
async () => {
|
||||||
|
await write?.(new EntityTypescript(app.em));
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "sync-types",
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
if (firstBoot) {
|
||||||
|
firstBoot = false;
|
||||||
|
await write?.(new EntityTypescript(app.em));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
7
app/src/plugins/index.ts
Normal file
7
app/src/plugins/index.ts
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
export {
|
||||||
|
cloudflareImageOptimization,
|
||||||
|
type CloudflareImageOptimizationOptions,
|
||||||
|
} from "./cloudflare/image-optimization.plugin";
|
||||||
|
export { showRoutes, type ShowRoutesOptions } from "./dev/show-routes.plugin";
|
||||||
|
export { syncConfig, type SyncConfigOptions } from "./dev/sync-config.plugin";
|
||||||
|
export { syncTypes, type SyncTypesOptions } from "./dev/sync-types.plugin";
|
||||||
Reference in New Issue
Block a user