mirror of
https://github.com/shishantbiswas/bknd.git
synced 2026-03-16 04:27:21 +00:00
refactor auth/media entities to separate files, suppress node:sqlite warning
This commit is contained in:
@@ -3,7 +3,7 @@
|
|||||||
"type": "module",
|
"type": "module",
|
||||||
"sideEffects": false,
|
"sideEffects": false,
|
||||||
"bin": "./dist/cli/index.js",
|
"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.",
|
"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",
|
"homepage": "https://bknd.io",
|
||||||
"repository": {
|
"repository": {
|
||||||
|
|||||||
@@ -3,12 +3,13 @@ import type { PasswordStrategy } from "auth/authenticate/strategies";
|
|||||||
import type { DB } from "core";
|
import type { DB } from "core";
|
||||||
import { $console, secureRandomString, transformObject } from "core/utils";
|
import { $console, secureRandomString, transformObject } from "core/utils";
|
||||||
import type { Entity, EntityManager } from "data";
|
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 { Module } from "modules/Module";
|
||||||
import { AuthController } from "./api/AuthController";
|
import { AuthController } from "./api/AuthController";
|
||||||
import { type AppAuthSchema, authConfigSchema, STRATEGIES } from "./auth-schema";
|
import { type AppAuthSchema, authConfigSchema, STRATEGIES } from "./auth-schema";
|
||||||
import { AppUserPool } from "auth/AppUserPool";
|
import { AppUserPool } from "auth/AppUserPool";
|
||||||
import type { AppEntity } from "core/config";
|
import type { AppEntity } from "core/config";
|
||||||
|
import { usersFields } from "./auth-entities";
|
||||||
|
|
||||||
export type UserFieldSchema = FieldSchema<typeof AppAuth.usersFields>;
|
export type UserFieldSchema = FieldSchema<typeof AppAuth.usersFields>;
|
||||||
declare module "core" {
|
declare module "core" {
|
||||||
@@ -125,18 +126,7 @@ export class AppAuth extends Module<typeof authConfigSchema> {
|
|||||||
return this.em.entity(entity_name) as any;
|
return this.em.entity(entity_name) as any;
|
||||||
}
|
}
|
||||||
|
|
||||||
static usersFields = {
|
static usersFields = 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(),
|
|
||||||
};
|
|
||||||
|
|
||||||
registerEntities() {
|
registerEntities() {
|
||||||
const users = this.getUsersEntity(true);
|
const users = this.getUsersEntity(true);
|
||||||
|
|||||||
14
app/src/auth/auth-entities.ts
Normal file
14
app/src/auth/auth-entities.ts
Normal file
@@ -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(),
|
||||||
|
};
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
import type { Entity, EntityManager, EntityRelation, TEntityType } from "data";
|
import type { Entity, EntityManager, EntityRelation, TEntityType } from "data";
|
||||||
import { autoFormatString } from "core/utils";
|
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 = {
|
export type TEntityTSType = {
|
||||||
name: string;
|
name: string;
|
||||||
@@ -32,8 +33,8 @@ export type EntityTypescriptOptions = {
|
|||||||
|
|
||||||
// keep a local copy here until properties have a type
|
// keep a local copy here until properties have a type
|
||||||
const systemEntities = {
|
const systemEntities = {
|
||||||
users: AppAuth.usersFields,
|
users: usersFields,
|
||||||
media: AppMedia.mediaFields,
|
media: mediaFields,
|
||||||
};
|
};
|
||||||
|
|
||||||
export class EntityTypescript {
|
export class EntityTypescript {
|
||||||
|
|||||||
@@ -3,16 +3,13 @@ import { EntityManager } from "data/entities/EntityManager";
|
|||||||
import type { Generated } from "kysely";
|
import type { Generated } from "kysely";
|
||||||
import { MediaField, type MediaFieldConfig, type MediaItem } from "media/MediaField";
|
import { MediaField, type MediaFieldConfig, type MediaItem } from "media/MediaField";
|
||||||
import type { ModuleConfigs } from "modules";
|
import type { ModuleConfigs } from "modules";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
BooleanField,
|
BooleanField,
|
||||||
type BooleanFieldConfig,
|
type BooleanFieldConfig,
|
||||||
type Connection,
|
|
||||||
DateField,
|
DateField,
|
||||||
type DateFieldConfig,
|
type DateFieldConfig,
|
||||||
Entity,
|
|
||||||
type EntityConfig,
|
|
||||||
EntityIndex,
|
EntityIndex,
|
||||||
type EntityRelation,
|
|
||||||
EnumField,
|
EnumField,
|
||||||
type EnumFieldConfig,
|
type EnumFieldConfig,
|
||||||
type Field,
|
type Field,
|
||||||
@@ -20,20 +17,27 @@ import {
|
|||||||
type JsonFieldConfig,
|
type JsonFieldConfig,
|
||||||
JsonSchemaField,
|
JsonSchemaField,
|
||||||
type JsonSchemaFieldConfig,
|
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,
|
ManyToManyRelation,
|
||||||
type ManyToManyRelationConfig,
|
type ManyToManyRelationConfig,
|
||||||
ManyToOneRelation,
|
ManyToOneRelation,
|
||||||
type ManyToOneRelationConfig,
|
type ManyToOneRelationConfig,
|
||||||
NumberField,
|
|
||||||
type NumberFieldConfig,
|
|
||||||
OneToOneRelation,
|
OneToOneRelation,
|
||||||
type OneToOneRelationConfig,
|
type OneToOneRelationConfig,
|
||||||
PolymorphicRelation,
|
PolymorphicRelation,
|
||||||
type PolymorphicRelationConfig,
|
type PolymorphicRelationConfig,
|
||||||
type TEntityType,
|
} from "data/relations";
|
||||||
TextField,
|
|
||||||
type TextFieldConfig,
|
|
||||||
} from "../index";
|
|
||||||
|
|
||||||
type Options<Config = any> = {
|
type Options<Config = any> = {
|
||||||
entity: { name: string; fields: Record<string, Field<any, any, any>> };
|
entity: { name: string; fields: Record<string, Field<any, any, any>> };
|
||||||
@@ -61,6 +65,46 @@ const FieldMap = {
|
|||||||
} as const;
|
} as const;
|
||||||
type TFieldType = keyof typeof FieldMap;
|
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(
|
export function text(
|
||||||
config?: Omit<TextFieldConfig, "required">,
|
config?: Omit<TextFieldConfig, "required">,
|
||||||
): TextField<false> & { required: () => TextField<true> } {
|
): TextField<false> & { required: () => TextField<true> } {
|
||||||
@@ -132,46 +176,6 @@ export function make<Actual extends Field<any, any>>(name: string, field: Actual
|
|||||||
throw new Error("Invalid field");
|
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<
|
export function entity<
|
||||||
EntityName extends string,
|
EntityName extends string,
|
||||||
Fields extends Record<string, Field<any, any, any>>,
|
Fields extends Record<string, Field<any, any, any>>,
|
||||||
|
|||||||
@@ -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 {
|
export {
|
||||||
App,
|
App,
|
||||||
createApp,
|
createApp,
|
||||||
|
|||||||
@@ -3,18 +3,10 @@ import { $console } from "core/utils";
|
|||||||
import type { Entity, EntityManager } from "data";
|
import type { Entity, EntityManager } from "data";
|
||||||
import { type FileUploadedEventData, Storage, type StorageAdapter, MediaPermissions } from "media";
|
import { type FileUploadedEventData, Storage, type StorageAdapter, MediaPermissions } from "media";
|
||||||
import { Module } from "modules/Module";
|
import { Module } from "modules/Module";
|
||||||
import {
|
import { type FieldSchema, em, entity } from "../data/prototype";
|
||||||
type FieldSchema,
|
|
||||||
boolean,
|
|
||||||
datetime,
|
|
||||||
em,
|
|
||||||
entity,
|
|
||||||
json,
|
|
||||||
number,
|
|
||||||
text,
|
|
||||||
} from "../data/prototype";
|
|
||||||
import { MediaController } from "./api/MediaController";
|
import { MediaController } from "./api/MediaController";
|
||||||
import { buildMediaSchema, type mediaConfigSchema, registry } from "./media-schema";
|
import { buildMediaSchema, type mediaConfigSchema, registry } from "./media-schema";
|
||||||
|
import { mediaFields } from "./media-entities";
|
||||||
|
|
||||||
export type MediaFieldSchema = FieldSchema<typeof AppMedia.mediaFields>;
|
export type MediaFieldSchema = FieldSchema<typeof AppMedia.mediaFields>;
|
||||||
declare module "core" {
|
declare module "core" {
|
||||||
@@ -95,18 +87,7 @@ export class AppMedia extends Module<typeof mediaConfigSchema> {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
static mediaFields = {
|
static mediaFields = 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(),
|
|
||||||
};
|
|
||||||
|
|
||||||
getMediaEntity(forceCreate?: boolean): Entity<"media", typeof AppMedia.mediaFields> {
|
getMediaEntity(forceCreate?: boolean): Entity<"media", typeof AppMedia.mediaFields> {
|
||||||
const entity_name = this.config.entity_name;
|
const entity_name = this.config.entity_name;
|
||||||
|
|||||||
14
app/src/media/media-entities.ts
Normal file
14
app/src/media/media-entities.ts
Normal file
@@ -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(),
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user