initial refactor

This commit is contained in:
dswbx
2025-06-21 13:35:58 +02:00
parent b2086c4da7
commit 42edce904f
93 changed files with 1021 additions and 1216 deletions
+17 -2
View File
@@ -5,7 +5,7 @@ import type { SafeUser } from "auth";
import type { EntityManager } from "data";
import { s } from "core/object/schema";
export type ServerEnv = Env & {
export interface ServerEnv extends Env {
Variables: {
app: App;
// to prevent resolving auth multiple times
@@ -17,7 +17,22 @@ export type ServerEnv = Env & {
};
html?: string;
};
};
[key: string]: any;
}
/* export type ServerEnv = Env & {
Variables: {
app: App;
// to prevent resolving auth multiple times
auth?: {
resolved: boolean;
registered: boolean;
skip: boolean;
user?: SafeUser;
};
html?: string;
};
}; */
export class Controller {
protected middlewares = middlewares;
+13 -8
View File
@@ -1,11 +1,13 @@
import type { Guard } from "auth";
import { type DebugLogger, SchemaObject } from "core";
import type { EventManager } from "core/events";
import type { Static, TSchema } from "core/utils";
import type { Connection, EntityManager } from "data";
import type { Hono } from "hono";
import type { ServerEnv } from "modules/Controller";
import type { ModuleHelper } from "./ModuleHelper";
import type { s } from "core/object/schema";
type PartialRec<T> = { [P in keyof T]?: PartialRec<T[P]> };
export type ModuleBuildContext = {
connection: Connection;
@@ -18,13 +20,13 @@ export type ModuleBuildContext = {
helper: ModuleHelper;
};
export abstract class Module<Schema extends TSchema = TSchema, ConfigSchema = Static<Schema>> {
export abstract class Module<Schema extends object = object> {
private _built = false;
private _schema: SchemaObject<ReturnType<(typeof this)["getSchema"]>>;
private _listener: any = () => null;
constructor(
initial?: Partial<Static<Schema>>,
initial?: PartialRec<Schema>,
protected _ctx?: ModuleBuildContext,
) {
this._schema = new SchemaObject(this.getSchema(), initial, {
@@ -47,7 +49,7 @@ export abstract class Module<Schema extends TSchema = TSchema, ConfigSchema = St
ctx_reload_required: boolean;
};
onBeforeUpdate(from: ConfigSchema, to: ConfigSchema): ConfigSchema | Promise<ConfigSchema> {
onBeforeUpdate(from: Schema, to: Schema): Schema | Promise<Schema> {
return to;
}
@@ -75,11 +77,13 @@ export abstract class Module<Schema extends TSchema = TSchema, ConfigSchema = St
return undefined;
}
get configDefault(): Static<ReturnType<(typeof this)["getSchema"]>> {
return this._schema.default();
//get configDefault(): s.Static<ReturnType<(typeof this)["getSchema"]>> {
get configDefault(): Schema {
return this._schema.default() as any;
}
get config(): Static<ReturnType<(typeof this)["getSchema"]>> {
//get config(): s.Static<ReturnType<(typeof this)["getSchema"]>> {
get config(): Schema {
return this._schema.get();
}
@@ -130,7 +134,8 @@ export abstract class Module<Schema extends TSchema = TSchema, ConfigSchema = St
}
}
toJSON(secrets?: boolean): Static<ReturnType<(typeof this)["getSchema"]>> {
//toJSON(secrets?: boolean): s.Static<ReturnType<(typeof this)["getSchema"]>> {
toJSON(secrets?: boolean): Schema {
return this.config;
}
}
+14 -22
View File
@@ -2,15 +2,7 @@ import { Guard } from "auth";
import { $console, BkndError, DebugLogger, env } from "core";
import { EventManager } from "core/events";
import * as $diff from "core/object/diff";
import {
Default,
type Static,
StringEnum,
mark,
objectEach,
stripMark,
transformObject,
} from "core/utils";
import { objectEach, transformObject } from "core/utils";
import type { Connection, Schema } from "data";
import { EntityManager } from "data/entities/EntityManager";
import * as proto from "data/prototype";
@@ -26,18 +18,17 @@ import { AppFlows } from "../flows/AppFlows";
import { AppMedia } from "../media/AppMedia";
import type { ServerEnv } from "./Controller";
import { Module, type ModuleBuildContext } from "./Module";
import * as tbbox from "@sinclair/typebox";
import { ModuleHelper } from "./ModuleHelper";
const { Type } = tbbox;
import { s, mark, stripMark } from "core/object/schema";
export type { ModuleBuildContext };
export const MODULES = {
server: AppServer,
data: AppData,
data: AppData, // @todo:
auth: AppAuth,
media: AppMedia,
flows: AppFlows,
flows: AppFlows, // @todo:
} as const;
// get names of MODULES as an array
@@ -53,7 +44,7 @@ export type ModuleSchemas = {
};
export type ModuleConfigs = {
[K in keyof ModuleSchemas]: Static<ModuleSchemas[K]>;
[K in keyof ModuleSchemas]: s.Static<ModuleSchemas[K]>;
};
type PartialRec<T> = { [P in keyof T]?: PartialRec<T[P]> };
@@ -101,14 +92,14 @@ export type ConfigTable<Json = ModuleConfigs> = {
updated_at?: Date;
};
const configJsonSchema = Type.Union([
const configJsonSchema = s.anyOf([
getDefaultSchema(),
Type.Array(
Type.Object({
t: StringEnum(["a", "r", "e"]),
p: Type.Array(Type.Union([Type.String(), Type.Number()])),
o: Type.Optional(Type.Any()),
n: Type.Optional(Type.Any()),
s.array(
s.strictObject({
t: s.string({ enum: ["a", "r", "e"] }),
p: s.array(s.anyOf([s.string(), s.number()])),
o: s.any().optional(),
n: s.any().optional(),
}),
),
]);
@@ -717,7 +708,8 @@ export function getDefaultSchema() {
export function getDefaultConfig(): ModuleConfigs {
const config = transformObject(MODULES, (module) => {
return Default(module.prototype.getSchema(), {});
return module.prototype.getSchema().template();
//return Default(module.prototype.getSchema(), {});
});
return config as any;
+16 -26
View File
@@ -1,37 +1,27 @@
import { Exception, isDebug, $console } from "core";
import { type Static, StringEnum } from "core/utils";
import { cors } from "hono/cors";
import { Module } from "modules/Module";
import * as tbbox from "@sinclair/typebox";
import { AuthException } from "auth/errors";
const { Type } = tbbox;
import { s } from "core/object/schema";
const serverMethods = ["GET", "POST", "PATCH", "PUT", "DELETE"];
const serverMethods = ["GET", "POST", "PATCH", "PUT", "DELETE"] as const;
export const serverConfigSchema = Type.Object(
{
cors: Type.Object(
{
origin: Type.String({ default: "*" }),
allow_methods: Type.Array(StringEnum(serverMethods), {
default: serverMethods,
uniqueItems: true,
}),
allow_headers: Type.Array(Type.String(), {
default: ["Content-Type", "Content-Length", "Authorization", "Accept"],
}),
},
{ default: {}, additionalProperties: false },
),
},
{
additionalProperties: false,
},
);
export const serverConfigSchema = s.strictObject({
cors: s.strictObject({
origin: s.string({ default: "*" }),
allow_methods: s.array(s.string({ enum: serverMethods }), {
default: serverMethods,
uniqueItems: true,
}),
allow_headers: s.array(s.string(), {
default: ["Content-Type", "Content-Length", "Authorization", "Accept"],
}),
}),
});
export type AppServerConfig = Static<typeof serverConfigSchema>;
export type AppServerConfig = s.Static<typeof serverConfigSchema>;
export class AppServer extends Module<typeof serverConfigSchema> {
export class AppServer extends Module<AppServerConfig> {
override getRestrictedPaths() {
return [];
}
+12 -17
View File
@@ -1,15 +1,8 @@
/// <reference types="@cloudflare/workers-types" />
import type { App } from "App";
import { $console, tbValidator as tb } from "core";
import {
StringEnum,
TypeInvalidError,
datetimeStringLocal,
datetimeStringUTC,
getTimezone,
getTimezoneOffset,
} from "core/utils";
import { $console } from "core";
import { datetimeStringLocal, datetimeStringUTC, getTimezone, getTimezoneOffset } from "core/utils";
import { getRuntimeKey } from "core/utils";
import type { Context, Hono } from "hono";
import { Controller } from "modules/Controller";
@@ -20,11 +13,11 @@ import {
type ModuleConfigs,
type ModuleSchemas,
type ModuleKey,
getDefaultConfig,
} from "modules/ModuleManager";
import * as SystemPermissions from "modules/permissions";
import { jsc, s, describeRoute } from "core/object/schema";
import { jsc, s, describeRoute, InvalidSchemaError } from "core/object/schema";
import { getVersion } from "core/env";
export type ConfigUpdate<Key extends ModuleKey = ModuleKey> = {
success: true;
module: Key;
@@ -104,7 +97,7 @@ export class SystemController extends Controller {
} catch (e) {
$console.error("config update error", e);
if (e instanceof TypeInvalidError) {
if (e instanceof InvalidSchemaError) {
return c.json(
{ success: false, type: "type-invalid", errors: e.errors },
{ status: 400 },
@@ -234,11 +227,13 @@ export class SystemController extends Controller {
permission(SystemPermissions.schemaRead),
jsc(
"query",
s.partialObject({
config: s.boolean(),
secrets: s.boolean(),
fresh: s.boolean(),
}),
s
.object({
config: s.boolean(),
secrets: s.boolean(),
fresh: s.boolean(),
})
.partial(),
),
async (c) => {
const module = c.req.param("module") as ModuleKey | undefined;