mirror of
https://github.com/shishantbiswas/bknd.git
synced 2026-03-17 04:46:05 +00:00
Merge remote-tracking branch 'origin/main' into release/0.18
# Conflicts: # app/package.json
This commit is contained in:
@@ -43,7 +43,7 @@ export type ApiOptions = {
|
||||
} & (
|
||||
| {
|
||||
token?: string;
|
||||
user?: TApiUser;
|
||||
user?: TApiUser | null;
|
||||
}
|
||||
| {
|
||||
request: Request;
|
||||
|
||||
@@ -153,7 +153,9 @@ export function serveStaticViaImport(opts?: { manifest?: Manifest }) {
|
||||
return async (c: Context, next: Next) => {
|
||||
if (!files) {
|
||||
const manifest =
|
||||
opts?.manifest || ((await import("bknd/dist/manifest.json")).default as Manifest);
|
||||
opts?.manifest ||
|
||||
((await import("bknd/dist/manifest.json", { with: { type: "json" } }))
|
||||
.default as Manifest);
|
||||
files = Object.values(manifest).flatMap((asset) => [asset.file, ...(asset.css || [])]);
|
||||
}
|
||||
|
||||
@@ -161,7 +163,7 @@ export function serveStaticViaImport(opts?: { manifest?: Manifest }) {
|
||||
if (files.includes(path)) {
|
||||
try {
|
||||
const content = await import(/* @vite-ignore */ `bknd/static/${path}?raw`, {
|
||||
assert: { type: "text" },
|
||||
with: { type: "text" },
|
||||
}).then((m) => m.default);
|
||||
|
||||
if (content) {
|
||||
|
||||
@@ -221,6 +221,7 @@ export class AuthController extends Controller {
|
||||
return user;
|
||||
};
|
||||
|
||||
const roles = Object.keys(this.auth.config.roles ?? {});
|
||||
mcp.tool(
|
||||
// @todo: needs permission
|
||||
"auth_user_create",
|
||||
@@ -231,7 +232,7 @@ export class AuthController extends Controller {
|
||||
password: s.string({ minLength: 8 }),
|
||||
role: s
|
||||
.string({
|
||||
enum: Object.keys(this.auth.config.roles ?? {}),
|
||||
enum: roles.length > 0 ? roles : undefined,
|
||||
})
|
||||
.optional(),
|
||||
}),
|
||||
|
||||
@@ -505,3 +505,10 @@ export function deepFreeze<T extends object>(object: T): T {
|
||||
|
||||
return Object.freeze(object);
|
||||
}
|
||||
|
||||
export function convertNumberedObjectToArray(obj: object): any[] | object {
|
||||
if (Object.keys(obj).every((key) => Number.isInteger(Number(key)))) {
|
||||
return Object.values(obj);
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
@@ -1,10 +1,16 @@
|
||||
import { v4, v7 } from "uuid";
|
||||
import { v4, v7, validate, version as uuidVersion } from "uuid";
|
||||
|
||||
// generates v4
|
||||
export function uuid(): string {
|
||||
return v4();
|
||||
return v4();
|
||||
}
|
||||
|
||||
// generates v7
|
||||
export function uuidv7(): string {
|
||||
return v7();
|
||||
return v7();
|
||||
}
|
||||
|
||||
// validate uuid
|
||||
export function uuidValidate(uuid: string, version: 4 | 7): boolean {
|
||||
return validate(uuid) && uuidVersion(uuid) === version;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,15 @@
|
||||
import type { ModuleBuildContext } from "modules";
|
||||
import { Controller } from "modules/Controller";
|
||||
import { jsc, s, describeRoute, schemaToSpec, omitKeys, pickKeys, mcpTool } from "bknd/utils";
|
||||
import {
|
||||
jsc,
|
||||
s,
|
||||
describeRoute,
|
||||
schemaToSpec,
|
||||
omitKeys,
|
||||
pickKeys,
|
||||
mcpTool,
|
||||
convertNumberedObjectToArray,
|
||||
} from "bknd/utils";
|
||||
import * as SystemPermissions from "modules/permissions";
|
||||
import type { AppDataConfig } from "../data-schema";
|
||||
import type { EntityManager, EntityData } from "data/entities";
|
||||
@@ -421,7 +430,13 @@ export class DataController extends Controller {
|
||||
if (!this.entityExists(entity)) {
|
||||
return this.notFound(c);
|
||||
}
|
||||
const body = (await c.req.json()) as EntityData | EntityData[];
|
||||
|
||||
const _body = (await c.req.json()) as EntityData | EntityData[];
|
||||
// @todo: check on jsonv-ts how to handle this better
|
||||
// temporary fix for numbered object to array
|
||||
// this happens when the MCP tool uses the allOf function
|
||||
// to transform all validation targets into a single object
|
||||
const body = convertNumberedObjectToArray(_body);
|
||||
|
||||
if (Array.isArray(body)) {
|
||||
const result = await this.em.mutator(entity).insertMany(body);
|
||||
|
||||
@@ -258,6 +258,9 @@ export class EntityManager<TBD extends object = DefaultDB> {
|
||||
|
||||
// @todo: centralize and add tests
|
||||
hydrate(entity_name: string, _data: EntityData[]) {
|
||||
if (!Array.isArray(_data) || _data.length === 0) {
|
||||
return [];
|
||||
}
|
||||
const entity = this.entity(entity_name);
|
||||
const data: EntityData[] = [];
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ import { css, Style } from "hono/css";
|
||||
import { Controller } from "modules/Controller";
|
||||
import * as SystemPermissions from "modules/permissions";
|
||||
import type { TApiUser } from "Api";
|
||||
import type { Manifest } from "vite";
|
||||
|
||||
const htmlBkndContextReplace = "<!-- BKND_CONTEXT -->";
|
||||
|
||||
@@ -32,6 +33,7 @@ export type AdminControllerOptions = {
|
||||
debugRerenders?: boolean;
|
||||
theme?: "dark" | "light" | "system";
|
||||
logoReturnPath?: string;
|
||||
manifest?: Manifest;
|
||||
};
|
||||
|
||||
export class AdminController extends Controller {
|
||||
@@ -194,8 +196,10 @@ export class AdminController extends Controller {
|
||||
};
|
||||
|
||||
if (isProd) {
|
||||
let manifest: any;
|
||||
if (this.options.assetsPath.startsWith("http")) {
|
||||
let manifest: Manifest;
|
||||
if (this.options.manifest) {
|
||||
manifest = this.options.manifest;
|
||||
} else if (this.options.assetsPath.startsWith("http")) {
|
||||
manifest = await fetch(this.options.assetsPath + ".vite/manifest.json", {
|
||||
headers: {
|
||||
Accept: "application/json",
|
||||
@@ -204,14 +208,14 @@ export class AdminController extends Controller {
|
||||
} else {
|
||||
// @ts-ignore
|
||||
manifest = await import("bknd/dist/manifest.json", {
|
||||
assert: { type: "json" },
|
||||
with: { type: "json" },
|
||||
}).then((res) => res.default);
|
||||
}
|
||||
|
||||
try {
|
||||
// @todo: load all marked as entry (incl. css)
|
||||
assets.js = manifest["src/ui/main.tsx"].file;
|
||||
assets.css = manifest["src/ui/main.tsx"].css[0] as any;
|
||||
assets.js = manifest["src/ui/main.tsx"]?.file!;
|
||||
assets.css = manifest["src/ui/main.tsx"]?.css?.[0] as any;
|
||||
} catch (e) {
|
||||
$console.warn("Couldn't find assets in manifest", e);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user