mirror of
https://github.com/bknd-io/bknd/
synced 2026-08-04 09:06:01 +00:00
refactor/imports (#217)
* refactored core and core/utils imports * refactored core and core/utils imports * refactored media imports * refactored auth imports * refactored data imports * updated package json exports, fixed mm config * fix tests
This commit is contained in:
+1
-1
@@ -1,4 +1,4 @@
|
||||
import type { SafeUser } from "auth";
|
||||
import type { SafeUser } from "bknd";
|
||||
import { AuthApi, type AuthApiOptions } from "auth/api/AuthApi";
|
||||
import { DataApi, type DataApiOptions } from "data/api/DataApi";
|
||||
import { decode } from "hono/jwt";
|
||||
|
||||
@@ -3,10 +3,9 @@
|
||||
import path from "node:path";
|
||||
import { type RuntimeBkndConfig, createRuntimeApp, type RuntimeOptions } from "bknd/adapter";
|
||||
import { registerLocalMediaAdapter } from ".";
|
||||
import { config } from "bknd/core";
|
||||
import { config, type App } from "bknd";
|
||||
import type { ServeOptions } from "bun";
|
||||
import { serveStatic } from "hono/bun";
|
||||
import type { App } from "App";
|
||||
|
||||
type BunEnv = Bun.Env;
|
||||
export type BunBkndConfig<Env = BunEnv> = RuntimeBkndConfig<Env> & Omit<ServeOptions, "fetch">;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Database } from "bun:sqlite";
|
||||
import { genericSqlite, type GenericSqliteConnection } from "bknd/data";
|
||||
import { genericSqlite, type GenericSqliteConnection } from "bknd";
|
||||
|
||||
export type BunSqliteConnection = GenericSqliteConnection<Database>;
|
||||
export type BunSqliteConnectionConfig = {
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
/// <reference types="@cloudflare/workers-types" />
|
||||
|
||||
import { Connection } from "bknd";
|
||||
import { sqlite } from "bknd/adapter/sqlite";
|
||||
import { makeConfig as makeAdapterConfig } from "bknd/adapter";
|
||||
import { registerMedia } from "./storage/StorageR2Adapter";
|
||||
import { getBinding } from "./bindings";
|
||||
import { d1Sqlite } from "./connection/D1Connection";
|
||||
import { Connection } from "bknd/data";
|
||||
import type { CloudflareBkndConfig, CloudflareEnv } from ".";
|
||||
import { App } from "bknd";
|
||||
import { makeConfig as makeAdapterConfig } from "bknd/adapter";
|
||||
import type { Context, ExecutionContext } from "hono";
|
||||
import { $console } from "core/utils";
|
||||
import { setCookie } from "hono/cookie";
|
||||
import { sqlite } from "bknd/adapter/sqlite";
|
||||
|
||||
export const constants = {
|
||||
exec_async_event_id: "cf_register_waituntil",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/// <reference types="@cloudflare/workers-types" />
|
||||
|
||||
import { genericSqlite, type GenericSqliteConnection } from "bknd/data";
|
||||
import { genericSqlite, type GenericSqliteConnection } from "bknd";
|
||||
import type { QueryResult } from "kysely";
|
||||
|
||||
export type D1SqliteConnection = GenericSqliteConnection<D1Database>;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/// <reference types="@cloudflare/workers-types" />
|
||||
|
||||
import { genericSqlite, type GenericSqliteConnection } from "bknd/data";
|
||||
import { genericSqlite, type GenericSqliteConnection } from "bknd";
|
||||
import type { QueryResult } from "kysely";
|
||||
|
||||
export type D1SqliteConnection = GenericSqliteConnection<D1Database>;
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
import { registries } from "bknd";
|
||||
import { isDebug } from "bknd/core";
|
||||
import { guessMimeType as guess, StorageAdapter, type FileBody } from "bknd/media";
|
||||
import { registries, isDebug, guessMimeType } from "bknd";
|
||||
import { getBindings } from "../bindings";
|
||||
import { s } from "bknd/core";
|
||||
import { s } from "bknd/utils";
|
||||
import { StorageAdapter, type FileBody } from "bknd";
|
||||
|
||||
export function makeSchema(bindings: string[] = []) {
|
||||
return s.object(
|
||||
@@ -90,7 +89,7 @@ export class StorageR2Adapter extends StorageAdapter {
|
||||
|
||||
const responseHeaders = new Headers({
|
||||
"Accept-Ranges": "bytes",
|
||||
"Content-Type": guess(key),
|
||||
"Content-Type": guessMimeType(key),
|
||||
});
|
||||
|
||||
const range = headers.has("range");
|
||||
@@ -142,7 +141,7 @@ export class StorageR2Adapter extends StorageAdapter {
|
||||
if (!metadata || Object.keys(metadata).length === 0) {
|
||||
// guessing is especially required for dev environment (miniflare)
|
||||
metadata = {
|
||||
contentType: guess(object.key),
|
||||
contentType: guessMimeType(object.key),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -159,7 +158,7 @@ export class StorageR2Adapter extends StorageAdapter {
|
||||
}
|
||||
|
||||
return {
|
||||
type: String(head.httpMetadata?.contentType ?? guess(key)),
|
||||
type: String(head.httpMetadata?.contentType ?? guessMimeType(key)),
|
||||
size: head.size,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,13 +1,8 @@
|
||||
import { App, type CreateAppConfig } from "bknd";
|
||||
import { config as $config } from "bknd/core";
|
||||
import { config as $config, App, type CreateAppConfig, Connection, guessMimeType } from "bknd";
|
||||
import { $console } from "bknd/utils";
|
||||
import type { Context, MiddlewareHandler, Next } from "hono";
|
||||
import type { AdminControllerOptions } from "modules/server/AdminController";
|
||||
import { Connection } from "bknd/data";
|
||||
import type { Manifest } from "vite";
|
||||
import { guessMimeType } from "media";
|
||||
|
||||
export { Connection } from "bknd/data";
|
||||
|
||||
export type BkndConfig<Args = any> = CreateAppConfig & {
|
||||
app?: CreateAppConfig | ((args: Args) => CreateAppConfig);
|
||||
@@ -74,7 +69,7 @@ export async function createAdapterApp<Config extends BkndConfig = BkndConfig, A
|
||||
const sqlite = (await import("bknd/adapter/sqlite")).sqlite;
|
||||
const conf = appConfig.connection ?? { url: ":memory:" };
|
||||
connection = sqlite(conf);
|
||||
$console.info(`Using ${connection.name} connection`, conf.url);
|
||||
$console.info(`Using ${connection!.name} connection`, conf.url);
|
||||
}
|
||||
appConfig.connection = connection;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { genericSqlite } from "bknd/data";
|
||||
import { genericSqlite } from "bknd";
|
||||
import { DatabaseSync } from "node:sqlite";
|
||||
|
||||
export type NodeSqliteConnectionConfig = {
|
||||
|
||||
@@ -3,9 +3,8 @@ import { serve as honoServe } from "@hono/node-server";
|
||||
import { serveStatic } from "@hono/node-server/serve-static";
|
||||
import { registerLocalMediaAdapter } from "adapter/node/storage";
|
||||
import { type RuntimeBkndConfig, createRuntimeApp, type RuntimeOptions } from "bknd/adapter";
|
||||
import { config as $config } from "bknd/core";
|
||||
import { $console } from "core/utils";
|
||||
import type { App } from "App";
|
||||
import { config as $config, type App } from "bknd";
|
||||
import { $console } from "bknd/utils";
|
||||
|
||||
type NodeEnv = NodeJS.ProcessEnv;
|
||||
export type NodeBkndConfig<Env = NodeEnv> = RuntimeBkndConfig<Env> & {
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
import { readFile, readdir, stat, unlink, writeFile } from "node:fs/promises";
|
||||
import { isFile } from "bknd/utils";
|
||||
import type { FileBody, FileListObject, FileMeta, FileUploadPayload } from "bknd/media";
|
||||
import { StorageAdapter, guessMimeType as guess } from "bknd/media";
|
||||
import { parse, s } from "bknd/core";
|
||||
import type { FileBody, FileListObject, FileMeta, FileUploadPayload } from "bknd";
|
||||
import { StorageAdapter, guessMimeType } from "bknd";
|
||||
import { parse, s, isFile } from "bknd/utils";
|
||||
|
||||
export const localAdapterConfig = s.object(
|
||||
{
|
||||
@@ -84,7 +83,7 @@ export class StorageLocalAdapter extends StorageAdapter {
|
||||
async getObject(key: string, headers: Headers): Promise<Response> {
|
||||
try {
|
||||
const content = await readFile(`${this.config.path}/${key}`);
|
||||
const mimeType = guess(key);
|
||||
const mimeType = guessMimeType(key);
|
||||
|
||||
return new Response(content, {
|
||||
status: 200,
|
||||
@@ -106,7 +105,7 @@ export class StorageLocalAdapter extends StorageAdapter {
|
||||
async getObjectMeta(key: string): Promise<FileMeta> {
|
||||
const stats = await stat(`${this.config.path}/${key}`);
|
||||
return {
|
||||
type: guess(key) || "application/octet-stream",
|
||||
type: guessMimeType(key) || "application/octet-stream",
|
||||
size: stats.size,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { Connection } from "bknd/data";
|
||||
import type { Connection } from "bknd";
|
||||
import { bunSqlite } from "../bun/connection/BunSqliteConnection";
|
||||
|
||||
export function sqlite(config?: { url: string }): Connection {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { type Connection, libsql } from "bknd/data";
|
||||
import { type Connection, libsql } from "bknd";
|
||||
|
||||
export function sqlite(config: { url: string }): Connection {
|
||||
return libsql(config);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { Connection } from "bknd/data";
|
||||
import type { Connection } from "bknd";
|
||||
import { nodeSqlite } from "../node/connection/NodeSqliteConnection";
|
||||
|
||||
export function sqlite(config?: { url: string }): Connection {
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import { Authenticator, AuthPermissions, Role, type Strategy } from "auth";
|
||||
import type { PasswordStrategy } from "auth/authenticate/strategies";
|
||||
import type { DB } from "core";
|
||||
import type { DB } from "bknd";
|
||||
import * as AuthPermissions from "auth/auth-permissions";
|
||||
import type { AuthStrategy } from "auth/authenticate/strategies/Strategy";
|
||||
import type { PasswordStrategy } from "auth/authenticate/strategies/PasswordStrategy";
|
||||
import { $console, secureRandomString, transformObject } from "core/utils";
|
||||
import type { Entity, EntityManager } from "data";
|
||||
import type { Entity, EntityManager } from "data/entities";
|
||||
import { em, entity, enumm, type FieldSchema } from "data/prototype";
|
||||
import { Module } from "modules/Module";
|
||||
import { AuthController } from "./api/AuthController";
|
||||
@@ -10,9 +11,11 @@ import { type AppAuthSchema, authConfigSchema, STRATEGIES } from "./auth-schema"
|
||||
import { AppUserPool } from "auth/AppUserPool";
|
||||
import type { AppEntity } from "core/config";
|
||||
import { usersFields } from "./auth-entities";
|
||||
import { Authenticator } from "./authenticate/Authenticator";
|
||||
import { Role } from "./authorize/Role";
|
||||
|
||||
export type UserFieldSchema = FieldSchema<typeof AppAuth.usersFields>;
|
||||
declare module "core" {
|
||||
declare module "bknd" {
|
||||
interface Users extends AppEntity, UserFieldSchema {}
|
||||
interface DB {
|
||||
users: Users;
|
||||
@@ -88,7 +91,7 @@ export class AppAuth extends Module<AppAuthSchema> {
|
||||
this.ctx.guard.registerPermissions(AuthPermissions);
|
||||
}
|
||||
|
||||
isStrategyEnabled(strategy: Strategy | string) {
|
||||
isStrategyEnabled(strategy: AuthStrategy | string) {
|
||||
const name = typeof strategy === "string" ? strategy : strategy.getName();
|
||||
// for now, password is always active
|
||||
if (name === "password") return true;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import type { AuthActionResponse } from "auth/api/AuthController";
|
||||
import type { AppAuthSchema } from "auth/auth-schema";
|
||||
import type { AuthResponse, SafeUser, Strategy } from "auth/authenticate/Authenticator";
|
||||
import type { AuthResponse, SafeUser, AuthStrategy } from "bknd";
|
||||
import { type BaseModuleApiOptions, ModuleApi } from "modules/ModuleApi";
|
||||
|
||||
export type AuthApiOptions = BaseModuleApiOptions & {
|
||||
@@ -39,7 +39,7 @@ export class AuthApi extends ModuleApi<AuthApiOptions> {
|
||||
}
|
||||
|
||||
async actionSchema(strategy: string, action: string) {
|
||||
return this.get<Strategy>([strategy, "actions", action, "schema.json"]);
|
||||
return this.get<AuthStrategy>([strategy, "actions", action, "schema.json"]);
|
||||
}
|
||||
|
||||
async action(strategy: string, action: string, input: any) {
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
import { type AppAuth, AuthPermissions, type SafeUser, type Strategy } from "auth";
|
||||
import { transformObject } from "core/utils";
|
||||
import { DataPermissions } from "data";
|
||||
import type { SafeUser } from "bknd";
|
||||
import type { AuthStrategy } from "auth/authenticate/strategies/Strategy";
|
||||
import type { AppAuth } from "auth/AppAuth";
|
||||
import * as AuthPermissions from "auth/auth-permissions";
|
||||
import * as DataPermissions from "data/permissions";
|
||||
import type { Hono } from "hono";
|
||||
import { Controller, type ServerEnv } from "modules/Controller";
|
||||
import { describeRoute, jsc, s, parse, InvalidSchemaError } from "bknd/core";
|
||||
import { describeRoute, jsc, s, parse, InvalidSchemaError, transformObject } from "bknd/utils";
|
||||
|
||||
export type AuthActionResponse = {
|
||||
success: boolean;
|
||||
@@ -30,7 +32,7 @@ export class AuthController extends Controller {
|
||||
return this.em.repo(entity_name as "users");
|
||||
}
|
||||
|
||||
private registerStrategyActions(strategy: Strategy, mainHono: Hono<ServerEnv>) {
|
||||
private registerStrategyActions(strategy: AuthStrategy, mainHono: Hono<ServerEnv>) {
|
||||
if (!this.auth.isStrategyEnabled(strategy)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Permission } from "core";
|
||||
import { Permission } from "core/security/Permission";
|
||||
|
||||
export const createUser = new Permission("auth.user.create");
|
||||
//export const updateUser = new Permission("auth.user.update");
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { cookieConfig, jwtConfig } from "auth/authenticate/Authenticator";
|
||||
import { CustomOAuthStrategy, OAuthStrategy, PasswordStrategy } from "auth/authenticate/strategies";
|
||||
import { objectTransform } from "core/utils";
|
||||
import { s } from "bknd/core";
|
||||
import { objectTransform, s } from "bknd/utils";
|
||||
|
||||
export const Strategies = {
|
||||
password: {
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
import { type DB, Exception } from "core";
|
||||
import type { DB } from "bknd";
|
||||
import { Exception } from "core/errors";
|
||||
import { addFlashMessage } from "core/server/flash";
|
||||
import { runtimeSupports, truncate, $console } from "core/utils";
|
||||
import type { Context, Hono } from "hono";
|
||||
import type { Context } from "hono";
|
||||
import { deleteCookie, getSignedCookie, setSignedCookie } from "hono/cookie";
|
||||
import { sign, verify } from "hono/jwt";
|
||||
import { type CookieOptions, serializeSigned } from "hono/utils/cookie";
|
||||
import type { ServerEnv } from "modules/Controller";
|
||||
import { pick } from "lodash-es";
|
||||
import { InvalidConditionsException } from "auth/errors";
|
||||
import { s, parse, secret } from "bknd/core";
|
||||
import { s, parse, secret, runtimeSupports, truncate, $console } from "bknd/utils";
|
||||
import type { AuthStrategy } from "./strategies/Strategy";
|
||||
|
||||
type Input = any; // workaround
|
||||
export type JWTPayload = Parameters<typeof sign>[0];
|
||||
@@ -21,17 +22,6 @@ export type StrategyAction<S extends s.ObjectSchema = s.ObjectSchema> = {
|
||||
};
|
||||
export type StrategyActions = Partial<Record<StrategyActionName, StrategyAction>>;
|
||||
|
||||
// @todo: add schema to interface to ensure proper inference
|
||||
// @todo: add tests (e.g. invalid strategy_value)
|
||||
export interface Strategy {
|
||||
getController: (auth: Authenticator) => Hono<any>;
|
||||
getType: () => string;
|
||||
getMode: () => "form" | "external";
|
||||
getName: () => string;
|
||||
toJSON: (secrets?: boolean) => any;
|
||||
getActions?: () => StrategyActions;
|
||||
}
|
||||
|
||||
export type User = DB["users"];
|
||||
|
||||
export type ProfileExchange = {
|
||||
@@ -98,7 +88,7 @@ export type AuthResolveOptions = {
|
||||
};
|
||||
export type AuthUserResolver = (
|
||||
action: AuthAction,
|
||||
strategy: Strategy,
|
||||
strategy: AuthStrategy,
|
||||
profile: ProfileExchange,
|
||||
opts?: AuthResolveOptions,
|
||||
) => Promise<ProfileExchange | undefined>;
|
||||
@@ -108,7 +98,9 @@ type AuthClaims = SafeUser & {
|
||||
exp?: number;
|
||||
};
|
||||
|
||||
export class Authenticator<Strategies extends Record<string, Strategy> = Record<string, Strategy>> {
|
||||
export class Authenticator<
|
||||
Strategies extends Record<string, AuthStrategy> = Record<string, AuthStrategy>,
|
||||
> {
|
||||
private readonly config: AuthConfig;
|
||||
|
||||
constructor(
|
||||
@@ -121,7 +113,7 @@ export class Authenticator<Strategies extends Record<string, Strategy> = Record<
|
||||
|
||||
async resolveLogin(
|
||||
c: Context,
|
||||
strategy: Strategy,
|
||||
strategy: AuthStrategy,
|
||||
profile: Partial<SafeUser>,
|
||||
verify: (user: User) => Promise<void>,
|
||||
opts?: AuthResolveOptions,
|
||||
@@ -159,7 +151,7 @@ export class Authenticator<Strategies extends Record<string, Strategy> = Record<
|
||||
|
||||
async resolveRegister(
|
||||
c: Context,
|
||||
strategy: Strategy,
|
||||
strategy: AuthStrategy,
|
||||
profile: CreateUser,
|
||||
verify: (user: User) => Promise<void>,
|
||||
opts?: AuthResolveOptions,
|
||||
@@ -228,7 +220,7 @@ export class Authenticator<Strategies extends Record<string, Strategy> = Record<
|
||||
|
||||
strategy<
|
||||
StrategyName extends keyof Strategies,
|
||||
Strat extends Strategy = Strategies[StrategyName],
|
||||
Strat extends AuthStrategy = Strategies[StrategyName],
|
||||
>(strategy: StrategyName): Strat {
|
||||
try {
|
||||
return this.strategies[strategy] as unknown as Strat;
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
import { type Authenticator, InvalidCredentialsException, type User } from "auth";
|
||||
import type { User } from "bknd";
|
||||
import type { Authenticator } from "auth/authenticate/Authenticator";
|
||||
import { InvalidCredentialsException } from "auth/errors";
|
||||
import { hash, $console } from "core/utils";
|
||||
import { Hono } from "hono";
|
||||
import { compare as bcryptCompare, genSalt as bcryptGenSalt, hash as bcryptHash } from "bcryptjs";
|
||||
import { Strategy } from "./Strategy";
|
||||
import { s, parse, jsc } from "bknd/core";
|
||||
import { AuthStrategy } from "./Strategy";
|
||||
import { s, parse, jsc } from "bknd/utils";
|
||||
|
||||
const schema = s
|
||||
.object({
|
||||
@@ -14,7 +16,7 @@ const schema = s
|
||||
|
||||
export type PasswordStrategyOptions = s.Static<typeof schema>;
|
||||
|
||||
export class PasswordStrategy extends Strategy<typeof schema> {
|
||||
export class PasswordStrategy extends AuthStrategy<typeof schema> {
|
||||
constructor(config: Partial<PasswordStrategyOptions> = {}) {
|
||||
super(config as any, "password", "password", "form");
|
||||
|
||||
|
||||
@@ -5,11 +5,11 @@ import type {
|
||||
StrategyActions,
|
||||
} from "../Authenticator";
|
||||
import type { Hono } from "hono";
|
||||
import { type s, parse } from "bknd/core";
|
||||
import { type s, parse } from "bknd/utils";
|
||||
|
||||
export type StrategyMode = "form" | "external";
|
||||
|
||||
export abstract class Strategy<Schema extends s.Schema = s.Schema> {
|
||||
export abstract class AuthStrategy<Schema extends s.Schema = s.Schema> {
|
||||
protected actions: StrategyActions = {};
|
||||
|
||||
constructor(
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import type * as oauth from "oauth4webapi";
|
||||
import { OAuthStrategy } from "./OAuthStrategy";
|
||||
import { s } from "bknd/core";
|
||||
import { s } from "bknd/utils";
|
||||
|
||||
type SupportedTypes = "oauth2" | "oidc";
|
||||
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import type { AuthAction, Authenticator } from "auth";
|
||||
import { Exception, isDebug } from "core";
|
||||
import { filterKeys } from "core/utils";
|
||||
import type { Authenticator, AuthAction } from "auth/authenticate/Authenticator";
|
||||
import { type Context, Hono } from "hono";
|
||||
import { getSignedCookie, setSignedCookie } from "hono/cookie";
|
||||
import * as oauth from "oauth4webapi";
|
||||
import * as issuers from "./issuers";
|
||||
import { Strategy } from "auth/authenticate/strategies/Strategy";
|
||||
import { s } from "bknd/core";
|
||||
import { s, filterKeys } from "bknd/utils";
|
||||
import { Exception } from "core/errors";
|
||||
import { isDebug } from "core/env";
|
||||
import { AuthStrategy } from "../Strategy";
|
||||
|
||||
type ConfiguredIssuers = keyof typeof issuers;
|
||||
type SupportedTypes = "oauth2" | "oidc";
|
||||
@@ -70,7 +70,7 @@ export class OAuthCallbackException extends Exception {
|
||||
}
|
||||
}
|
||||
|
||||
export class OAuthStrategy extends Strategy<typeof schemaProvided> {
|
||||
export class OAuthStrategy extends AuthStrategy<typeof schemaProvided> {
|
||||
constructor(config: ProvidedOAuthConfig) {
|
||||
super(config, "oauth", config.name, "external");
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { Exception, Permission } from "core";
|
||||
import { Exception } from "core/errors";
|
||||
import { $console, objectTransform } from "core/utils";
|
||||
import { Permission } from "core/security/Permission";
|
||||
import type { Context } from "hono";
|
||||
import type { ServerEnv } from "modules/Controller";
|
||||
import { Role } from "./Role";
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Permission } from "core";
|
||||
import { Permission } from "core/security/Permission";
|
||||
|
||||
export class RolePermission {
|
||||
constructor(
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { Exception, isDebug } from "core";
|
||||
import { HttpStatus } from "core/utils";
|
||||
import { Exception } from "core/errors";
|
||||
import { isDebug } from "core/env";
|
||||
import { HttpStatus } from "bknd/utils";
|
||||
|
||||
export class AuthException extends Exception {
|
||||
getSafeErrorAndCode() {
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
export { UserExistsException, UserNotFoundException, InvalidCredentialsException } from "./errors";
|
||||
export {
|
||||
type ProfileExchange,
|
||||
type Strategy,
|
||||
type User,
|
||||
type SafeUser,
|
||||
type CreateUser,
|
||||
type AuthResponse,
|
||||
type UserPool,
|
||||
type AuthAction,
|
||||
type AuthUserResolver,
|
||||
Authenticator,
|
||||
authenticatorConfig,
|
||||
jwtConfig,
|
||||
} from "./authenticate/Authenticator";
|
||||
|
||||
export { AppAuth, type UserFieldSchema } from "./AppAuth";
|
||||
|
||||
export { Guard, type GuardUserContext, type GuardConfig } from "./authorize/Guard";
|
||||
export { Role } from "./authorize/Role";
|
||||
|
||||
export * as AuthPermissions from "./auth-permissions";
|
||||
@@ -1,5 +1,5 @@
|
||||
import type { Permission } from "core";
|
||||
import { $console, patternMatch } from "core/utils";
|
||||
import type { Permission } from "core/security/Permission";
|
||||
import { $console, patternMatch } from "bknd/utils";
|
||||
import type { Context } from "hono";
|
||||
import { createMiddleware } from "hono/factory";
|
||||
import type { ServerEnv } from "modules/Controller";
|
||||
|
||||
@@ -5,7 +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 { env } from "core";
|
||||
import { env } from "bknd";
|
||||
import color from "picocolors";
|
||||
import { overridePackageJson, updateBkndPackages } from "./npm";
|
||||
import { type Template, templates, type TemplateSetupCtx } from "./templates";
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
import type { Config } from "@libsql/client/node";
|
||||
import type { App, CreateAppConfig } from "App";
|
||||
import { StorageLocalAdapter } from "adapter/node/storage";
|
||||
import type { CliBkndConfig, CliCommand } from "cli/types";
|
||||
import { Option } from "commander";
|
||||
import { config } from "core";
|
||||
import { config, type App, type CreateAppConfig } from "bknd";
|
||||
import dotenv from "dotenv";
|
||||
import { registries } from "modules/registries";
|
||||
import c from "picocolors";
|
||||
@@ -16,8 +15,8 @@ import {
|
||||
serveStatic,
|
||||
startServer,
|
||||
} from "./platform";
|
||||
import { createRuntimeApp, makeConfig } from "adapter";
|
||||
import { colorizeConsole, isBun } from "core/utils";
|
||||
import { createRuntimeApp, makeConfig } from "bknd/adapter";
|
||||
import { colorizeConsole, isBun } from "bknd/utils";
|
||||
|
||||
const env_files = [".env", ".dev.vars"];
|
||||
dotenv.config({
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { PostHog } from "posthog-js-lite";
|
||||
import { getVersion } from "cli/utils/sys";
|
||||
import { env, isDebug } from "core";
|
||||
import { $console } from "core/utils";
|
||||
import { env, isDebug } from "bknd";
|
||||
import { $console } from "bknd/utils";
|
||||
|
||||
type Properties = { [p: string]: any };
|
||||
|
||||
|
||||
@@ -6,23 +6,3 @@ export interface IEmailDriver<Data = unknown, Options = object> {
|
||||
options?: Options,
|
||||
): Promise<Data>;
|
||||
}
|
||||
|
||||
import type { BkndConfig } from "bknd";
|
||||
import { resendEmail, memoryCache } from "bknd/core";
|
||||
|
||||
export default {
|
||||
onBuilt: async (app) => {
|
||||
app.server.get("/send-email", async (c) => {
|
||||
if (await app.drivers?.email?.send("test@test.com", "Test", "Test")) {
|
||||
return c.text("success");
|
||||
}
|
||||
return c.text("failed");
|
||||
});
|
||||
},
|
||||
options: {
|
||||
drivers: {
|
||||
email: resendEmail({ apiKey: "..." }),
|
||||
cache: memoryCache(),
|
||||
},
|
||||
},
|
||||
} as const satisfies BkndConfig;
|
||||
|
||||
@@ -1,51 +0,0 @@
|
||||
import type { Hono, MiddlewareHandler } from "hono";
|
||||
|
||||
export { Exception, BkndError } from "./errors";
|
||||
export { isDebug, env } from "./env";
|
||||
export { type PrimaryFieldType, config, type DB, type AppEntity } from "./config";
|
||||
export { AwsClient } from "./clients/aws/AwsClient";
|
||||
export {
|
||||
SimpleRenderer,
|
||||
type TemplateObject,
|
||||
type TemplateTypes,
|
||||
type SimpleRendererOptions,
|
||||
} from "./template/SimpleRenderer";
|
||||
export { SchemaObject } from "./object/SchemaObject";
|
||||
export { DebugLogger } from "./utils/DebugLogger";
|
||||
export { Permission } from "./security/Permission";
|
||||
export {
|
||||
exp,
|
||||
makeValidator,
|
||||
type FilterQuery,
|
||||
type Primitive,
|
||||
isPrimitive,
|
||||
type TExpression,
|
||||
type BooleanLike,
|
||||
isBooleanLike,
|
||||
} from "./object/query/query";
|
||||
export { Registry, type Constructor } from "./registry/Registry";
|
||||
export { getFlashMessage } from "./server/flash";
|
||||
export {
|
||||
s,
|
||||
stripMark,
|
||||
mark,
|
||||
stringIdentifier,
|
||||
secret,
|
||||
parse,
|
||||
jsc,
|
||||
describeRoute,
|
||||
schemaToSpec,
|
||||
openAPISpecs,
|
||||
type ParseOptions,
|
||||
InvalidSchemaError,
|
||||
} from "./object/schema";
|
||||
|
||||
export * from "./drivers";
|
||||
export * from "./events";
|
||||
|
||||
// compatibility
|
||||
export type Middleware = MiddlewareHandler<any, any, any>;
|
||||
export interface ClassController {
|
||||
getController: () => Hono<any, any, any>;
|
||||
getMiddleware?: MiddlewareHandler<any, any, any>;
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
import { get, has, omit, set } from "lodash-es";
|
||||
import { getFullPathKeys, mergeObjectWith } from "../utils";
|
||||
import { type s, parse, stripMark } from "bknd/core";
|
||||
import { type s, parse, stripMark, getFullPathKeys, mergeObjectWith, deepFreeze } from "bknd/utils";
|
||||
|
||||
export type SchemaObjectOptions<Schema extends s.Schema> = {
|
||||
onUpdate?: (config: s.Static<Schema>) => void | Promise<void>;
|
||||
@@ -26,14 +25,16 @@ export class SchemaObject<Schema extends TSchema = TSchema> {
|
||||
initial?: Partial<s.Static<Schema>>,
|
||||
private options?: SchemaObjectOptions<Schema>,
|
||||
) {
|
||||
this._default = _schema.template({}, { withOptional: true }) as any;
|
||||
this._value = parse(_schema, structuredClone(initial ?? {}), {
|
||||
withDefaults: true,
|
||||
withExtendedDefaults: true,
|
||||
forceParse: this.isForceParse(),
|
||||
skipMark: this.isForceParse(),
|
||||
});
|
||||
this._config = Object.freeze(this._value);
|
||||
this._default = deepFreeze(_schema.template({}, { withOptional: true }) as any);
|
||||
this._value = deepFreeze(
|
||||
parse(_schema, structuredClone(initial ?? {}), {
|
||||
withDefaults: true,
|
||||
withExtendedDefaults: true,
|
||||
forceParse: this.isForceParse(),
|
||||
skipMark: this.isForceParse(),
|
||||
}),
|
||||
);
|
||||
this._config = deepFreeze(this._value);
|
||||
}
|
||||
|
||||
protected isForceParse(): boolean {
|
||||
@@ -76,8 +77,8 @@ export class SchemaObject<Schema extends TSchema = TSchema> {
|
||||
// regardless of "noEmit" – this should always be triggered
|
||||
const updatedConfig = await this.onBeforeUpdate(this._config, valid);
|
||||
|
||||
this._value = updatedConfig;
|
||||
this._config = Object.freeze(updatedConfig);
|
||||
this._value = deepFreeze(updatedConfig);
|
||||
this._config = deepFreeze(updatedConfig);
|
||||
|
||||
if (noEmit !== true) {
|
||||
await this.options?.onUpdate?.(this._config);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { PrimaryFieldType } from "core";
|
||||
import type { PrimaryFieldType } from "core/config";
|
||||
|
||||
export type Primitive = PrimaryFieldType | string | number | boolean;
|
||||
export function isPrimitive(value: any): value is Primitive {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { describe, expect, test } from "bun:test";
|
||||
import { SimpleRenderer } from "core";
|
||||
import { SimpleRenderer } from "./SimpleRenderer";
|
||||
|
||||
describe(SimpleRenderer, () => {
|
||||
const renderer = new SimpleRenderer(
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { datetimeStringLocal } from "core/utils";
|
||||
import { datetimeStringLocal } from "./dates";
|
||||
import colors from "picocolors";
|
||||
import { env } from "core";
|
||||
import { env } from "core/env";
|
||||
|
||||
function hasColors() {
|
||||
try {
|
||||
|
||||
@@ -13,3 +13,18 @@ export * from "./uuid";
|
||||
export * from "./test";
|
||||
export * from "./runtime";
|
||||
export * from "./numbers";
|
||||
export {
|
||||
s,
|
||||
stripMark,
|
||||
mark,
|
||||
stringIdentifier,
|
||||
SecretSchema,
|
||||
secret,
|
||||
parse,
|
||||
jsc,
|
||||
describeRoute,
|
||||
schemaToSpec,
|
||||
openAPISpecs,
|
||||
type ParseOptions,
|
||||
InvalidSchemaError,
|
||||
} from "./schema";
|
||||
|
||||
@@ -94,16 +94,14 @@ export function transformObject<T extends Record<string, any>, U>(
|
||||
object: T,
|
||||
transform: (value: T[keyof T], key: keyof T) => U | undefined,
|
||||
): { [K in keyof T]: U } {
|
||||
return Object.entries(object).reduce(
|
||||
(acc, [key, value]) => {
|
||||
const t = transform(value, key as keyof T);
|
||||
if (typeof t !== "undefined") {
|
||||
acc[key as keyof T] = t;
|
||||
}
|
||||
return acc;
|
||||
},
|
||||
{} as { [K in keyof T]: U },
|
||||
);
|
||||
const result = {} as { [K in keyof T]: U };
|
||||
for (const [key, value] of Object.entries(object) as [keyof T, T[keyof T]][]) {
|
||||
const t = transform(value, key);
|
||||
if (typeof t !== "undefined") {
|
||||
result[key] = t;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
export const objectTransform = transformObject;
|
||||
|
||||
@@ -419,3 +417,21 @@ export function pick<T extends object, K extends keyof T>(obj: T, keys: K[]): Pi
|
||||
{} as Pick<T, K>,
|
||||
);
|
||||
}
|
||||
|
||||
export function deepFreeze<T extends object>(object: T): T {
|
||||
if (Object.isFrozen(object)) return object;
|
||||
|
||||
// Retrieve the property names defined on object
|
||||
const propNames = Reflect.ownKeys(object);
|
||||
|
||||
// Freeze properties before freezing self
|
||||
for (const name of propNames) {
|
||||
const value = object[name];
|
||||
|
||||
if ((value && typeof value === "object") || typeof value === "function") {
|
||||
deepFreeze(value);
|
||||
}
|
||||
}
|
||||
|
||||
return Object.freeze(object);
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ import * as s from "jsonv-ts";
|
||||
export { validator as jsc, type Options } from "jsonv-ts/hono";
|
||||
export { describeRoute, schemaToSpec, openAPISpecs } from "jsonv-ts/hono";
|
||||
|
||||
export { secret } from "./secret";
|
||||
export { secret, SecretSchema } from "./secret";
|
||||
|
||||
export { s };
|
||||
|
||||
@@ -1,15 +1,12 @@
|
||||
import { transformObject } from "core/utils";
|
||||
import {
|
||||
DataPermissions,
|
||||
type Entity,
|
||||
EntityIndex,
|
||||
type EntityManager,
|
||||
constructEntity,
|
||||
constructRelation,
|
||||
} from "data";
|
||||
|
||||
import { Module } from "modules/Module";
|
||||
import { DataController } from "./api/DataController";
|
||||
import { type AppDataConfig, dataConfigSchema } from "./data-schema";
|
||||
import { constructEntity, constructRelation } from "./schema/constructor";
|
||||
import type { Entity, EntityManager } from "data/entities";
|
||||
import { EntityIndex } from "data/fields";
|
||||
import * as DataPermissions from "data/permissions";
|
||||
|
||||
export class AppData extends Module<AppDataConfig> {
|
||||
override async build() {
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import type { DB } from "core";
|
||||
import type { EntityData, RepoQueryIn, RepositoryResultJSON } from "data";
|
||||
import type { DB, EntityData, RepoQueryIn } from "bknd";
|
||||
|
||||
import type { Insertable, Selectable, Updateable } from "kysely";
|
||||
import { type BaseModuleApiOptions, ModuleApi, type PrimaryFieldType } from "modules";
|
||||
import type { FetchPromise, ResponseObject } from "modules/ModuleApi";
|
||||
import type { RepositoryResultJSON } from "data/entities/query/RepositoryResult";
|
||||
|
||||
export type DataApiOptions = BaseModuleApiOptions & {
|
||||
queryLengthLimit: number;
|
||||
|
||||
@@ -1,17 +1,12 @@
|
||||
import {
|
||||
DataPermissions,
|
||||
type EntityData,
|
||||
type EntityManager,
|
||||
type RepoQuery,
|
||||
repoQuery,
|
||||
} from "data";
|
||||
import type { Handler } from "hono/types";
|
||||
import type { ModuleBuildContext } from "modules";
|
||||
import { Controller } from "modules/Controller";
|
||||
import { jsc, s, describeRoute, schemaToSpec } from "bknd/core";
|
||||
import { jsc, s, describeRoute, schemaToSpec, omitKeys } from "bknd/utils";
|
||||
import * as SystemPermissions from "modules/permissions";
|
||||
import type { AppDataConfig } from "../data-schema";
|
||||
import { omitKeys } from "core/utils";
|
||||
import type { EntityManager, EntityData } from "data/entities";
|
||||
import * as DataPermissions from "data/permissions";
|
||||
import { repoQuery, type RepoQuery } from "data/server/query";
|
||||
|
||||
export class DataController extends Controller {
|
||||
constructor(
|
||||
|
||||
@@ -18,7 +18,8 @@ import {
|
||||
sql,
|
||||
} from "kysely";
|
||||
import type { BaseIntrospector, BaseIntrospectorConfig } from "./BaseIntrospector";
|
||||
import type { Constructor, DB } from "core";
|
||||
import type { DB } from "bknd";
|
||||
import type { Constructor } from "core/registry/Registry";
|
||||
import { KyselyPluginRunner } from "data/plugins/KyselyPluginRunner";
|
||||
import type { Field } from "data/fields/Field";
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ import {
|
||||
} from "kysely";
|
||||
import { jsonArrayFrom, jsonBuildObject, jsonObjectFrom } from "kysely/helpers/sqlite";
|
||||
import { Connection, type DbFunctions, type FieldSpec, type SchemaResponse } from "../Connection";
|
||||
import type { Constructor } from "core";
|
||||
import type { Constructor } from "core/registry/Registry";
|
||||
import { customIntrospector } from "../Connection";
|
||||
import { SqliteIntrospector } from "./SqliteIntrospector";
|
||||
import type { Field } from "data/fields/Field";
|
||||
|
||||
@@ -4,7 +4,7 @@ import { FieldClassMap } from "data/fields";
|
||||
import { RelationClassMap, RelationFieldClassMap } from "data/relations";
|
||||
import { entityConfigSchema, entityTypes } from "data/entities";
|
||||
import { primaryFieldTypes } from "./fields";
|
||||
import { s } from "bknd/core";
|
||||
import { s } from "bknd/utils";
|
||||
|
||||
export const FIELDS = {
|
||||
...FieldClassMap,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { config } from "core";
|
||||
import { snakeToPascalWithSpaces, transformObject, $console } from "core/utils";
|
||||
import { config } from "core/config";
|
||||
import { snakeToPascalWithSpaces, transformObject, $console, s, parse } from "bknd/utils";
|
||||
import {
|
||||
type Field,
|
||||
PrimaryField,
|
||||
@@ -7,7 +7,6 @@ import {
|
||||
type TActionContext,
|
||||
type TRenderContext,
|
||||
} from "../fields";
|
||||
import { s, parse } from "bknd/core";
|
||||
|
||||
// @todo: entity must be migrated to typebox
|
||||
export const entityConfigSchema = s
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import type { DB as DefaultDB } from "core";
|
||||
import { $console } from "core/utils";
|
||||
import type { DB as DefaultDB } from "bknd";
|
||||
import { $console } from "bknd/utils";
|
||||
import { EventManager } from "core/events";
|
||||
import { sql } from "kysely";
|
||||
import { Connection } from "../connection/Connection";
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import type { Entity, EntityManager, EntityRelation, TEntityType } from "data";
|
||||
import type { Entity, EntityManager, TEntityType } from "data/entities";
|
||||
import type { EntityRelation } from "data/relations";
|
||||
import { autoFormatString } from "core/utils";
|
||||
import { usersFields } from "auth/auth-entities";
|
||||
import { mediaFields } from "media/media-entities";
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { isDebug } from "core";
|
||||
import { isDebug } from "core/env";
|
||||
import { pick } from "core/utils";
|
||||
import type { Connection } from "data/connection";
|
||||
import type {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import type { DB as DefaultDB, PrimaryFieldType } from "core";
|
||||
import type { DB as DefaultDB, PrimaryFieldType } from "bknd";
|
||||
import { type EmitsEvents, EventManager } from "core/events";
|
||||
import type { DeleteQueryBuilder, InsertQueryBuilder, UpdateQueryBuilder } from "kysely";
|
||||
import type { TActionContext } from "../..";
|
||||
import type { TActionContext } from "data/fields";
|
||||
import { WhereBuilder } from "../query/WhereBuilder";
|
||||
import type { Entity, EntityData, EntityManager } from "../../entities";
|
||||
import { InvalidSearchParamsException } from "../../errors";
|
||||
@@ -9,7 +9,6 @@ import { MutatorEvents } from "../../events";
|
||||
import { RelationMutator } from "../../relations";
|
||||
import type { RepoQuery } from "../../server/query";
|
||||
import { MutatorResult, type MutatorResultOptions } from "./MutatorResult";
|
||||
import { transformObject } from "core/utils";
|
||||
|
||||
type MutatorQB =
|
||||
| InsertQueryBuilder<any, any, any>
|
||||
|
||||
@@ -2,7 +2,7 @@ import { $console } from "core/utils";
|
||||
import type { Entity, EntityData } from "../Entity";
|
||||
import type { EntityManager } from "../EntityManager";
|
||||
import { Result, type ResultJSON, type ResultOptions } from "../Result";
|
||||
import { isDebug } from "core";
|
||||
import { isDebug } from "core/env";
|
||||
|
||||
export type MutatorResultOptions = ResultOptions & {
|
||||
silent?: boolean;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { DB as DefaultDB, PrimaryFieldType } from "core";
|
||||
import type { DB as DefaultDB, PrimaryFieldType } from "bknd";
|
||||
import { $console } from "core/utils";
|
||||
import { type EmitsEvents, EventManager } from "core/events";
|
||||
import { type SelectQueryBuilder, sql } from "kysely";
|
||||
@@ -14,7 +14,6 @@ import {
|
||||
} from "../index";
|
||||
import { JoinBuilder } from "./JoinBuilder";
|
||||
import { RepositoryResult, type RepositoryResultOptions } from "./RepositoryResult";
|
||||
import type { ResultOptions } from "../Result";
|
||||
|
||||
export type RepositoryQB = SelectQueryBuilder<any, any, any>;
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ import {
|
||||
isBooleanLike,
|
||||
isPrimitive,
|
||||
makeValidator,
|
||||
} from "core";
|
||||
} from "core/object/query/query";
|
||||
import type {
|
||||
DeleteQueryBuilder,
|
||||
ExpressionBuilder,
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
import { isObject } from "core/utils";
|
||||
import type { KyselyJsonFrom, RepoQuery } from "data";
|
||||
|
||||
import type { KyselyJsonFrom } from "data/relations/EntityRelation";
|
||||
import type { RepoQuery } from "data/server/query";
|
||||
import { InvalidSearchParamsException } from "data/errors";
|
||||
import type { Entity, EntityManager, RepositoryQB } from "../../entities";
|
||||
import type { Entity, EntityManager, RepositoryQB } from "data/entities";
|
||||
|
||||
export class WithBuilder {
|
||||
static addClause(
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { Exception } from "core";
|
||||
import { HttpStatus } from "core/utils";
|
||||
import type { InvalidSchemaError } from "bknd/core";
|
||||
import { Exception } from "core/errors";
|
||||
import { type InvalidSchemaError, HttpStatus } from "bknd/utils";
|
||||
import type { Entity } from "./entities";
|
||||
import type { Field } from "./fields";
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import type { PrimaryFieldType } from "core";
|
||||
import { $console } from "core/utils";
|
||||
import type { PrimaryFieldType } from "bknd";
|
||||
import { $console } from "bknd/utils";
|
||||
import { Event, InvalidEventReturn } from "core/events";
|
||||
import type { Entity, EntityData } from "../entities";
|
||||
import type { RepoQuery } from "data/server/query";
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { omitKeys } from "core/utils";
|
||||
import type { EntityManager } from "data";
|
||||
import type { EntityManager } from "data/entities";
|
||||
import { TransformPersistFailedException } from "../errors";
|
||||
import { Field, type TActionContext, type TRenderContext, baseFieldConfigSchema } from "./Field";
|
||||
import { s } from "bknd/core";
|
||||
import { s } from "bknd/utils";
|
||||
|
||||
export const booleanFieldConfigSchema = s
|
||||
.strictObject({
|
||||
|
||||
@@ -3,7 +3,7 @@ import type { EntityManager } from "../entities";
|
||||
import { Field, type TActionContext, type TRenderContext, baseFieldConfigSchema } from "./Field";
|
||||
import { $console } from "core/utils";
|
||||
import type { TFieldTSType } from "data/entities/EntityTypescript";
|
||||
import { s } from "bknd/core";
|
||||
import { s } from "bknd/utils";
|
||||
|
||||
export const dateFieldConfigSchema = s
|
||||
.strictObject({
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { omitKeys } from "core/utils";
|
||||
import type { EntityManager } from "data";
|
||||
import type { EntityManager } from "data/entities";
|
||||
import { TransformPersistFailedException } from "../errors";
|
||||
import { baseFieldConfigSchema, Field, type TActionContext, type TRenderContext } from "./Field";
|
||||
import type { TFieldTSType } from "data/entities/EntityTypescript";
|
||||
import { s } from "bknd/core";
|
||||
import { s } from "bknd/utils";
|
||||
|
||||
export const enumFieldConfigSchema = s
|
||||
.strictObject({
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
import { snakeToPascalWithSpaces } from "core/utils";
|
||||
import type { HTMLInputTypeAttribute, InputHTMLAttributes } from "react";
|
||||
import type { EntityManager } from "../entities";
|
||||
import { InvalidFieldConfigException, TransformPersistFailedException } from "../errors";
|
||||
import type { FieldSpec } from "data/connection/Connection";
|
||||
import type { TFieldTSType } from "data/entities/EntityTypescript";
|
||||
import { s, parse, InvalidSchemaError } from "bknd/core";
|
||||
import { s, parse, InvalidSchemaError, snakeToPascalWithSpaces } from "bknd/utils";
|
||||
|
||||
// @todo: contexts need to be reworked
|
||||
// e.g. "table" is irrelevant, because if read is not given, it fails
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { omitKeys } from "core/utils";
|
||||
import type { EntityManager } from "data";
|
||||
import type { EntityManager } from "data/entities";
|
||||
import { TransformPersistFailedException } from "../errors";
|
||||
import { Field, type TActionContext, type TRenderContext, baseFieldConfigSchema } from "./Field";
|
||||
import type { TFieldTSType } from "data/entities/EntityTypescript";
|
||||
import { s } from "bknd/core";
|
||||
import { s } from "bknd/utils";
|
||||
|
||||
export const jsonFieldConfigSchema = s
|
||||
.strictObject({
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { type Schema as JsonSchema, Validator } from "@cfworker/json-schema";
|
||||
import { objectToJsLiteral } from "core/utils";
|
||||
import type { EntityManager } from "data";
|
||||
import type { EntityManager } from "data/entities";
|
||||
import { TransformPersistFailedException } from "../errors";
|
||||
import { Field, type TActionContext, type TRenderContext, baseFieldConfigSchema } from "./Field";
|
||||
import type { TFieldTSType } from "data/entities/EntityTypescript";
|
||||
import { s } from "bknd/core";
|
||||
import { s } from "bknd/utils";
|
||||
|
||||
export const jsonSchemaFieldConfigSchema = s
|
||||
.strictObject({
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import type { EntityManager } from "data";
|
||||
import type { EntityManager } from "data/entities";
|
||||
import { TransformPersistFailedException } from "../errors";
|
||||
import { Field, type TActionContext, type TRenderContext, baseFieldConfigSchema } from "./Field";
|
||||
import type { TFieldTSType } from "data/entities/EntityTypescript";
|
||||
import { s } from "bknd/core";
|
||||
import { s } from "bknd/utils";
|
||||
import { omitKeys } from "core/utils";
|
||||
|
||||
export const numberFieldConfigSchema = s
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
import { config } from "core";
|
||||
import { omitKeys, uuidv7 } from "core/utils";
|
||||
import { config } from "core/config";
|
||||
import { omitKeys, uuidv7, s } from "bknd/utils";
|
||||
import { Field, baseFieldConfigSchema } from "./Field";
|
||||
import type { TFieldTSType } from "data/entities/EntityTypescript";
|
||||
import { s } from "bknd/core";
|
||||
|
||||
export const primaryFieldTypes = ["integer", "uuid"] as const;
|
||||
export type TPrimaryFieldFormat = (typeof primaryFieldTypes)[number];
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import type { EntityManager } from "data";
|
||||
import type { EntityManager } from "data/entities";
|
||||
import { omitKeys } from "core/utils";
|
||||
import { TransformPersistFailedException } from "../errors";
|
||||
import { Field, type TActionContext, baseFieldConfigSchema } from "./Field";
|
||||
import { s } from "bknd/core";
|
||||
import { s } from "bknd/utils";
|
||||
|
||||
export const textFieldConfigSchema = s
|
||||
.strictObject({
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Field, baseFieldConfigSchema } from "./Field";
|
||||
import { s } from "bknd/core";
|
||||
import { s } from "bknd/utils";
|
||||
|
||||
export const virtualFieldConfigSchema = s
|
||||
.strictObject({
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { BaseFieldConfig, Field, TActionContext } from "data";
|
||||
import type { BaseFieldConfig, Field, TActionContext } from "data/fields";
|
||||
import type { ColumnDataType } from "kysely";
|
||||
import { omit } from "lodash-es";
|
||||
import type { TestRunner } from "core/test";
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import type { EntityData, EntityManager, Field } from "data";
|
||||
import type { EntityData, EntityManager } from "data/entities";
|
||||
import type { Field } from "data/fields";
|
||||
import { transform } from "lodash-es";
|
||||
|
||||
export function getDefaultValues(fields: Field[], data: EntityData): EntityData {
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
import { MutatorEvents, RepositoryEvents } from "./events";
|
||||
|
||||
export * from "./fields";
|
||||
export * from "./entities";
|
||||
export * from "./relations";
|
||||
export * from "./schema/SchemaManager";
|
||||
export * from "./prototype";
|
||||
export * from "./connection";
|
||||
|
||||
export {
|
||||
type RepoQuery,
|
||||
type RepoQueryIn,
|
||||
getRepoQueryTemplate,
|
||||
repoQuery,
|
||||
} from "./server/query";
|
||||
|
||||
export type { WhereQuery } from "./entities/query/WhereBuilder";
|
||||
|
||||
export { KyselyPluginRunner } from "./plugins/KyselyPluginRunner";
|
||||
|
||||
export { constructEntity, constructRelation } from "./schema/constructor";
|
||||
|
||||
export const DatabaseEvents = {
|
||||
...MutatorEvents,
|
||||
...RepositoryEvents,
|
||||
};
|
||||
export { MutatorEvents, RepositoryEvents };
|
||||
|
||||
export * as DataPermissions from "./permissions";
|
||||
|
||||
export { MediaField, type MediaFieldConfig, type MediaItem } from "media/MediaField";
|
||||
|
||||
export { libsql } from "./connection/sqlite/libsql/LibsqlConnection";
|
||||
export {
|
||||
genericSqlite,
|
||||
genericSqliteUtils,
|
||||
type GenericSqliteConnection,
|
||||
} from "./connection/sqlite/GenericSqliteConnection";
|
||||
|
||||
export {
|
||||
EntityTypescript,
|
||||
type EntityTypescriptOptions,
|
||||
type TEntityTSType,
|
||||
type TFieldTSType,
|
||||
} from "./entities/EntityTypescript";
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Permission } from "core";
|
||||
import { Permission } from "core/security/Permission";
|
||||
|
||||
export const entityRead = new Permission("data.entity.read");
|
||||
export const entityCreate = new Permission("data.entity.create");
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { parse } from "bknd/core";
|
||||
import type { PrimaryFieldType } from "bknd";
|
||||
import { s, parse } from "bknd/utils";
|
||||
import type { ExpressionBuilder, SelectQueryBuilder } from "kysely";
|
||||
import type { Entity, EntityData, EntityManager } from "../entities";
|
||||
import {
|
||||
@@ -8,8 +9,6 @@ import {
|
||||
} from "../relations";
|
||||
import type { RepoQuery } from "../server/query";
|
||||
import type { RelationType } from "./relation-types";
|
||||
import type { PrimaryFieldType } from "core";
|
||||
import { s } from "bknd/core";
|
||||
|
||||
const directions = ["source", "target"] as const;
|
||||
export type TDirection = (typeof directions)[number];
|
||||
|
||||
@@ -6,7 +6,7 @@ import { EntityRelation, type KyselyQueryBuilder } from "./EntityRelation";
|
||||
import { EntityRelationAnchor } from "./EntityRelationAnchor";
|
||||
import { RelationField } from "./RelationField";
|
||||
import { type RelationType, RelationTypes } from "./relation-types";
|
||||
import { s } from "bknd/core";
|
||||
import { s } from "bknd/utils";
|
||||
|
||||
export type ManyToManyRelationConfig = s.Static<typeof ManyToManyRelation.schema>;
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import type { PrimaryFieldType } from "core";
|
||||
import { snakeToPascalWithSpaces } from "core/utils";
|
||||
import type { PrimaryFieldType } from "bknd";
|
||||
import { snakeToPascalWithSpaces, s } from "bknd/utils";
|
||||
import type { ExpressionBuilder } from "kysely";
|
||||
import type { Entity, EntityManager } from "../entities";
|
||||
import type { RepoQuery } from "../server/query";
|
||||
@@ -8,7 +8,6 @@ import { EntityRelationAnchor } from "./EntityRelationAnchor";
|
||||
import { RelationField, type RelationFieldBaseConfig } from "./RelationField";
|
||||
import type { MutationInstructionResponse } from "./RelationMutator";
|
||||
import { type RelationType, RelationTypes } from "./relation-types";
|
||||
import { s } from "bknd/core";
|
||||
|
||||
/**
|
||||
* Source entity receives the mapping field
|
||||
|
||||
@@ -5,7 +5,7 @@ import type { RepoQuery } from "../server/query";
|
||||
import { EntityRelation, type KyselyJsonFrom, type KyselyQueryBuilder } from "./EntityRelation";
|
||||
import { EntityRelationAnchor } from "./EntityRelationAnchor";
|
||||
import { type RelationType, RelationTypes } from "./relation-types";
|
||||
import { s } from "bknd/core";
|
||||
import { s } from "bknd/utils";
|
||||
|
||||
export type PolymorphicRelationConfig = s.Static<typeof PolymorphicRelation.schema>;
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ import { Field, baseFieldConfigSchema } from "../fields";
|
||||
import type { EntityRelation } from "./EntityRelation";
|
||||
import type { EntityRelationAnchor } from "./EntityRelationAnchor";
|
||||
import type { TFieldTSType } from "data/entities/EntityTypescript";
|
||||
import { s } from "bknd/core";
|
||||
import { s } from "bknd/utils";
|
||||
|
||||
const CASCADES = ["cascade", "set null", "set default", "restrict", "no action"] as const;
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { PrimaryFieldType } from "core";
|
||||
import type { PrimaryFieldType } from "bknd";
|
||||
import type { Entity, EntityManager } from "../entities";
|
||||
import {
|
||||
type EntityRelation,
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import type { CompiledQuery, TableMetadata } from "kysely";
|
||||
import type { IndexMetadata, SchemaResponse } from "../connection/Connection";
|
||||
import type { Entity, EntityManager } from "../entities";
|
||||
import { PrimaryField } from "../fields";
|
||||
import { $console } from "core/utils";
|
||||
import type { IndexMetadata, SchemaResponse } from "data/connection/Connection";
|
||||
import type { Entity, EntityManager } from "data/entities";
|
||||
import { PrimaryField } from "data/fields";
|
||||
import { $console } from "bknd/utils";
|
||||
|
||||
type IntrospectedTable = TableMetadata & {
|
||||
indices: IndexMetadata[];
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { transformObject } from "core/utils";
|
||||
import { Entity, type Field } from "data";
|
||||
import { Entity } from "data/entities";
|
||||
import type { Field } from "data/fields";
|
||||
import { FIELDS, RELATIONS, type TAppDataEntity, type TAppDataRelation } from "data/data-schema";
|
||||
|
||||
export function constructEntity(name: string, entityConfig: TAppDataEntity) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { test, describe, expect } from "bun:test";
|
||||
import * as q from "./query";
|
||||
import { s as schema, parse as $parse, type ParseOptions } from "bknd/core";
|
||||
import { parse as $parse, type ParseOptions } from "bknd/utils";
|
||||
|
||||
const parse = (v: unknown, o: ParseOptions = {}) =>
|
||||
$parse(q.repoQuery, v, {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { s } from "bknd/core";
|
||||
import { s } from "bknd/utils";
|
||||
import { WhereBuilder, type WhereQuery } from "data/entities/query/WhereBuilder";
|
||||
import { isObject, $console } from "core/utils";
|
||||
import type { anyOf, CoercionOptions, Schema } from "jsonv-ts";
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
import { transformObject } from "core/utils";
|
||||
import { Flow, HttpTrigger } from "flows";
|
||||
import { Hono } from "hono";
|
||||
import { Module } from "modules/Module";
|
||||
import { TASKS, flowsConfigSchema } from "./flows-schema";
|
||||
import type { s } from "bknd/core";
|
||||
import { type s, transformObject } from "bknd/utils";
|
||||
|
||||
export type AppFlowsSchema = s.Static<typeof flowsConfigSchema>;
|
||||
export type TAppFlowSchema = AppFlowsSchema["flows"][number];
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { transformObject } from "core/utils";
|
||||
import { TaskMap, TriggerMap } from "flows";
|
||||
import { s } from "bknd/core";
|
||||
import { s } from "bknd/utils";
|
||||
|
||||
export const TASKS = {
|
||||
...TaskMap,
|
||||
|
||||
@@ -2,7 +2,7 @@ import type { EventManager } from "core/events";
|
||||
import type { Flow } from "../Flow";
|
||||
import { Trigger } from "./Trigger";
|
||||
import { $console } from "core/utils";
|
||||
import { s } from "bknd/core";
|
||||
import { s } from "bknd/utils";
|
||||
|
||||
export class EventTrigger extends Trigger<typeof EventTrigger.schema> {
|
||||
override type = "event";
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import type { Context, Hono } from "hono";
|
||||
import type { Flow } from "../Flow";
|
||||
import { Trigger } from "./Trigger";
|
||||
import { s } from "bknd/core";
|
||||
import { s } from "bknd/utils";
|
||||
|
||||
const httpMethods = ["GET", "POST", "PUT", "PATCH", "DELETE"] as const;
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import type { Execution } from "../Execution";
|
||||
import type { Flow } from "../Flow";
|
||||
import { s, parse } from "bknd/core";
|
||||
import { s, parse } from "bknd/utils";
|
||||
|
||||
export class Trigger<Schema extends typeof Trigger.schema = typeof Trigger.schema> {
|
||||
// @todo: remove this
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
//import { BkndError, SimpleRenderer } from "core";
|
||||
import { BkndError } from "core/errors";
|
||||
|
||||
import { s, parse } from "bknd/core";
|
||||
import { s, parse } from "bknd/utils";
|
||||
import type { InputsMap } from "../flows/Execution";
|
||||
import { SimpleRenderer } from "core/template/SimpleRenderer";
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Task, dynamic } from "../Task";
|
||||
import { s } from "bknd/core";
|
||||
import { s } from "bknd/utils";
|
||||
|
||||
const FetchMethods = ["GET", "POST", "PUT", "PATCH", "DELETE"];
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Task } from "../Task";
|
||||
import { $console } from "core/utils";
|
||||
import { s } from "bknd/core";
|
||||
import { s } from "bknd/utils";
|
||||
|
||||
export class LogTask extends Task<typeof LogTask.schema> {
|
||||
type = "log";
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Task } from "../Task";
|
||||
import { s } from "bknd/core";
|
||||
import { s } from "bknd/utils";
|
||||
|
||||
export class RenderTask<Output extends Record<string, any>> extends Task<
|
||||
typeof RenderTask.schema,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Flow } from "../../flows/Flow";
|
||||
import { Task, dynamic } from "../Task";
|
||||
import { s } from "bknd/core";
|
||||
import { s } from "bknd/utils";
|
||||
|
||||
export class SubFlowTask<Output extends Record<string, any>> extends Task<
|
||||
typeof SubFlowTask.schema,
|
||||
|
||||
+124
-2
@@ -36,5 +36,127 @@ export type { BkndConfig } from "bknd/adapter";
|
||||
export * as middlewares from "modules/middlewares";
|
||||
export { registries } from "modules/registries";
|
||||
|
||||
export type { MediaFieldSchema } from "media/AppMedia";
|
||||
export type { UserFieldSchema } from "auth/AppAuth";
|
||||
/**
|
||||
* Core
|
||||
*/
|
||||
export { Exception, BkndError } from "core/errors";
|
||||
export { isDebug, env } from "core/env";
|
||||
export { type PrimaryFieldType, config, type DB, type AppEntity } from "core/config";
|
||||
export { Permission } from "core/security/Permission";
|
||||
export { getFlashMessage } from "core/server/flash";
|
||||
export * from "core/drivers";
|
||||
export { Event, InvalidEventReturn } from "core/events/Event";
|
||||
export type {
|
||||
ListenerMode,
|
||||
ListenerHandler,
|
||||
} from "core/events/EventListener";
|
||||
export { EventManager, type EmitsEvents, type EventClass } from "core/events/EventManager";
|
||||
|
||||
/**
|
||||
* Auth
|
||||
*/
|
||||
export {
|
||||
UserExistsException,
|
||||
UserNotFoundException,
|
||||
InvalidCredentialsException,
|
||||
} from "auth/errors";
|
||||
export type {
|
||||
ProfileExchange,
|
||||
User,
|
||||
SafeUser,
|
||||
CreateUser,
|
||||
AuthResponse,
|
||||
UserPool,
|
||||
AuthAction,
|
||||
AuthUserResolver,
|
||||
} from "auth/authenticate/Authenticator";
|
||||
export { AuthStrategy } from "auth/authenticate/strategies/Strategy";
|
||||
export * as AuthPermissions from "auth/auth-permissions";
|
||||
|
||||
/**
|
||||
* Media
|
||||
*/
|
||||
export { getExtensionFromName, getRandomizedFilename } from "media/utils";
|
||||
export * as StorageEvents from "media/storage/events";
|
||||
export * as MediaPermissions from "media/media-permissions";
|
||||
export type { FileUploadedEventData } from "media/storage/events";
|
||||
export { guess as guessMimeType } from "media/storage/mime-types-tiny";
|
||||
export {
|
||||
Storage,
|
||||
type FileMeta,
|
||||
type FileListObject,
|
||||
type StorageConfig,
|
||||
type FileBody,
|
||||
type FileUploadPayload,
|
||||
} from "media/storage/Storage";
|
||||
export { StorageAdapter } from "media/storage/StorageAdapter";
|
||||
|
||||
/**
|
||||
* Data
|
||||
*/
|
||||
import { MutatorEvents, RepositoryEvents } from "data/events";
|
||||
export const DataEvents = { ...MutatorEvents, ...RepositoryEvents };
|
||||
export type {
|
||||
RepoQuery,
|
||||
RepoQueryIn,
|
||||
} from "data/server/query";
|
||||
export type { WhereQuery } from "data/entities/query/WhereBuilder";
|
||||
export { KyselyPluginRunner } from "data/plugins/KyselyPluginRunner";
|
||||
export * as DataPermissions from "data/permissions";
|
||||
export { libsql } from "data/connection/sqlite/libsql/LibsqlConnection";
|
||||
export {
|
||||
genericSqlite,
|
||||
genericSqliteUtils,
|
||||
type GenericSqliteConnection,
|
||||
} from "data/connection/sqlite/GenericSqliteConnection";
|
||||
export {
|
||||
EntityTypescript,
|
||||
type EntityTypescriptOptions,
|
||||
type TEntityTSType,
|
||||
type TFieldTSType,
|
||||
} from "data/entities/EntityTypescript";
|
||||
export * from "data/fields/Field";
|
||||
export * from "data/errors";
|
||||
export type { EntityRelation } from "data/relations";
|
||||
export type * from "data/entities/Entity";
|
||||
export type { EntityManager } from "data/entities/EntityManager";
|
||||
export type { SchemaManager } from "data/schema/SchemaManager";
|
||||
export {
|
||||
BaseIntrospector,
|
||||
Connection,
|
||||
customIntrospector,
|
||||
type FieldSpec,
|
||||
type IndexSpec,
|
||||
type DbFunctions,
|
||||
type SchemaResponse,
|
||||
type ConnQuery,
|
||||
type ConnQueryResults,
|
||||
} from "data/connection";
|
||||
export { SqliteConnection } from "data/connection/sqlite/SqliteConnection";
|
||||
export { SqliteIntrospector } from "data/connection/sqlite/SqliteIntrospector";
|
||||
export { SqliteLocalConnection } from "data/connection/sqlite/SqliteLocalConnection";
|
||||
export {
|
||||
text,
|
||||
number,
|
||||
date,
|
||||
datetime,
|
||||
week,
|
||||
boolean,
|
||||
enumm,
|
||||
json,
|
||||
jsonSchema,
|
||||
media,
|
||||
medium,
|
||||
make,
|
||||
entity,
|
||||
relation,
|
||||
index,
|
||||
em,
|
||||
type InferEntityFields,
|
||||
type InferFields,
|
||||
type Simplify,
|
||||
type InferField,
|
||||
type InsertSchema,
|
||||
type Schema,
|
||||
type FieldSchema,
|
||||
} from "data/prototype";
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
import type { AppEntity } from "core";
|
||||
import type { AppEntity, FileUploadedEventData, StorageAdapter } from "bknd";
|
||||
import { $console } from "core/utils";
|
||||
import type { Entity, EntityManager } from "data";
|
||||
import { type FileUploadedEventData, Storage, type StorageAdapter, MediaPermissions } from "media";
|
||||
import type { Entity, EntityManager } from "data/entities";
|
||||
import { Storage } from "media/storage/Storage";
|
||||
import { Module } from "modules/Module";
|
||||
import { type FieldSchema, em, entity } from "../data/prototype";
|
||||
import { MediaController } from "./api/MediaController";
|
||||
import { buildMediaSchema, type mediaConfigSchema, registry, type TAppMediaConfig } from "./media-schema";
|
||||
import { buildMediaSchema, registry, type TAppMediaConfig } from "./media-schema";
|
||||
import { mediaFields } from "./media-entities";
|
||||
import * as MediaPermissions from "media/media-permissions";
|
||||
|
||||
export type MediaFieldSchema = FieldSchema<typeof AppMedia.mediaFields>;
|
||||
declare module "core" {
|
||||
declare module "bknd" {
|
||||
interface Media extends AppEntity, MediaFieldSchema {}
|
||||
interface DB {
|
||||
media: Media;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Field, baseFieldConfigSchema } from "data/fields";
|
||||
import { s } from "bknd/core";
|
||||
import { s } from "bknd/utils";
|
||||
|
||||
export const mediaFieldConfigSchema = s
|
||||
.strictObject({
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
import type { FileListObject } from "media";
|
||||
import type { FileListObject } from "media/storage/Storage";
|
||||
import {
|
||||
type BaseModuleApiOptions,
|
||||
ModuleApi,
|
||||
type PrimaryFieldType,
|
||||
type TInput,
|
||||
} from "modules/ModuleApi";
|
||||
import type { FileWithPath } from "ui/elements/media/file-selector";
|
||||
import type { ApiFetcher } from "Api";
|
||||
|
||||
export type MediaApiOptions = BaseModuleApiOptions & {
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
import { isDebug } from "core";
|
||||
import { HttpStatus, getFileFromContext } from "core/utils";
|
||||
import type { StorageAdapter } from "media";
|
||||
import { StorageEvents, getRandomizedFilename, MediaPermissions } from "media";
|
||||
import { DataPermissions } from "data";
|
||||
import { isDebug } from "core/env";
|
||||
import type { StorageAdapter } from "media/storage/StorageAdapter";
|
||||
import * as DataPermissions from "data/permissions";
|
||||
import { Controller } from "modules/Controller";
|
||||
import type { AppMedia } from "../AppMedia";
|
||||
import { MediaField } from "../MediaField";
|
||||
import { jsc, s, describeRoute } from "bknd/core";
|
||||
import * as MediaPermissions from "media/media-permissions";
|
||||
import * as StorageEvents from "media/storage/events";
|
||||
import { jsc, s, describeRoute, HttpStatus, getFileFromContext } from "bknd/utils";
|
||||
import { getRandomizedFilename } from "media/utils";
|
||||
|
||||
export class MediaController extends Controller {
|
||||
constructor(private readonly media: AppMedia) {
|
||||
|
||||
@@ -1,51 +0,0 @@
|
||||
import { type Constructor, Registry } from "core";
|
||||
|
||||
export { guess as guessMimeType } from "./storage/mime-types-tiny";
|
||||
export {
|
||||
Storage,
|
||||
type FileMeta,
|
||||
type FileListObject,
|
||||
type StorageConfig,
|
||||
type FileBody,
|
||||
type FileUploadPayload,
|
||||
} from "./storage/Storage";
|
||||
import { StorageAdapter } from "./storage/StorageAdapter";
|
||||
import {
|
||||
type CloudinaryConfig,
|
||||
StorageCloudinaryAdapter,
|
||||
} from "./storage/adapters/cloudinary/StorageCloudinaryAdapter";
|
||||
import { type S3AdapterConfig, StorageS3Adapter } from "./storage/adapters/s3/StorageS3Adapter";
|
||||
import type { s } from "bknd/core";
|
||||
|
||||
export { StorageAdapter };
|
||||
export { StorageS3Adapter, type S3AdapterConfig, StorageCloudinaryAdapter, type CloudinaryConfig };
|
||||
|
||||
export * as StorageEvents from "./storage/events";
|
||||
export * as MediaPermissions from "./media-permissions";
|
||||
export type { FileUploadedEventData } from "./storage/events";
|
||||
export * from "./utils";
|
||||
|
||||
type ClassThatImplements<T> = Constructor<T> & { prototype: T };
|
||||
|
||||
export const MediaAdapterRegistry = new Registry<{
|
||||
cls: ClassThatImplements<StorageAdapter>;
|
||||
schema: s.Schema;
|
||||
}>((cls: ClassThatImplements<StorageAdapter>) => ({
|
||||
cls,
|
||||
schema: cls.prototype.getSchema() as s.Schema,
|
||||
}))
|
||||
.register("s3", StorageS3Adapter)
|
||||
.register("cloudinary", StorageCloudinaryAdapter);
|
||||
|
||||
export const Adapters = {
|
||||
s3: {
|
||||
cls: StorageS3Adapter,
|
||||
schema: StorageS3Adapter.prototype.getSchema(),
|
||||
},
|
||||
cloudinary: {
|
||||
cls: StorageCloudinaryAdapter,
|
||||
schema: StorageCloudinaryAdapter.prototype.getSchema(),
|
||||
},
|
||||
} as const;
|
||||
|
||||
export { adapterTestSuite } from "./storage/adapters/adapter-test-suite";
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Permission } from "core";
|
||||
import { Permission } from "core/security/Permission";
|
||||
|
||||
export const readFile = new Permission("media.file.read");
|
||||
export const listFiles = new Permission("media.file.list");
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user