mirror of
https://github.com/shishantbiswas/bknd.git
synced 2026-03-16 12:37:20 +00:00
updated remix adapter for non-middleware env, fixed console mute
This commit is contained in:
@@ -1,4 +1,6 @@
|
||||
import type { CreateUserPayload } from "auth/AppAuth";
|
||||
import { Api, type ApiOptions } from "bknd/client";
|
||||
import { $console } from "core";
|
||||
import { Event } from "core/events";
|
||||
import { Connection, type LibSqlCredentials, LibsqlConnection } from "data";
|
||||
import type { Hono } from "hono";
|
||||
@@ -69,17 +71,17 @@ export class App {
|
||||
// respond to events, such as "onUpdated".
|
||||
// this is important if multiple changes are done, and then build() is called manually
|
||||
if (!this.emgr.enabled) {
|
||||
console.warn("App config updated, but event manager is disabled, skip.");
|
||||
$console.warn("App config updated, but event manager is disabled, skip.");
|
||||
return;
|
||||
}
|
||||
|
||||
console.log("App config updated", key);
|
||||
$console.log("App config updated", key);
|
||||
// @todo: potentially double syncing
|
||||
await this.build({ sync: true });
|
||||
await this.emgr.emit(new AppConfigUpdatedEvent({ app: this }));
|
||||
},
|
||||
onFirstBoot: async () => {
|
||||
console.log("App first boot");
|
||||
$console.log("App first boot");
|
||||
this.trigger_first_boot = true;
|
||||
},
|
||||
onServerInit: async (server) => {
|
||||
@@ -177,6 +179,15 @@ export class App {
|
||||
async createUser(p: CreateUserPayload) {
|
||||
return this.module.auth.createUser(p);
|
||||
}
|
||||
|
||||
getApi(options: Request | ApiOptions = {}) {
|
||||
const fetcher = this.server.request as typeof fetch;
|
||||
if (options instanceof Request) {
|
||||
return new Api({ request: options, headers: options.headers, fetcher });
|
||||
}
|
||||
|
||||
return new Api({ host: "http://localhost", ...options, fetcher });
|
||||
}
|
||||
}
|
||||
|
||||
export function createApp(config: CreateAppConfig = {}) {
|
||||
@@ -187,7 +198,7 @@ export function createApp(config: CreateAppConfig = {}) {
|
||||
connection = config.connection;
|
||||
} else if (typeof config.connection === "object") {
|
||||
if ("type" in config.connection) {
|
||||
console.warn(
|
||||
$console.warn(
|
||||
"Using deprecated connection type 'libsql', use the 'config' object directly."
|
||||
);
|
||||
connection = new LibsqlConnection(config.connection.config);
|
||||
@@ -196,10 +207,10 @@ export function createApp(config: CreateAppConfig = {}) {
|
||||
}
|
||||
} else {
|
||||
connection = new LibsqlConnection({ url: ":memory:" });
|
||||
console.warn("No connection provided, using in-memory database");
|
||||
$console.warn("No connection provided, using in-memory database");
|
||||
}
|
||||
} catch (e) {
|
||||
console.error("Could not create connection", e);
|
||||
$console.error("Could not create connection", e);
|
||||
}
|
||||
|
||||
if (!connection) {
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import type { App } from "bknd";
|
||||
import { type FrameworkBkndConfig, createFrameworkApp } from "bknd/adapter";
|
||||
import { Api } from "bknd/client";
|
||||
|
||||
export type RemixBkndConfig<Args = RemixContext> = FrameworkBkndConfig<Args>;
|
||||
|
||||
@@ -9,29 +8,30 @@ type RemixContext = {
|
||||
};
|
||||
|
||||
let app: App;
|
||||
let building: boolean = false;
|
||||
|
||||
export async function getApp(config: RemixBkndConfig, args?: RemixContext) {
|
||||
if (building) {
|
||||
while (building) {
|
||||
await new Promise((resolve) => setTimeout(resolve, 5));
|
||||
}
|
||||
if (app) return app;
|
||||
}
|
||||
|
||||
building = true;
|
||||
if (!app) {
|
||||
app = await createFrameworkApp(config, args);
|
||||
await app.build();
|
||||
}
|
||||
building = false;
|
||||
return app;
|
||||
}
|
||||
|
||||
export function serve<Args extends RemixContext = RemixContext>(
|
||||
config: RemixBkndConfig<Args> = {}
|
||||
) {
|
||||
return async (args: Args) => {
|
||||
if (!app) {
|
||||
app = await createFrameworkApp(config, args);
|
||||
}
|
||||
app = await createFrameworkApp(config, args);
|
||||
return app.fetch(args.request);
|
||||
};
|
||||
}
|
||||
|
||||
export function withApi<Args extends { request: Request; context: { api: Api } }, R>(
|
||||
handler: (args: Args, api: Api) => Promise<R>
|
||||
) {
|
||||
return async (args: Args) => {
|
||||
if (!args.context.api) {
|
||||
args.context.api = new Api({
|
||||
host: new URL(args.request.url).origin,
|
||||
headers: args.request.headers
|
||||
});
|
||||
await args.context.api.verifyAuth();
|
||||
}
|
||||
|
||||
return handler(args, args.context.api);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import type { CliCommand } from "cli/types";
|
||||
import { typewriter, wait } from "cli/utils/cli";
|
||||
import { execAsync, getVersion } from "cli/utils/sys";
|
||||
import { Option } from "commander";
|
||||
import { colorizeConsole } from "core";
|
||||
import color from "picocolors";
|
||||
import { overridePackageJson, updateBkndPackages } from "./npm";
|
||||
import { type Template, templates } from "./templates";
|
||||
@@ -47,6 +48,7 @@ function errorOutro() {
|
||||
}
|
||||
|
||||
async function action(options: { template?: string; dir?: string; integration?: string }) {
|
||||
colorizeConsole(console);
|
||||
console.log("");
|
||||
|
||||
const downloadOpts = {
|
||||
|
||||
@@ -36,7 +36,6 @@ const subjects = {
|
||||
};
|
||||
|
||||
async function action(subject: string) {
|
||||
console.log("debug", { subject });
|
||||
if (subject in subjects) {
|
||||
await subjects[subject]();
|
||||
} else {
|
||||
|
||||
@@ -2,9 +2,8 @@ import type { Config } from "@libsql/client/node";
|
||||
import { App, type CreateAppConfig } from "App";
|
||||
import { StorageLocalAdapter } from "adapter/node";
|
||||
import type { CliBkndConfig, CliCommand } from "cli/types";
|
||||
import { replaceConsole } from "cli/utils/cli";
|
||||
import { Option } from "commander";
|
||||
import { config } from "core";
|
||||
import { colorizeConsole, config } from "core";
|
||||
import dotenv from "dotenv";
|
||||
import { registries } from "modules/registries";
|
||||
import c from "picocolors";
|
||||
@@ -112,7 +111,7 @@ async function action(options: {
|
||||
dbToken?: string;
|
||||
server: Platform;
|
||||
}) {
|
||||
replaceConsole();
|
||||
colorizeConsole(console);
|
||||
const configFilePath = await getConfigPath(options.config);
|
||||
|
||||
let app: App | undefined = undefined;
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
import { isDebug } from "core";
|
||||
import c from "picocolors";
|
||||
import type { Formatter } from "picocolors/types";
|
||||
const _SPEEDUP = process.env.LOCAL;
|
||||
|
||||
const DEFAULT_WAIT = _SPEEDUP ? 0 : 250;
|
||||
@@ -57,31 +54,3 @@ export async function* typewriter(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function ifString(args: any[], c: Formatter) {
|
||||
return args.map((a) => (typeof a === "string" ? c(a) : a));
|
||||
}
|
||||
|
||||
const originalConsole = {
|
||||
log: console.log,
|
||||
info: console.info,
|
||||
debug: console.debug,
|
||||
warn: console.warn,
|
||||
error: console.error
|
||||
};
|
||||
|
||||
export const $console = {
|
||||
log: (...args: any[]) => originalConsole.info(c.gray("[LOG] "), ...ifString(args, c.dim)),
|
||||
info: (...args: any[]) => originalConsole.info(c.cyan("[INFO] "), ...args),
|
||||
debug: (...args: any[]) => isDebug() && originalConsole.info(c.yellow("[DEBUG]"), ...args),
|
||||
warn: (...args: any[]) => originalConsole.info(c.yellow("[WARN] "), ...ifString(args, c.yellow)),
|
||||
error: (...args: any[]) => originalConsole.info(c.red("[ERROR]"), ...ifString(args, c.red))
|
||||
};
|
||||
|
||||
export function replaceConsole() {
|
||||
console.log = $console.log;
|
||||
console.info = $console.info;
|
||||
console.debug = $console.debug;
|
||||
console.warn = $console.warn;
|
||||
console.error = $console.error;
|
||||
}
|
||||
|
||||
105
app/src/core/console.ts
Normal file
105
app/src/core/console.ts
Normal file
@@ -0,0 +1,105 @@
|
||||
import colors from "picocolors";
|
||||
|
||||
function hasColors() {
|
||||
try {
|
||||
// biome-ignore lint/style/useSingleVarDeclarator: <explanation>
|
||||
const p = process || {},
|
||||
argv = p.argv || [],
|
||||
env = p.env || {};
|
||||
return (
|
||||
!(!!env.NO_COLOR || argv.includes("--no-color")) &&
|
||||
// biome-ignore lint/complexity/useOptionalChain: <explanation>
|
||||
(!!env.FORCE_COLOR ||
|
||||
argv.includes("--color") ||
|
||||
p.platform === "win32" ||
|
||||
((p.stdout || {}).isTTY && env.TERM !== "dumb") ||
|
||||
!!env.CI)
|
||||
);
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
const originalConsoles = {
|
||||
error: console.error,
|
||||
warn: console.warn,
|
||||
info: console.info,
|
||||
log: console.log,
|
||||
debug: console.debug
|
||||
} as typeof console;
|
||||
|
||||
function __tty(type: any, args: any[]) {
|
||||
const has = hasColors();
|
||||
const styles = {
|
||||
error: {
|
||||
prefix: colors.red,
|
||||
args: colors.red
|
||||
},
|
||||
warn: {
|
||||
prefix: colors.yellow,
|
||||
args: colors.yellow
|
||||
},
|
||||
info: {
|
||||
prefix: colors.cyan
|
||||
},
|
||||
log: {
|
||||
prefix: colors.gray
|
||||
},
|
||||
debug: {
|
||||
prefix: colors.yellow
|
||||
}
|
||||
} as const;
|
||||
const prefix = styles[type].prefix(
|
||||
`[${type.toUpperCase()}]${has ? " ".repeat(5 - type.length) : ""}`
|
||||
);
|
||||
const _args = args.map((a) =>
|
||||
"args" in styles[type] && has && typeof a === "string" ? styles[type].args(a) : a
|
||||
);
|
||||
return originalConsoles[type](prefix, ..._args);
|
||||
}
|
||||
|
||||
export type TConsoleSeverity = keyof typeof originalConsoles;
|
||||
const severities = Object.keys(originalConsoles) as TConsoleSeverity[];
|
||||
|
||||
let enabled = [...severities];
|
||||
|
||||
export function disableConsole(severities: TConsoleSeverity[] = enabled) {
|
||||
enabled = enabled.filter((s) => !severities.includes(s));
|
||||
}
|
||||
|
||||
export function enableConsole() {
|
||||
enabled = [...severities];
|
||||
}
|
||||
|
||||
export const $console = new Proxy(
|
||||
{},
|
||||
{
|
||||
get: (_, prop) => {
|
||||
if (prop in originalConsoles && enabled.includes(prop as TConsoleSeverity)) {
|
||||
return (...args: any[]) => __tty(prop, args);
|
||||
}
|
||||
return () => null;
|
||||
}
|
||||
}
|
||||
) as typeof console;
|
||||
|
||||
export async function withDisabledConsole<R>(
|
||||
fn: () => Promise<R>,
|
||||
sev?: TConsoleSeverity[]
|
||||
): Promise<R> {
|
||||
disableConsole(sev);
|
||||
try {
|
||||
const result = await fn();
|
||||
enableConsole();
|
||||
return result;
|
||||
} catch (e) {
|
||||
enableConsole();
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
export function colorizeConsole(con: typeof console) {
|
||||
for (const [key] of Object.entries(originalConsoles)) {
|
||||
con[key] = $console[key];
|
||||
}
|
||||
}
|
||||
@@ -26,6 +26,8 @@ export {
|
||||
} from "./object/query/query";
|
||||
export { Registry, type Constructor } from "./registry/Registry";
|
||||
|
||||
export * from "./console";
|
||||
|
||||
// compatibility
|
||||
export type Middleware = MiddlewareHandler<any, any, any>;
|
||||
export interface ClassController {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import type { DB as DefaultDB, PrimaryFieldType } from "core";
|
||||
import { $console } from "core";
|
||||
import { type EmitsEvents, EventManager } from "core/events";
|
||||
import { type SelectQueryBuilder, sql } from "kysely";
|
||||
import { cloneDeep } from "lodash-es";
|
||||
@@ -161,7 +162,7 @@ export class Repository<TBD extends object = DefaultDB, TB extends keyof TBD = a
|
||||
protected async performQuery(qb: RepositoryQB): Promise<RepositoryResponse> {
|
||||
const entity = this.entity;
|
||||
const compiled = qb.compile();
|
||||
//console.log("performQuery", compiled.sql, compiled.parameters);
|
||||
//$console.log("performQuery", compiled.sql, compiled.parameters);
|
||||
|
||||
const start = performance.now();
|
||||
const selector = (as = "count") => this.conn.fn.countAll<number>().as(as);
|
||||
@@ -180,7 +181,7 @@ export class Repository<TBD extends object = DefaultDB, TB extends keyof TBD = a
|
||||
totalQuery,
|
||||
qb
|
||||
]);
|
||||
//console.log("result", { _count, _total });
|
||||
//$console.log("result", { _count, _total });
|
||||
|
||||
const time = Number.parseFloat((performance.now() - start).toFixed(2));
|
||||
const data = this.em.hydrate(entity.name, result);
|
||||
@@ -201,7 +202,7 @@ export class Repository<TBD extends object = DefaultDB, TB extends keyof TBD = a
|
||||
};
|
||||
} catch (e) {
|
||||
if (e instanceof Error) {
|
||||
console.error("[ERROR] Repository.performQuery", e.message);
|
||||
$console.error("[ERROR] Repository.performQuery", e.message);
|
||||
}
|
||||
|
||||
throw e;
|
||||
@@ -254,7 +255,7 @@ export class Repository<TBD extends object = DefaultDB, TB extends keyof TBD = a
|
||||
...config?.defaults
|
||||
};
|
||||
|
||||
/*console.log("build query options", {
|
||||
/*$console.log("build query options", {
|
||||
entity: entity.name,
|
||||
options,
|
||||
config
|
||||
@@ -426,9 +427,9 @@ export class Repository<TBD extends object = DefaultDB, TB extends keyof TBD = a
|
||||
qb = qb.limit(1);
|
||||
|
||||
const compiled = qb.compile();
|
||||
//console.log("exists query", compiled.sql, compiled.parameters);
|
||||
//$console.log("exists query", compiled.sql, compiled.parameters);
|
||||
const result = await qb.execute();
|
||||
//console.log("result", result);
|
||||
//$console.log("result", result);
|
||||
|
||||
return {
|
||||
sql: compiled.sql,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Guard } from "auth";
|
||||
import { BkndError, DebugLogger } from "core";
|
||||
import { BkndError, DebugLogger, withDisabledConsole } from "core";
|
||||
import { EventManager } from "core/events";
|
||||
import { clone, diff } from "core/object/diff";
|
||||
import {
|
||||
@@ -10,8 +10,7 @@ import {
|
||||
mark,
|
||||
objectEach,
|
||||
stripMark,
|
||||
transformObject,
|
||||
withDisabledConsole
|
||||
transformObject
|
||||
} from "core/utils";
|
||||
import {
|
||||
type Connection,
|
||||
|
||||
@@ -17,6 +17,7 @@ export type AdminControllerOptions = {
|
||||
assets_path?: string;
|
||||
html?: string;
|
||||
forceDev?: boolean | { mainPath: string };
|
||||
debug_rerenders?: boolean;
|
||||
};
|
||||
|
||||
export class AdminController extends Controller {
|
||||
@@ -192,10 +193,12 @@ export class AdminController extends Controller {
|
||||
/>
|
||||
<link rel="icon" href={favicon} type="image/x-icon" />
|
||||
<title>BKND</title>
|
||||
{/*<script
|
||||
crossOrigin="anonymous"
|
||||
src="//unpkg.com/react-scan/dist/auto.global.js"
|
||||
/>*/}
|
||||
{this.options.debug_rerenders && (
|
||||
<script
|
||||
crossOrigin="anonymous"
|
||||
src="//unpkg.com/react-scan/dist/auto.global.js"
|
||||
/>
|
||||
)}
|
||||
{isProd ? (
|
||||
<Fragment>
|
||||
<script
|
||||
|
||||
@@ -25,11 +25,11 @@ export const ClientProvider = ({ children, baseUrl, user }: ClientProviderProps)
|
||||
console.warn("wrapped many times, take from context", actualBaseUrl);
|
||||
} else if (typeof window !== "undefined") {
|
||||
actualBaseUrl = window.location.origin;
|
||||
console.log("setting from window", actualBaseUrl);
|
||||
//console.log("setting from window", actualBaseUrl);
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.error("error .....", e);
|
||||
console.error("Error in ClientProvider", e);
|
||||
}
|
||||
|
||||
//console.log("api init", { host: actualBaseUrl, user: user ?? winCtx.user });
|
||||
|
||||
Reference in New Issue
Block a user