mirror of
https://github.com/shishantbiswas/bknd.git
synced 2026-03-16 04:27:21 +00:00
feat: add schema marking and validation skip mechanism
This commit is contained in:
@@ -12,6 +12,7 @@ export {
|
||||
getMcpServer,
|
||||
stdioTransport,
|
||||
McpClient,
|
||||
logLevels as mcpLogLevels,
|
||||
type McpClientConfig,
|
||||
type ToolAnnotation,
|
||||
type ToolHandlerCtx,
|
||||
@@ -21,8 +22,35 @@ export { secret, SecretSchema } from "./secret";
|
||||
|
||||
export { s };
|
||||
|
||||
export const stripMark = <O extends object>(o: O): O => o;
|
||||
export const mark = <O extends object>(o: O): O => o;
|
||||
const symbol = Symbol("bknd-validation-mark");
|
||||
|
||||
export function stripMark<O = any>(obj: O) {
|
||||
const newObj = structuredClone(obj);
|
||||
mark(newObj, false);
|
||||
return newObj as O;
|
||||
}
|
||||
|
||||
export function mark(obj: any, validated = true) {
|
||||
try {
|
||||
if (typeof obj === "object" && obj !== null && !Array.isArray(obj)) {
|
||||
if (validated) {
|
||||
obj[symbol] = true;
|
||||
} else {
|
||||
delete obj[symbol];
|
||||
}
|
||||
for (const key in obj) {
|
||||
if (typeof obj[key] === "object" && obj[key] !== null) {
|
||||
mark(obj[key], validated);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e) {}
|
||||
}
|
||||
|
||||
export function isMarked(obj: any) {
|
||||
if (typeof obj !== "object" || obj === null) return false;
|
||||
return obj[symbol] === true;
|
||||
}
|
||||
|
||||
export const stringIdentifier = s.string({
|
||||
pattern: "^[a-zA-Z_][a-zA-Z0-9_]*$",
|
||||
@@ -74,6 +102,10 @@ export function parse<S extends s.Schema, Options extends ParseOptions = ParseOp
|
||||
v: unknown,
|
||||
opts?: Options,
|
||||
): Options extends { coerce: true } ? s.StaticCoerced<S> : s.Static<S> {
|
||||
if (!opts?.forceParse && !opts?.coerce && isMarked(v)) {
|
||||
return v as any;
|
||||
}
|
||||
|
||||
const schema = (opts?.clone ? cloneSchema(_schema as any) : _schema) as s.Schema;
|
||||
let value =
|
||||
opts?.coerce !== false
|
||||
|
||||
@@ -1,4 +1,12 @@
|
||||
import { objectEach, transformObject, McpServer, type s, SecretSchema, setPath } from "bknd/utils";
|
||||
import {
|
||||
objectEach,
|
||||
transformObject,
|
||||
McpServer,
|
||||
type s,
|
||||
SecretSchema,
|
||||
setPath,
|
||||
mark,
|
||||
} from "bknd/utils";
|
||||
import { DebugLogger } from "core/utils/DebugLogger";
|
||||
import { Guard } from "auth/authorize/Guard";
|
||||
import { env } from "core/env";
|
||||
@@ -65,7 +73,7 @@ export type ModuleManagerOptions = {
|
||||
// callback after server was created
|
||||
onServerInit?: (server: Hono<ServerEnv>) => void;
|
||||
// doesn't perform validity checks for given/fetched config
|
||||
trustFetched?: boolean;
|
||||
skipValidation?: boolean;
|
||||
// runs when initial config provided on a fresh database
|
||||
seed?: (ctx: ModuleBuildContext) => Promise<void>;
|
||||
// called right after modules are built, before finish
|
||||
@@ -124,7 +132,12 @@ export class ModuleManager {
|
||||
this.emgr = new EventManager({ ...ModuleManagerEvents });
|
||||
this.logger = new DebugLogger(debug_modules);
|
||||
|
||||
this.createModules(options?.initial ?? {});
|
||||
const config = options?.initial ?? {};
|
||||
if (options?.skipValidation) {
|
||||
mark(config, true);
|
||||
}
|
||||
|
||||
this.createModules(config);
|
||||
}
|
||||
|
||||
protected onModuleConfigUpdated(key: string, config: any) {}
|
||||
|
||||
@@ -380,8 +380,8 @@ export class DbModuleManager extends ModuleManager {
|
||||
}
|
||||
}
|
||||
|
||||
if (this.options?.trustFetched === true) {
|
||||
this.logger.log("trusting fetched config (mark)");
|
||||
if (this.options?.skipValidation === true) {
|
||||
this.logger.log("skipping validation (mark)");
|
||||
mark(result.configs.json);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user