From 45138c25f0c822bb666ab700892221289ee45db8 Mon Sep 17 00:00:00 2001 From: dswbx Date: Wed, 2 Jul 2025 16:36:06 +0200 Subject: [PATCH] refactor auth/media entities to separate files, suppress node:sqlite warning --- app/package.json | 2 +- app/src/auth/AppAuth.ts | 16 +--- app/src/auth/auth-entities.ts | 14 +++ app/src/data/entities/EntityTypescript.ts | 7 +- app/src/data/prototype/index.ts | 104 +++++++++++----------- app/src/index.ts | 11 +++ app/src/media/AppMedia.ts | 25 +----- app/src/media/media-entities.ts | 14 +++ 8 files changed, 104 insertions(+), 89 deletions(-) create mode 100644 app/src/auth/auth-entities.ts create mode 100644 app/src/media/media-entities.ts diff --git a/app/package.json b/app/package.json index 02a5f06..f0624c2 100644 --- a/app/package.json +++ b/app/package.json @@ -3,7 +3,7 @@ "type": "module", "sideEffects": false, "bin": "./dist/cli/index.js", - "version": "0.15.0-rc.7", + "version": "0.15.0-rc.8", "description": "Lightweight Firebase/Supabase alternative built to run anywhere — incl. Next.js, React Router, Astro, Cloudflare, Bun, Node, AWS Lambda & more.", "homepage": "https://bknd.io", "repository": { diff --git a/app/src/auth/AppAuth.ts b/app/src/auth/AppAuth.ts index ac78b9f..474e86a 100644 --- a/app/src/auth/AppAuth.ts +++ b/app/src/auth/AppAuth.ts @@ -3,12 +3,13 @@ import type { PasswordStrategy } from "auth/authenticate/strategies"; import type { DB } from "core"; import { $console, secureRandomString, transformObject } from "core/utils"; import type { Entity, EntityManager } from "data"; -import { em, entity, enumm, type FieldSchema, text } from "data/prototype"; +import { em, entity, enumm, type FieldSchema } from "data/prototype"; import { Module } from "modules/Module"; import { AuthController } from "./api/AuthController"; import { type AppAuthSchema, authConfigSchema, STRATEGIES } from "./auth-schema"; import { AppUserPool } from "auth/AppUserPool"; import type { AppEntity } from "core/config"; +import { usersFields } from "./auth-entities"; export type UserFieldSchema = FieldSchema; declare module "core" { @@ -125,18 +126,7 @@ export class AppAuth extends Module { return this.em.entity(entity_name) as any; } - static usersFields = { - email: text().required(), - strategy: text({ - fillable: ["create"], - hidden: ["update", "form"], - }).required(), - strategy_value: text({ - fillable: ["create"], - hidden: ["read", "table", "update", "form"], - }).required(), - role: text(), - }; + static usersFields = usersFields; registerEntities() { const users = this.getUsersEntity(true); diff --git a/app/src/auth/auth-entities.ts b/app/src/auth/auth-entities.ts new file mode 100644 index 0000000..5a9aea4 --- /dev/null +++ b/app/src/auth/auth-entities.ts @@ -0,0 +1,14 @@ +import { text } from "data/prototype"; + +export const usersFields = { + email: text().required(), + strategy: text({ + fillable: ["create"], + hidden: ["update", "form"], + }).required(), + strategy_value: text({ + fillable: ["create"], + hidden: ["read", "table", "update", "form"], + }).required(), + role: text(), +}; diff --git a/app/src/data/entities/EntityTypescript.ts b/app/src/data/entities/EntityTypescript.ts index b0aa89e..197c22d 100644 --- a/app/src/data/entities/EntityTypescript.ts +++ b/app/src/data/entities/EntityTypescript.ts @@ -1,6 +1,7 @@ import type { Entity, EntityManager, EntityRelation, TEntityType } from "data"; import { autoFormatString } from "core/utils"; -import { AppAuth, AppMedia } from "modules"; +import { usersFields } from "auth/auth-entities"; +import { mediaFields } from "media/media-entities"; export type TEntityTSType = { name: string; @@ -32,8 +33,8 @@ export type EntityTypescriptOptions = { // keep a local copy here until properties have a type const systemEntities = { - users: AppAuth.usersFields, - media: AppMedia.mediaFields, + users: usersFields, + media: mediaFields, }; export class EntityTypescript { diff --git a/app/src/data/prototype/index.ts b/app/src/data/prototype/index.ts index 489607c..4f25aeb 100644 --- a/app/src/data/prototype/index.ts +++ b/app/src/data/prototype/index.ts @@ -3,16 +3,13 @@ import { EntityManager } from "data/entities/EntityManager"; import type { Generated } from "kysely"; import { MediaField, type MediaFieldConfig, type MediaItem } from "media/MediaField"; import type { ModuleConfigs } from "modules"; + import { BooleanField, type BooleanFieldConfig, - type Connection, DateField, type DateFieldConfig, - Entity, - type EntityConfig, EntityIndex, - type EntityRelation, EnumField, type EnumFieldConfig, type Field, @@ -20,20 +17,27 @@ import { type JsonFieldConfig, JsonSchemaField, type JsonSchemaFieldConfig, + NumberField, + type NumberFieldConfig, + TextField, + type TextFieldConfig, +} from "data/fields"; + +import { Entity, type EntityConfig, type TEntityType } from "data/entities"; + +import type { Connection } from "data/connection"; + +import { + type EntityRelation, ManyToManyRelation, type ManyToManyRelationConfig, ManyToOneRelation, type ManyToOneRelationConfig, - NumberField, - type NumberFieldConfig, OneToOneRelation, type OneToOneRelationConfig, PolymorphicRelation, type PolymorphicRelationConfig, - type TEntityType, - TextField, - type TextFieldConfig, -} from "../index"; +} from "data/relations"; type Options = { entity: { name: string; fields: Record> }; @@ -61,6 +65,46 @@ const FieldMap = { } as const; type TFieldType = keyof typeof FieldMap; +export class FieldPrototype { + constructor( + public type: TFieldType, + public config: any, + public is_required: boolean, + ) {} + + required() { + this.is_required = true; + return this; + } + + getField(o: Options): Field { + if (!FieldMap[this.type]) { + throw new Error(`Unknown field type: ${this.type}`); + } + try { + return FieldMap[this.type](o) as unknown as Field; + } catch (e) { + throw new Error(`Faild to construct field "${this.type}": ${e}`); + } + } + + make(field_name: string): Field { + if (!FieldMap[this.type]) { + throw new Error(`Unknown field type: ${this.type}`); + } + try { + return FieldMap[this.type]({ + entity: { name: "unknown", fields: {} }, + field_name, + config: this.config, + is_required: this.is_required, + }) as unknown as Field; + } catch (e) { + throw new Error(`Faild to construct field "${this.type}": ${e}`); + } + } +} + export function text( config?: Omit, ): TextField & { required: () => TextField } { @@ -132,46 +176,6 @@ export function make>(name: string, field: Actual throw new Error("Invalid field"); } -export class FieldPrototype { - constructor( - public type: TFieldType, - public config: any, - public is_required: boolean, - ) {} - - required() { - this.is_required = true; - return this; - } - - getField(o: Options): Field { - if (!FieldMap[this.type]) { - throw new Error(`Unknown field type: ${this.type}`); - } - try { - return FieldMap[this.type](o) as unknown as Field; - } catch (e) { - throw new Error(`Faild to construct field "${this.type}": ${e}`); - } - } - - make(field_name: string): Field { - if (!FieldMap[this.type]) { - throw new Error(`Unknown field type: ${this.type}`); - } - try { - return FieldMap[this.type]({ - entity: { name: "unknown", fields: {} }, - field_name, - config: this.config, - is_required: this.is_required, - }) as unknown as Field; - } catch (e) { - throw new Error(`Faild to construct field "${this.type}": ${e}`); - } - } -} - export function entity< EntityName extends string, Fields extends Record>, diff --git a/app/src/index.ts b/app/src/index.ts index afac83d..ed12dbb 100644 --- a/app/src/index.ts +++ b/app/src/index.ts @@ -1,3 +1,14 @@ +try { + /** + * Adding this to avoid warnings from node:sqlite being experimental + */ + const { emitWarning } = process; + process.emitWarning = (warning: string, ...args: any[]) => { + if (warning.includes("SQLite is an experimental feature")) return; + return emitWarning(warning, ...args); + }; +} catch (e) {} + export { App, createApp, diff --git a/app/src/media/AppMedia.ts b/app/src/media/AppMedia.ts index 36fce41..235a927 100644 --- a/app/src/media/AppMedia.ts +++ b/app/src/media/AppMedia.ts @@ -3,18 +3,10 @@ import { $console } from "core/utils"; import type { Entity, EntityManager } from "data"; import { type FileUploadedEventData, Storage, type StorageAdapter, MediaPermissions } from "media"; import { Module } from "modules/Module"; -import { - type FieldSchema, - boolean, - datetime, - em, - entity, - json, - number, - text, -} from "../data/prototype"; +import { type FieldSchema, em, entity } from "../data/prototype"; import { MediaController } from "./api/MediaController"; import { buildMediaSchema, type mediaConfigSchema, registry } from "./media-schema"; +import { mediaFields } from "./media-entities"; export type MediaFieldSchema = FieldSchema; declare module "core" { @@ -95,18 +87,7 @@ export class AppMedia extends Module { }; } - static mediaFields = { - path: text().required(), - folder: boolean({ default_value: false, hidden: true, fillable: ["create"] }), - mime_type: text(), - size: number(), - scope: text({ hidden: true, fillable: ["create"] }), - etag: text(), - modified_at: datetime(), - reference: text(), - entity_id: number(), - metadata: json(), - }; + static mediaFields = mediaFields; getMediaEntity(forceCreate?: boolean): Entity<"media", typeof AppMedia.mediaFields> { const entity_name = this.config.entity_name; diff --git a/app/src/media/media-entities.ts b/app/src/media/media-entities.ts new file mode 100644 index 0000000..a074b18 --- /dev/null +++ b/app/src/media/media-entities.ts @@ -0,0 +1,14 @@ +import { boolean, datetime, json, number, text } from "data/prototype"; + +export const mediaFields = { + path: text().required(), + folder: boolean({ default_value: false, hidden: true, fillable: ["create"] }), + mime_type: text(), + size: number(), + scope: text({ hidden: true, fillable: ["create"] }), + etag: text(), + modified_at: datetime(), + reference: text(), + entity_id: number(), + metadata: json(), +};