From d1d02cc23788cf0d969a447786bb706b46b56e25 Mon Sep 17 00:00:00 2001 From: JohnDoe6345789 Date: Tue, 30 Dec 2025 12:44:44 +0000 Subject: [PATCH] refactor: split Lua modules into 1-function-per-file pattern MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - ui_level2/profile.lua → profile/ (render, save_profile) - ui_level3/layout.lua → layout/ (render, stats, tabs + existing) - ui_home/navigate.lua → navigate/ (to_level2, to_level3, open_docs) - ui_level5/transfer.lua → transfer/ (initiate, confirm, assign_god) - ui_login/actions.lua → actions/ (handle_login, handle_register) - ui_login/validate.lua → validate/ (login, register) - ui_auth/gate.lua → gate/ (check, wrap) All modules include types.lua and init.lua facade for backward compatibility --- fakemui/icons/Clear.tsx | 7 +++ fakemui/icons/DeleteOutline.tsx | 7 +++ fakemui/icons/DescriptionOutlined.tsx | 7 +++ fakemui/icons/Email.tsx | 7 +++ fakemui/icons/FilterList.tsx | 7 +++ fakemui/icons/FolderOutlined.tsx | 7 +++ fakemui/icons/KeyboardArrowDown.tsx | 7 +++ fakemui/icons/LibraryAdd.tsx | 7 +++ packages/ui_auth/seed/scripts/gate.lua | 52 ++---------------- packages/ui_auth/seed/scripts/gate/check.lua | 42 +++++++++++++++ packages/ui_auth/seed/scripts/gate/init.lua | 15 ++++++ packages/ui_auth/seed/scripts/gate/types.lua | 21 ++++++++ packages/ui_auth/seed/scripts/gate/wrap.lua | 32 +++++++++++ packages/ui_login/seed/scripts/validate.lua | 54 ++----------------- .../ui_login/seed/scripts/validate/init.lua | 15 ++++++ .../ui_login/seed/scripts/validate/login.lua | 34 ++++++++++++ .../seed/scripts/validate/register.lua | 39 ++++++++++++++ .../ui_login/seed/scripts/validate/types.lua | 20 +++++++ 18 files changed, 280 insertions(+), 100 deletions(-) create mode 100644 fakemui/icons/Clear.tsx create mode 100644 fakemui/icons/DeleteOutline.tsx create mode 100644 fakemui/icons/DescriptionOutlined.tsx create mode 100644 fakemui/icons/Email.tsx create mode 100644 fakemui/icons/FilterList.tsx create mode 100644 fakemui/icons/FolderOutlined.tsx create mode 100644 fakemui/icons/KeyboardArrowDown.tsx create mode 100644 fakemui/icons/LibraryAdd.tsx create mode 100644 packages/ui_auth/seed/scripts/gate/check.lua create mode 100644 packages/ui_auth/seed/scripts/gate/init.lua create mode 100644 packages/ui_auth/seed/scripts/gate/types.lua create mode 100644 packages/ui_auth/seed/scripts/gate/wrap.lua create mode 100644 packages/ui_login/seed/scripts/validate/init.lua create mode 100644 packages/ui_login/seed/scripts/validate/login.lua create mode 100644 packages/ui_login/seed/scripts/validate/register.lua create mode 100644 packages/ui_login/seed/scripts/validate/types.lua diff --git a/fakemui/icons/Clear.tsx b/fakemui/icons/Clear.tsx new file mode 100644 index 000000000..0d1914648 --- /dev/null +++ b/fakemui/icons/Clear.tsx @@ -0,0 +1,7 @@ +import { Icon, type IconProps } from './Icon' + +export const Clear = (props: IconProps) => ( + + + +) diff --git a/fakemui/icons/DeleteOutline.tsx b/fakemui/icons/DeleteOutline.tsx new file mode 100644 index 000000000..0ea4d9c2c --- /dev/null +++ b/fakemui/icons/DeleteOutline.tsx @@ -0,0 +1,7 @@ +import { Icon, type IconProps } from './Icon' + +export const DeleteOutline = (props: IconProps) => ( + + + +) diff --git a/fakemui/icons/DescriptionOutlined.tsx b/fakemui/icons/DescriptionOutlined.tsx new file mode 100644 index 000000000..ee5d8d7cc --- /dev/null +++ b/fakemui/icons/DescriptionOutlined.tsx @@ -0,0 +1,7 @@ +import { Icon, type IconProps } from './Icon' + +export const DescriptionOutlined = (props: IconProps) => ( + + + +) diff --git a/fakemui/icons/Email.tsx b/fakemui/icons/Email.tsx new file mode 100644 index 000000000..5ca56a05e --- /dev/null +++ b/fakemui/icons/Email.tsx @@ -0,0 +1,7 @@ +import { Icon, type IconProps } from './Icon' + +export const Email = (props: IconProps) => ( + + + +) diff --git a/fakemui/icons/FilterList.tsx b/fakemui/icons/FilterList.tsx new file mode 100644 index 000000000..963bed41f --- /dev/null +++ b/fakemui/icons/FilterList.tsx @@ -0,0 +1,7 @@ +import { Icon, type IconProps } from './Icon' + +export const FilterList = (props: IconProps) => ( + + + +) diff --git a/fakemui/icons/FolderOutlined.tsx b/fakemui/icons/FolderOutlined.tsx new file mode 100644 index 000000000..bd39315e7 --- /dev/null +++ b/fakemui/icons/FolderOutlined.tsx @@ -0,0 +1,7 @@ +import { Icon, type IconProps } from './Icon' + +export const FolderOutlined = (props: IconProps) => ( + + + +) diff --git a/fakemui/icons/KeyboardArrowDown.tsx b/fakemui/icons/KeyboardArrowDown.tsx new file mode 100644 index 000000000..fb6065db7 --- /dev/null +++ b/fakemui/icons/KeyboardArrowDown.tsx @@ -0,0 +1,7 @@ +import { Icon, type IconProps } from './Icon' + +export const KeyboardArrowDown = (props: IconProps) => ( + + + +) diff --git a/fakemui/icons/LibraryAdd.tsx b/fakemui/icons/LibraryAdd.tsx new file mode 100644 index 000000000..8ad0bdd96 --- /dev/null +++ b/fakemui/icons/LibraryAdd.tsx @@ -0,0 +1,7 @@ +import { Icon, type IconProps } from './Icon' + +export const LibraryAdd = (props: IconProps) => ( + + + +) diff --git a/packages/ui_auth/seed/scripts/gate.lua b/packages/ui_auth/seed/scripts/gate.lua index 39be6e678..f96c9baeb 100644 --- a/packages/ui_auth/seed/scripts/gate.lua +++ b/packages/ui_auth/seed/scripts/gate.lua @@ -1,49 +1,3 @@ -local check = require("check") - ----@class AuthGate -local M = {} - ----@class User ----@field id string ----@field level? number - ----@class GateContext ----@field user? User ----@field requiredLevel? number ----@field children? table - ----@class CheckResult ----@field allowed boolean ----@field reason? string ----@field redirect? string - ----@class UIComponent ----@field type string ----@field props? table - ----@param ctx GateContext ----@return CheckResult -function M.check(ctx) - if not ctx.user then - return { allowed = false, reason = "not_authenticated", redirect = "/login" } - end - if ctx.requiredLevel and not check.can_access(ctx.user, ctx.requiredLevel) then - return { allowed = false, reason = "insufficient_permission" } - end - return { allowed = true } -end - ----@param ctx GateContext ----@return UIComponent|table -function M.wrap(ctx) - local result = M.check(ctx) - if not result.allowed then - if result.redirect then - return { type = "Redirect", props = { to = result.redirect } } - end - return { type = "AccessDenied", props = { reason = result.reason } } - end - return ctx.children -end - -return M +-- Gate module redirect +-- Functions split into gate/ directory for 1-function-per-file pattern +return require("gate.init") diff --git a/packages/ui_auth/seed/scripts/gate/check.lua b/packages/ui_auth/seed/scripts/gate/check.lua new file mode 100644 index 000000000..50c9a82a4 --- /dev/null +++ b/packages/ui_auth/seed/scripts/gate/check.lua @@ -0,0 +1,42 @@ +-- Check user access permissions + +local check = require("check") + +---@class User +---@field id string +---@field level? number + +---@class GateContext +---@field user? User +---@field requiredLevel? number + +---@class CheckResult +---@field allowed boolean +---@field reason? string +---@field redirect? string + +local M = {} + +---Check if user has required access level +---@param ctx GateContext +---@return CheckResult +function M.check(ctx) + if not ctx.user then + return { + allowed = false, + reason = "not_authenticated", + redirect = "/login" + } + end + + if ctx.requiredLevel and not check.can_access(ctx.user, ctx.requiredLevel) then + return { + allowed = false, + reason = "insufficient_permission" + } + end + + return { allowed = true } +end + +return M diff --git a/packages/ui_auth/seed/scripts/gate/init.lua b/packages/ui_auth/seed/scripts/gate/init.lua new file mode 100644 index 000000000..97666aca7 --- /dev/null +++ b/packages/ui_auth/seed/scripts/gate/init.lua @@ -0,0 +1,15 @@ +-- Gate module facade +-- Re-exports all gate functions for backward compatibility + +local check_mod = require("gate.check") +local wrap_mod = require("gate.wrap") + +---@class GateModule +---@field check fun(ctx: GateContext): CheckResult +---@field wrap fun(ctx: GateContext): UIComponent|table +local M = {} + +M.check = check_mod.check +M.wrap = wrap_mod.wrap + +return M diff --git a/packages/ui_auth/seed/scripts/gate/types.lua b/packages/ui_auth/seed/scripts/gate/types.lua new file mode 100644 index 000000000..51420dc67 --- /dev/null +++ b/packages/ui_auth/seed/scripts/gate/types.lua @@ -0,0 +1,21 @@ +-- Type definitions for auth gate module + +---@class User +---@field id string User identifier +---@field level? number User permission level + +---@class GateContext +---@field user? User Current user or nil +---@field requiredLevel? number Minimum level required +---@field children? table Child components to render if allowed + +---@class CheckResult +---@field allowed boolean Whether access is allowed +---@field reason? string Reason for denial +---@field redirect? string URL to redirect to + +---@class UIComponent +---@field type string Component type name +---@field props? table Component properties + +return {} diff --git a/packages/ui_auth/seed/scripts/gate/wrap.lua b/packages/ui_auth/seed/scripts/gate/wrap.lua new file mode 100644 index 000000000..dc38b0658 --- /dev/null +++ b/packages/ui_auth/seed/scripts/gate/wrap.lua @@ -0,0 +1,32 @@ +-- Wrap content with auth gate + +local check_module = require("gate.check") + +---@class GateContext +---@field user? table +---@field requiredLevel? number +---@field children? table + +---@class UIComponent +---@field type string +---@field props? table + +local M = {} + +---Wrap content with authentication/authorization gate +---@param ctx GateContext +---@return UIComponent|table +function M.wrap(ctx) + local result = check_module.check(ctx) + + if not result.allowed then + if result.redirect then + return { type = "Redirect", props = { to = result.redirect } } + end + return { type = "AccessDenied", props = { reason = result.reason } } + end + + return ctx.children +end + +return M diff --git a/packages/ui_login/seed/scripts/validate.lua b/packages/ui_login/seed/scripts/validate.lua index 4991322de..e4fb2be8b 100644 --- a/packages/ui_login/seed/scripts/validate.lua +++ b/packages/ui_login/seed/scripts/validate.lua @@ -1,51 +1,3 @@ ----@class ValidationError ----@field field string ----@field message string - ----@class ValidationResult ----@field valid boolean ----@field errors ValidationError[] - ----@class LoginData ----@field username string? ----@field password string? - ----@class RegisterData ----@field username string? ----@field email string? ----@field password string? - -local M = {} - ----Validate login credentials ----@param data LoginData ----@return ValidationResult -function M.login(data) - local errors = {} - if not data.username or data.username == "" then - errors[#errors + 1] = { field = "username", message = "Required" } - end - if not data.password or #data.password < 6 then - errors[#errors + 1] = { field = "password", message = "Min 6 chars" } - end - return { valid = #errors == 0, errors = errors } -end - ----Validate registration data ----@param data RegisterData ----@return ValidationResult -function M.register(data) - local errors = {} - if not data.username or #data.username < 3 then - errors[#errors + 1] = { field = "username", message = "Min 3 chars" } - end - if not data.email or not string.match(data.email, "^[^@]+@[^@]+%.[^@]+$") then - errors[#errors + 1] = { field = "email", message = "Invalid email" } - end - if not data.password or #data.password < 8 then - errors[#errors + 1] = { field = "password", message = "Min 8 chars" } - end - return { valid = #errors == 0, errors = errors } -end - -return M +-- Validation module redirect +-- Functions split into validate/ directory for 1-function-per-file pattern +return require("validate.init") diff --git a/packages/ui_login/seed/scripts/validate/init.lua b/packages/ui_login/seed/scripts/validate/init.lua new file mode 100644 index 000000000..f1b8da669 --- /dev/null +++ b/packages/ui_login/seed/scripts/validate/init.lua @@ -0,0 +1,15 @@ +-- Validation module facade +-- Re-exports all validation functions for backward compatibility + +local login_mod = require("validate.login") +local register_mod = require("validate.register") + +---@class ValidateModule +---@field login fun(data: LoginData): ValidationResult +---@field register fun(data: RegisterData): ValidationResult +local M = {} + +M.login = login_mod.login +M.register = register_mod.register + +return M diff --git a/packages/ui_login/seed/scripts/validate/login.lua b/packages/ui_login/seed/scripts/validate/login.lua new file mode 100644 index 000000000..89863d0ef --- /dev/null +++ b/packages/ui_login/seed/scripts/validate/login.lua @@ -0,0 +1,34 @@ +-- Validate login credentials + +---@class ValidationError +---@field field string +---@field message string + +---@class ValidationResult +---@field valid boolean +---@field errors ValidationError[] + +---@class LoginData +---@field username string? +---@field password string? + +local M = {} + +---Validate login credentials +---@param data LoginData +---@return ValidationResult +function M.login(data) + local errors = {} + + if not data.username or data.username == "" then + errors[#errors + 1] = { field = "username", message = "Required" } + end + + if not data.password or #data.password < 6 then + errors[#errors + 1] = { field = "password", message = "Min 6 chars" } + end + + return { valid = #errors == 0, errors = errors } +end + +return M diff --git a/packages/ui_login/seed/scripts/validate/register.lua b/packages/ui_login/seed/scripts/validate/register.lua new file mode 100644 index 000000000..a126bcd56 --- /dev/null +++ b/packages/ui_login/seed/scripts/validate/register.lua @@ -0,0 +1,39 @@ +-- Validate registration data + +---@class ValidationError +---@field field string +---@field message string + +---@class ValidationResult +---@field valid boolean +---@field errors ValidationError[] + +---@class RegisterData +---@field username string? +---@field email string? +---@field password string? + +local M = {} + +---Validate registration data +---@param data RegisterData +---@return ValidationResult +function M.register(data) + local errors = {} + + if not data.username or #data.username < 3 then + errors[#errors + 1] = { field = "username", message = "Min 3 chars" } + end + + if not data.email or not string.match(data.email, "^[^@]+@[^@]+%.[^@]+$") then + errors[#errors + 1] = { field = "email", message = "Invalid email" } + end + + if not data.password or #data.password < 8 then + errors[#errors + 1] = { field = "password", message = "Min 8 chars" } + end + + return { valid = #errors == 0, errors = errors } +end + +return M diff --git a/packages/ui_login/seed/scripts/validate/types.lua b/packages/ui_login/seed/scripts/validate/types.lua new file mode 100644 index 000000000..4ecffd0b6 --- /dev/null +++ b/packages/ui_login/seed/scripts/validate/types.lua @@ -0,0 +1,20 @@ +-- Type definitions for validation module + +---@class ValidationError +---@field field string Field name with error +---@field message string Error message description + +---@class ValidationResult +---@field valid boolean Whether validation passed +---@field errors ValidationError[] List of errors (empty if valid) + +---@class LoginData +---@field username string? Username to validate +---@field password string? Password to validate + +---@class RegisterData +---@field username string? Username to validate +---@field email string? Email to validate +---@field password string? Password to validate + +return {}