Add extraction registry tracking and improve logging with detailed function analysis

Co-authored-by: johndoe6345789 <224850594+johndoe6345789@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot]
2025-12-29 18:56:18 +00:00
parent 4427f63c17
commit 2489c2133e
16 changed files with 491 additions and 531 deletions

View File

@@ -1,21 +1,21 @@
{
"timestamp": "2025-12-29T18:39:04.533Z",
"duration": "4.22s",
"timestamp": "2025-12-29T18:54:34.117Z",
"duration": "7.75s",
"options": {
"dryRun": true,
"priority": "all",
"limit": 100,
"dryRun": false,
"priority": "high",
"limit": 5,
"batchSize": 5,
"skipLint": false,
"skipTest": false,
"autoConfirm": false,
"verbose": false
"autoConfirm": true,
"verbose": true
},
"summary": {
"total": 52,
"completed": 52,
"total": 5,
"completed": 1,
"failed": 0,
"skipped": 0
"skipped": 4
},
"files": [
{
@@ -23,364 +23,50 @@
"lines": 278,
"priority": "high",
"category": "library",
"status": "completed"
"status": "skipped",
"error": "No functions found in file"
},
{
"path": "frontends/nextjs/src/lib/nerd-mode-ide/templates/configs/base.ts",
"lines": 267,
"priority": "high",
"category": "library",
"status": "completed"
"status": "skipped",
"error": "No functions found in file"
},
{
"path": "frontends/nextjs/src/lib/schema/default/forms.ts",
"lines": 244,
"priority": "high",
"category": "library",
"status": "completed"
"status": "skipped",
"error": "No functions found in file"
},
{
"path": "frontends/nextjs/src/lib/db/core/operations.ts",
"lines": 190,
"priority": "high",
"category": "library",
"status": "completed"
"status": "skipped",
"error": "No functions found in file"
},
{
"path": "frontends/nextjs/src/lib/rendering/page/page-renderer.ts",
"lines": 178,
"priority": "high",
"category": "library",
"status": "completed"
},
{
"path": "frontends/nextjs/src/lib/github/workflows/analysis/runs/stats.ts",
"lines": 153,
"priority": "high",
"category": "library",
"status": "completed"
},
{
"path": "tools/refactoring/orchestrate-refactor.ts",
"lines": 249,
"priority": "high",
"category": "tool",
"status": "completed"
},
{
"path": "tools/refactoring/bulk-lambda-refactor.ts",
"lines": 249,
"priority": "high",
"category": "tool",
"status": "completed"
},
{
"path": "tools/refactoring/languages/typescript-refactor.ts",
"lines": 219,
"priority": "high",
"category": "tool",
"status": "completed"
},
{
"path": "tools/refactoring/cli/orchestrate-refactor.ts",
"lines": 213,
"priority": "high",
"category": "tool",
"status": "completed"
},
{
"path": "tools/refactoring/languages/cpp-refactor.ts",
"lines": 209,
"priority": "high",
"category": "tool",
"status": "completed"
},
{
"path": "tools/refactoring/ast-lambda-refactor.ts",
"lines": 192,
"priority": "high",
"category": "tool",
"status": "completed"
},
{
"path": "tools/refactoring/error-as-todo-refactor/index.ts",
"lines": 163,
"priority": "high",
"category": "tool",
"status": "completed"
},
{
"path": "dbal/shared/tools/cpp-build-assistant/workflow.ts",
"lines": 153,
"priority": "high",
"category": "tool",
"status": "completed"
},
{
"path": "tools/refactoring/auto-code-extractor-3000.ts",
"lines": 508,
"priority": "medium",
"category": "tool",
"status": "completed"
},
{
"path": "frontends/nextjs/src/lib/dbal/core/client/dbal-integration.ts",
"lines": 313,
"priority": "medium",
"category": "dbal",
"status": "completed"
},
{
"path": "frontends/nextjs/src/components/misc/data/QuickGuide.tsx",
"lines": 297,
"priority": "medium",
"category": "component",
"status": "completed"
},
{
"path": "frontends/nextjs/src/components/misc/data/GenericPage.tsx",
"lines": 274,
"priority": "medium",
"category": "component",
"status": "completed"
},
{
"path": "frontends/nextjs/src/components/molecules/overlay/DropdownMenu.tsx",
"lines": 268,
"priority": "medium",
"category": "component",
"status": "completed"
},
{
"path": "frontends/nextjs/src/components/managers/database/DatabaseManager.tsx",
"lines": 261,
"priority": "medium",
"category": "component",
"status": "completed"
},
{
"path": "frontends/nextjs/src/components/examples/ContactForm.example.tsx",
"lines": 258,
"priority": "medium",
"category": "component",
"status": "completed"
},
{
"path": "frontends/nextjs/src/components/managers/component/ComponentHierarchyEditor.tsx",
"lines": 242,
"priority": "medium",
"category": "component",
"status": "completed"
},
{
"path": "frontends/nextjs/src/components/managers/component/ComponentConfigDialog/Fields.tsx",
"lines": 238,
"priority": "medium",
"category": "component",
"status": "completed"
},
{
"path": "frontends/nextjs/src/components/editors/lua/blocks/BlockItem.tsx",
"lines": 218,
"priority": "medium",
"category": "component",
"status": "completed"
},
{
"path": "frontends/nextjs/src/components/rendering/FieldRenderer.tsx",
"lines": 210,
"priority": "medium",
"category": "component",
"status": "completed"
},
{
"path": "frontends/nextjs/src/components/ui/organisms/data/Form.tsx",
"lines": 210,
"priority": "medium",
"category": "component",
"status": "completed"
},
{
"path": "frontends/nextjs/src/components/level5/tabs/PowerTransferTab.tsx",
"lines": 207,
"priority": "medium",
"category": "component",
"status": "completed"
},
{
"path": "frontends/nextjs/src/components/misc/auth/UnifiedLogin.tsx",
"lines": 207,
"priority": "medium",
"category": "component",
"status": "completed"
},
{
"path": "frontends/nextjs/src/components/ui/molecules/overlay/DropdownMenu.tsx",
"lines": 207,
"priority": "medium",
"category": "component",
"status": "completed"
},
{
"path": "frontends/nextjs/src/components/ui/organisms/navigation/NavigationMenuItems.tsx",
"lines": 203,
"priority": "medium",
"category": "component",
"status": "completed"
},
{
"path": "frontends/nextjs/src/components/editors/lua/LuaBlocksEditor.tsx",
"lines": 193,
"priority": "medium",
"category": "component",
"status": "completed"
},
{
"path": "frontends/nextjs/src/components/molecules/overlay/Dialog.tsx",
"lines": 191,
"priority": "medium",
"category": "component",
"status": "completed"
},
{
"path": "frontends/nextjs/src/components/editors/JsonEditor.tsx",
"lines": 191,
"priority": "medium",
"category": "component",
"status": "completed"
},
{
"path": "frontends/nextjs/src/components/misc/demos/IRCWebchatDeclarative.tsx",
"lines": 190,
"priority": "medium",
"category": "component",
"status": "completed"
},
{
"path": "frontends/nextjs/src/components/rendering/components/RenderNode.tsx",
"lines": 188,
"priority": "medium",
"category": "component",
"status": "completed"
},
{
"path": "frontends/nextjs/src/components/misc/viewers/AuditLogViewer.tsx",
"lines": 188,
"priority": "medium",
"category": "component",
"status": "completed"
},
{
"path": "frontends/nextjs/src/components/misc/viewers/audit-log/Filters.tsx",
"lines": 188,
"priority": "medium",
"category": "component",
"status": "completed"
},
{
"path": "frontends/nextjs/src/components/schema/level4/Tabs.tsx",
"lines": 186,
"priority": "medium",
"category": "component",
"status": "completed"
},
{
"path": "frontends/nextjs/src/components/managers/package/PackageDetailsDialog.tsx",
"lines": 185,
"priority": "medium",
"category": "component",
"status": "completed"
},
{
"path": "frontends/nextjs/src/components/misc/data/SMTPConfigEditor.tsx",
"lines": 184,
"priority": "medium",
"category": "component",
"status": "completed"
},
{
"path": "frontends/nextjs/src/components/managers/dropdown/DropdownConfigForm.tsx",
"lines": 182,
"priority": "medium",
"category": "component",
"status": "completed"
},
{
"path": "frontends/nextjs/src/components/ui/organisms/data/Table.tsx",
"lines": 174,
"priority": "medium",
"category": "component",
"status": "completed"
},
{
"path": "frontends/nextjs/src/components/misc/github/views/run-list/RunListAlerts.tsx",
"lines": 171,
"priority": "medium",
"category": "component",
"status": "completed"
},
{
"path": "frontends/nextjs/src/components/organisms/security/SecurityMessage.tsx",
"lines": 171,
"priority": "medium",
"category": "component",
"status": "completed"
},
{
"path": "frontends/nextjs/src/components/rendering/Builder.tsx",
"lines": 163,
"priority": "medium",
"category": "component",
"status": "completed"
},
{
"path": "frontends/nextjs/src/components/level4/tabs/TabContent.tsx",
"lines": 153,
"priority": "medium",
"category": "component",
"status": "completed"
},
{
"path": "frontends/nextjs/src/components/misc/demos/IRCWebchat.tsx",
"lines": 153,
"priority": "medium",
"category": "component",
"status": "completed"
},
{
"path": "frontends/nextjs/src/components/managers/UserManagement.tsx",
"lines": 334,
"priority": "medium",
"category": "component",
"status": "completed"
},
{
"path": "frontends/nextjs/src/components/managers/css/CssClassManager.tsx",
"lines": 327,
"priority": "medium",
"category": "component",
"status": "completed"
},
{
"path": "frontends/nextjs/src/components/misc/viewers/ModelListView.tsx",
"lines": 318,
"priority": "medium",
"category": "component",
"status": "completed"
},
{
"path": "frontends/nextjs/src/components/nerd-mode-ide/core/NerdModeIDE/useNerdIdeState.ts",
"lines": 274,
"priority": "low",
"category": "other",
"status": "completed"
},
{
"path": "frontends/nextjs/src/components/editors/lua/hooks/useLuaBlocksState/actions.ts",
"lines": 208,
"priority": "low",
"category": "other",
"status": "completed"
"status": "completed",
"extractedFunctions": [
"registerPage",
"loadPages",
"getPage",
"getPagesByLevel",
"executeLuaScript",
"checkPermissions",
"onPageLoad",
"onPageUnload",
"getPageRenderer"
]
}
]
}

View File

@@ -0,0 +1,60 @@
{
"version": "1.0.0",
"lastUpdated": "2025-12-29T18:54:30.245Z",
"functions": [
{
"functionName": "registerPage",
"originalFile": "frontends/nextjs/src/lib/rendering/page/page-renderer.ts",
"extractedPath": "frontends/nextjs/src/lib/rendering/page/page-renderer/functions/register-page.ts",
"timestamp": "2025-12-29T18:54:30.244Z"
},
{
"functionName": "loadPages",
"originalFile": "frontends/nextjs/src/lib/rendering/page/page-renderer.ts",
"extractedPath": "frontends/nextjs/src/lib/rendering/page/page-renderer/functions/load-pages.ts",
"timestamp": "2025-12-29T18:54:30.244Z"
},
{
"functionName": "getPage",
"originalFile": "frontends/nextjs/src/lib/rendering/page/page-renderer.ts",
"extractedPath": "frontends/nextjs/src/lib/rendering/page/page-renderer/functions/get-page.ts",
"timestamp": "2025-12-29T18:54:30.244Z"
},
{
"functionName": "getPagesByLevel",
"originalFile": "frontends/nextjs/src/lib/rendering/page/page-renderer.ts",
"extractedPath": "frontends/nextjs/src/lib/rendering/page/page-renderer/functions/get-pages-by-level.ts",
"timestamp": "2025-12-29T18:54:30.244Z"
},
{
"functionName": "executeLuaScript",
"originalFile": "frontends/nextjs/src/lib/rendering/page/page-renderer.ts",
"extractedPath": "frontends/nextjs/src/lib/rendering/page/page-renderer/functions/execute-lua-script.ts",
"timestamp": "2025-12-29T18:54:30.244Z"
},
{
"functionName": "checkPermissions",
"originalFile": "frontends/nextjs/src/lib/rendering/page/page-renderer.ts",
"extractedPath": "frontends/nextjs/src/lib/rendering/page/page-renderer/functions/check-permissions.ts",
"timestamp": "2025-12-29T18:54:30.244Z"
},
{
"functionName": "onPageLoad",
"originalFile": "frontends/nextjs/src/lib/rendering/page/page-renderer.ts",
"extractedPath": "frontends/nextjs/src/lib/rendering/page/page-renderer/functions/on-page-load.ts",
"timestamp": "2025-12-29T18:54:30.244Z"
},
{
"functionName": "onPageUnload",
"originalFile": "frontends/nextjs/src/lib/rendering/page/page-renderer.ts",
"extractedPath": "frontends/nextjs/src/lib/rendering/page/page-renderer/functions/on-page-unload.ts",
"timestamp": "2025-12-29T18:54:30.244Z"
},
{
"functionName": "getPageRenderer",
"originalFile": "frontends/nextjs/src/lib/rendering/page/page-renderer.ts",
"extractedPath": "frontends/nextjs/src/lib/rendering/page/page-renderer/functions/get-page-renderer.ts",
"timestamp": "2025-12-29T18:54:30.244Z"
}
]
}

View File

@@ -1,11 +1,11 @@
# Lambda-per-File Refactoring Progress
**Generated:** 2025-12-29T18:28:41.724Z
**Generated:** 2025-12-29T18:54:34.116Z
## Summary
- **Total files > 150 lines:** 62
- **Pending:** 52
- **Total files > 150 lines:** 61
- **Pending:** 51
- **In Progress:** 0
- **Completed:** 0
- **Skipped:** 10
@@ -15,7 +15,7 @@
- **component:** 34
- **test:** 10
- **tool:** 9
- **library:** 6
- **library:** 5
- **other:** 2
- **dbal:** 1
@@ -23,7 +23,7 @@
Files are prioritized by ease of refactoring and impact.
### High Priority (15 files)
### High Priority (13 files)
Library and tool files - easiest to refactor
@@ -31,7 +31,6 @@ Library and tool files - easiest to refactor
- [ ] `frontends/nextjs/src/lib/nerd-mode-ide/templates/configs/base.ts` (267 lines)
- [ ] `frontends/nextjs/src/lib/schema/default/forms.ts` (244 lines)
- [ ] `frontends/nextjs/src/lib/db/core/operations.ts` (190 lines)
- [ ] `frontends/nextjs/src/lib/rendering/page/page-renderer.ts` (178 lines)
- [ ] `frontends/nextjs/src/lib/github/workflows/analysis/runs/stats.ts` (153 lines)
- [ ] `tools/refactoring/orchestrate-refactor.ts` (249 lines)
- [ ] `tools/refactoring/bulk-lambda-refactor.ts` (249 lines)
@@ -41,12 +40,12 @@ Library and tool files - easiest to refactor
- [ ] `tools/refactoring/ast-lambda-refactor.ts` (192 lines)
- [ ] `tools/refactoring/error-as-todo-refactor/index.ts` (163 lines)
- [ ] `dbal/shared/tools/cpp-build-assistant/workflow.ts` (153 lines)
- [ ] `tools/refactoring/auto-code-extractor-3000.ts` (487 lines)
### Medium Priority (35 files)
### Medium Priority (36 files)
DBAL and component files - moderate complexity
- [ ] `tools/refactoring/auto-code-extractor-3000.ts` (655 lines)
- [ ] `frontends/nextjs/src/lib/dbal/core/client/dbal-integration.ts` (313 lines)
- [ ] `frontends/nextjs/src/components/misc/data/QuickGuide.tsx` (297 lines)
- [ ] `frontends/nextjs/src/components/misc/data/GenericPage.tsx` (274 lines)
@@ -66,8 +65,7 @@ DBAL and component files - moderate complexity
- [ ] `frontends/nextjs/src/components/molecules/overlay/Dialog.tsx` (191 lines)
- [ ] `frontends/nextjs/src/components/editors/JsonEditor.tsx` (191 lines)
- [ ] `frontends/nextjs/src/components/misc/demos/IRCWebchatDeclarative.tsx` (190 lines)
- [ ] `frontends/nextjs/src/components/rendering/components/RenderNode.tsx` (188 lines)
- ... and 15 more
- ... and 16 more
### Low Priority (2 files)

View File

@@ -1,178 +1,13 @@
import { Database } from '@/lib/database'
import type { LuaEngine } from '@/lib/lua-engine'
import { executeLuaScriptWithProfile } from '@/lib/lua/execute-lua-script-with-profile'
import type { ComponentInstance } from '@/lib/types/builder-types'
import type { User } from '@/lib/types/level-types'
/**
* This file has been refactored into modular lambda-per-file structure.
*
* Import individual functions or use the class wrapper:
* @example
* import { registerPage } from './page-renderer'
*
* @example
* import { PageRendererUtils } from './page-renderer'
* PageRendererUtils.registerPage(...)
*/
export interface PageDefinition {
id: string
level: 1 | 2 | 3 | 4 | 5 | 6
title: string
description?: string
layout: 'default' | 'sidebar' | 'dashboard' | 'blank'
components: ComponentInstance[]
luaScripts?: {
onLoad?: string
onUnload?: string
handlers?: Record<string, string>
}
permissions?: {
requiresAuth: boolean
requiredRole?: string
customCheck?: string
}
metadata?: {
showHeader?: boolean
showFooter?: boolean
headerTitle?: string
headerActions?: ComponentInstance[]
sidebarItems?: Array<{
id: string
label: string
icon: string
action: 'navigate' | 'lua' | 'external'
target: string
}>
}
}
export interface PageContext {
user: User | null
level: number
isPreviewMode: boolean
navigationHandlers: {
onNavigate: (level: number) => void
onLogout: () => void
}
luaEngine: LuaEngine
}
export class PageRenderer {
private pages: Map<string, PageDefinition> = new Map()
async registerPage(page: PageDefinition): Promise<void> {
this.pages.set(page.id, page)
const pageConfig = {
id: page.id,
path: `/_page_${page.id}`,
title: page.title,
level: page.level,
componentTree: page.components,
requiresAuth: page.permissions?.requiresAuth || false,
requiredRole: page.permissions?.requiredRole as any
}
await Database.addPage(pageConfig)
}
async loadPages(): Promise<void> {
const savedPages = await Database.getPages()
savedPages.forEach(page => {
const pageDef: PageDefinition = {
id: page.id,
level: page.level as 1 | 2 | 3 | 4 | 5 | 6,
title: page.title,
layout: 'default',
components: page.componentTree,
permissions: {
requiresAuth: page.requiresAuth,
requiredRole: page.requiredRole
}
}
this.pages.set(page.id, pageDef)
})
}
getPage(id: string): PageDefinition | undefined {
return this.pages.get(id)
}
getPagesByLevel(level: number): PageDefinition[] {
return Array.from(this.pages.values()).filter(p => p.level === level)
}
async executeLuaScript(scriptId: string, context: any): Promise<any> {
const scripts = await Database.getLuaScripts()
const script = scripts.find(s => s.id === scriptId)
if (!script) {
throw new Error(`Lua script not found: ${scriptId}`)
}
const result = await executeLuaScriptWithProfile(script.code, context, script)
if (!result.success) {
throw new Error(result.error || 'Lua execution failed')
}
return result.result
}
async checkPermissions(
page: PageDefinition,
user: User | null
): Promise<{ allowed: boolean; reason?: string }> {
if (!page.permissions) {
return { allowed: true }
}
if (page.permissions.requiresAuth && !user) {
return { allowed: false, reason: 'Authentication required' }
}
if (page.permissions.requiredRole) {
const roleHierarchy = ['public', 'user', 'moderator', 'admin', 'god', 'supergod']
const userRole = user?.role ?? 'public'
const userRoleIndex = roleHierarchy.indexOf(userRole)
const requiredRoleIndex = roleHierarchy.indexOf(page.permissions.requiredRole)
if (requiredRoleIndex >= 0 && userRoleIndex >= 0 && userRoleIndex < requiredRoleIndex) {
return { allowed: false, reason: 'Insufficient permissions' }
}
}
if (page.permissions.customCheck) {
try {
const result = await this.executeLuaScript(page.permissions.customCheck, {
data: { user }
})
if (!result) {
return { allowed: false, reason: 'Custom permission check failed' }
}
} catch (error) {
return { allowed: false, reason: 'Permission check error' }
}
}
return { allowed: true }
}
async onPageLoad(page: PageDefinition, context: PageContext): Promise<void> {
if (page.luaScripts?.onLoad) {
await this.executeLuaScript(page.luaScripts.onLoad, {
data: {
user: context.user,
level: context.level,
isPreviewMode: context.isPreviewMode
}
})
}
}
async onPageUnload(page: PageDefinition, context: PageContext): Promise<void> {
if (page.luaScripts?.onUnload) {
await this.executeLuaScript(page.luaScripts.onUnload, {
data: {
user: context.user,
level: context.level
}
})
}
}
}
let pageRendererInstance: PageRenderer | null = null
export function getPageRenderer(): PageRenderer {
if (!pageRendererInstance) {
pageRendererInstance = new PageRenderer()
}
return pageRendererInstance
}
export * from './page-renderer'

View File

@@ -0,0 +1,54 @@
// Auto-generated class wrapper
import { registerPage } from './functions/register-page'
import { loadPages } from './functions/load-pages'
import { getPage } from './functions/get-page'
import { getPagesByLevel } from './functions/get-pages-by-level'
import { executeLuaScript } from './functions/execute-lua-script'
import { checkPermissions } from './functions/check-permissions'
import { onPageLoad } from './functions/on-page-load'
import { onPageUnload } from './functions/on-page-unload'
import { getPageRenderer } from './functions/get-page-renderer'
/**
* PageRendererUtils - Class wrapper for 9 functions
*
* This is a convenience wrapper. Prefer importing individual functions.
*/
export class PageRendererUtils {
static async registerPage(...args: any[]) {
return await registerPage(...args as any)
}
static async loadPages(...args: any[]) {
return await loadPages(...args as any)
}
static getPage(...args: any[]) {
return getPage(...args as any)
}
static getPagesByLevel(...args: any[]) {
return getPagesByLevel(...args as any)
}
static async executeLuaScript(...args: any[]) {
return await executeLuaScript(...args as any)
}
static async checkPermissions(...args: any[]) {
return await checkPermissions(...args as any)
}
static async onPageLoad(...args: any[]) {
return await onPageLoad(...args as any)
}
static async onPageUnload(...args: any[]) {
return await onPageUnload(...args as any)
}
static getPageRenderer(...args: any[]) {
return getPageRenderer(...args as any)
}
}

View File

@@ -0,0 +1,44 @@
import { Database } from '@/lib/database'
import type { LuaEngine } from '@/lib/lua-engine'
import { executeLuaScriptWithProfile } from '@/lib/lua/execute-lua-script-with-profile'
import type { ComponentInstance } from '@/lib/types/builder-types'
import type { User } from '@/lib/types/level-types'
export async function checkPermissions(
page: PageDefinition,
user: User | null
): Promise<{ allowed: boolean; reason?: string }> {
if (!page.permissions) {
return { allowed: true }
}
if (page.permissions.requiresAuth && !user) {
return { allowed: false, reason: 'Authentication required' }
}
if (page.permissions.requiredRole) {
const roleHierarchy = ['public', 'user', 'moderator', 'admin', 'god', 'supergod']
const userRole = user?.role ?? 'public'
const userRoleIndex = roleHierarchy.indexOf(userRole)
const requiredRoleIndex = roleHierarchy.indexOf(page.permissions.requiredRole)
if (requiredRoleIndex >= 0 && userRoleIndex >= 0 && userRoleIndex < requiredRoleIndex) {
return { allowed: false, reason: 'Insufficient permissions' }
}
}
if (page.permissions.customCheck) {
try {
const result = await this.executeLuaScript(page.permissions.customCheck, {
data: { user }
})
if (!result) {
return { allowed: false, reason: 'Custom permission check failed' }
}
} catch (error) {
return { allowed: false, reason: 'Permission check error' }
}
}
return { allowed: true }
}

View File

@@ -0,0 +1,20 @@
import { Database } from '@/lib/database'
import type { LuaEngine } from '@/lib/lua-engine'
import { executeLuaScriptWithProfile } from '@/lib/lua/execute-lua-script-with-profile'
import type { ComponentInstance } from '@/lib/types/builder-types'
import type { User } from '@/lib/types/level-types'
export async function executeLuaScript(scriptId: string, context: any): Promise<any> {
const scripts = await Database.getLuaScripts()
const script = scripts.find(s => s.id === scriptId)
if (!script) {
throw new Error(`Lua script not found: ${scriptId}`)
}
const result = await executeLuaScriptWithProfile(script.code, context, script)
if (!result.success) {
throw new Error(result.error || 'Lua execution failed')
}
return result.result
}

View File

@@ -0,0 +1,12 @@
import { Database } from '@/lib/database'
import type { LuaEngine } from '@/lib/lua-engine'
import { executeLuaScriptWithProfile } from '@/lib/lua/execute-lua-script-with-profile'
import type { ComponentInstance } from '@/lib/types/builder-types'
import type { User } from '@/lib/types/level-types'
export function getPageRenderer(): PageRenderer {
if (!pageRendererInstance) {
pageRendererInstance = new PageRenderer()
}
return pageRendererInstance
}

View File

@@ -0,0 +1,9 @@
import { Database } from '@/lib/database'
import type { LuaEngine } from '@/lib/lua-engine'
import { executeLuaScriptWithProfile } from '@/lib/lua/execute-lua-script-with-profile'
import type { ComponentInstance } from '@/lib/types/builder-types'
import type { User } from '@/lib/types/level-types'
export function getPage(id: string): PageDefinition | undefined {
return this.pages.get(id)
}

View File

@@ -0,0 +1,9 @@
import { Database } from '@/lib/database'
import type { LuaEngine } from '@/lib/lua-engine'
import { executeLuaScriptWithProfile } from '@/lib/lua/execute-lua-script-with-profile'
import type { ComponentInstance } from '@/lib/types/builder-types'
import type { User } from '@/lib/types/level-types'
export function getPagesByLevel(level: number): PageDefinition[] {
return Array.from(this.pages.values()).filter(p => p.level === level)
}

View File

@@ -0,0 +1,23 @@
import { Database } from '@/lib/database'
import type { LuaEngine } from '@/lib/lua-engine'
import { executeLuaScriptWithProfile } from '@/lib/lua/execute-lua-script-with-profile'
import type { ComponentInstance } from '@/lib/types/builder-types'
import type { User } from '@/lib/types/level-types'
export async function loadPages(): Promise<void> {
const savedPages = await Database.getPages()
savedPages.forEach(page => {
const pageDef: PageDefinition = {
id: page.id,
level: page.level as 1 | 2 | 3 | 4 | 5 | 6,
title: page.title,
layout: 'default',
components: page.componentTree,
permissions: {
requiresAuth: page.requiresAuth,
requiredRole: page.requiredRole
}
}
this.pages.set(page.id, pageDef)
})
}

View File

@@ -0,0 +1,17 @@
import { Database } from '@/lib/database'
import type { LuaEngine } from '@/lib/lua-engine'
import { executeLuaScriptWithProfile } from '@/lib/lua/execute-lua-script-with-profile'
import type { ComponentInstance } from '@/lib/types/builder-types'
import type { User } from '@/lib/types/level-types'
export async function onPageLoad(page: PageDefinition, context: PageContext): Promise<void> {
if (page.luaScripts?.onLoad) {
await this.executeLuaScript(page.luaScripts.onLoad, {
data: {
user: context.user,
level: context.level,
isPreviewMode: context.isPreviewMode
}
})
}
}

View File

@@ -0,0 +1,16 @@
import { Database } from '@/lib/database'
import type { LuaEngine } from '@/lib/lua-engine'
import { executeLuaScriptWithProfile } from '@/lib/lua/execute-lua-script-with-profile'
import type { ComponentInstance } from '@/lib/types/builder-types'
import type { User } from '@/lib/types/level-types'
export async function onPageUnload(page: PageDefinition, context: PageContext): Promise<void> {
if (page.luaScripts?.onUnload) {
await this.executeLuaScript(page.luaScripts.onUnload, {
data: {
user: context.user,
level: context.level
}
})
}
}

View File

@@ -0,0 +1,19 @@
import { Database } from '@/lib/database'
import type { LuaEngine } from '@/lib/lua-engine'
import { executeLuaScriptWithProfile } from '@/lib/lua/execute-lua-script-with-profile'
import type { ComponentInstance } from '@/lib/types/builder-types'
import type { User } from '@/lib/types/level-types'
export async function registerPage(page: PageDefinition): Promise<void> {
this.pages.set(page.id, page)
const pageConfig = {
id: page.id,
path: `/_page_${page.id}`,
title: page.title,
level: page.level,
componentTree: page.components,
requiresAuth: page.permissions?.requiresAuth || false,
requiredRole: page.permissions?.requiredRole as any
}
await Database.addPage(pageConfig)
}

View File

@@ -0,0 +1,11 @@
// Auto-generated re-exports for backward compatibility
export { registerPage } from './functions/register-page'
export { loadPages } from './functions/load-pages'
export { getPage } from './functions/get-page'
export { getPagesByLevel } from './functions/get-pages-by-level'
export { executeLuaScript } from './functions/execute-lua-script'
export { checkPermissions } from './functions/check-permissions'
export { onPageLoad } from './functions/on-page-load'
export { onPageUnload } from './functions/on-page-unload'
export { getPageRenderer } from './functions/get-page-renderer'

View File

@@ -61,12 +61,31 @@ interface FileToExtract {
category: string
status: 'pending' | 'completed' | 'failed' | 'skipped'
error?: string
extractedFunctions?: string[]
}
interface ExtractedFunction {
functionName: string
originalFile: string
extractedPath: string
timestamp: string
}
interface ExtractionRegistry {
version: string
lastUpdated: string
functions: ExtractedFunction[]
}
class AutoCodeExtractor3000 {
private options: ExtractionOptions
private results: FileToExtract[] = []
private startTime: number = 0
private extractionRegistry: ExtractionRegistry = {
version: '1.0.0',
lastUpdated: new Date().toISOString(),
functions: []
}
constructor(options: Partial<ExtractionOptions> = {}) {
this.options = {
@@ -91,6 +110,56 @@ class AutoCodeExtractor3000 {
console.log(`${icons[level]} ${message}`)
}
private async loadExtractionRegistry(): Promise<void> {
try {
let rootDir = process.cwd()
if (rootDir.endsWith('/frontends/nextjs') || rootDir.endsWith('\\frontends\\nextjs')) {
rootDir = path.join(rootDir, '..', '..')
}
const registryPath = path.join(rootDir, 'docs', 'todo', 'EXTRACTION_REGISTRY.json')
this.log(`Loading extraction registry from ${registryPath}`, 'info')
const content = await fs.readFile(registryPath, 'utf-8')
this.extractionRegistry = JSON.parse(content)
this.log(`✅ Loaded extraction registry with ${this.extractionRegistry.functions.length} functions`, 'success')
} catch (error) {
if (error instanceof Error && 'code' in error && error.code === 'ENOENT') {
this.log('No existing extraction registry found, will create new one', 'info')
} else {
this.log(`⚠️ Warning loading registry: ${error instanceof Error ? error.message : String(error)}`, 'warning')
}
}
}
private async saveExtractionRegistry(): Promise<void> {
if (this.options.dryRun) {
this.log('Dry-run mode: skipping registry save', 'info')
return
}
try {
let rootDir = process.cwd()
if (rootDir.endsWith('/frontends/nextjs') || rootDir.endsWith('\\frontends\\nextjs')) {
rootDir = path.join(rootDir, '..', '..')
}
this.extractionRegistry.lastUpdated = new Date().toISOString()
const registryPath = path.join(rootDir, 'docs', 'todo', 'EXTRACTION_REGISTRY.json')
this.log(`Saving extraction registry to ${registryPath}`, 'info')
this.log(`Registry contains ${this.extractionRegistry.functions.length} functions`, 'info')
await fs.writeFile(registryPath, JSON.stringify(this.extractionRegistry, null, 2), 'utf-8')
this.log(`✅ Saved extraction registry with ${this.extractionRegistry.functions.length} functions`, 'success')
} catch (error) {
this.log(`❌ Error saving registry: ${error instanceof Error ? error.message : String(error)}`, 'error')
if (this.options.verbose && error instanceof Error && error.stack) {
console.error('Stack trace:', error.stack)
}
}
}
private async scanAndCategorizeFiles(): Promise<FileToExtract[]> {
this.log('Scanning codebase for files exceeding 150 lines...', 'info')
@@ -176,11 +245,65 @@ class AutoCodeExtractor3000 {
console.log(`\n[${globalIdx}/${files.length}] Processing: ${file.path}`)
try {
// Analyze file to get function names before extraction
this.log(` 🔍 Analyzing file for functions...`, 'info')
const { analyzeAstFile } = await import('./ast/analyze-ast-file')
const { functions } = await analyzeAstFile(absolutePath)
this.log(` 📊 Found ${functions.length} functions: ${functions.map(f => f.name).join(', ') || '(none)'}`, 'info')
if (functions.length === 0) {
file.status = 'skipped'
file.error = 'No functions found in file'
this.log(` ⏭️ Skipped - no functions to extract`, 'warning')
continue
}
if (functions.length <= 2) {
file.status = 'skipped'
file.error = `Only ${functions.length} function(s) - not worth refactoring`
this.log(` ⏭️ Skipped - only ${functions.length} function(s)`, 'warning')
continue
}
this.log(` 🔨 Extracting ${functions.length} functions...`, 'info')
await refactor.refactorFile(absolutePath)
file.status = 'completed'
// Record extracted functions in registry
if (!this.options.dryRun && functions.length > 0) {
const basename = path.basename(absolutePath, path.extname(absolutePath))
const dir = path.dirname(absolutePath)
this.log(` 📝 Recording ${functions.length} functions in registry...`, 'info')
for (const func of functions) {
const kebabName = func.name.replace(/([A-Z])/g, '-$1').toLowerCase().replace(/^-/, '')
const extractedPath = path.join(dir, basename, 'functions', `${kebabName}.ts`)
this.extractionRegistry.functions.push({
functionName: func.name,
originalFile: file.path,
extractedPath: extractedPath.replace(rootDir + '/', ''),
timestamp: new Date().toISOString()
})
}
file.extractedFunctions = functions.map(f => f.name)
this.log(` ✅ Recorded ${functions.length} functions in registry`, 'success')
}
this.log(`Successfully extracted ${file.path}`, 'success')
} catch (error) {
const errorMsg = error instanceof Error ? error.message : String(error)
const errorStack = error instanceof Error ? error.stack : undefined
this.log(` ❌ Error: ${errorMsg}`, 'error')
if (this.options.verbose && errorStack) {
console.error(' Stack trace:', errorStack)
}
if (errorMsg.includes('skipping') || errorMsg.includes('No functions')) {
file.status = 'skipped'
file.error = errorMsg
@@ -290,6 +413,10 @@ class AutoCodeExtractor3000 {
const failed = this.results.filter(f => f.status === 'failed').length
const skipped = this.results.filter(f => f.status === 'skipped').length
const duration = (Date.now() - this.startTime) / 1000
const totalFunctionsExtracted = this.results
.filter(f => f.extractedFunctions)
.reduce((sum, f) => sum + (f.extractedFunctions?.length || 0), 0)
console.log('\n' + '='.repeat(70))
console.log('🎉 AUTO CODE EXTRACTOR 3000™ - SUMMARY')
@@ -299,6 +426,15 @@ class AutoCodeExtractor3000 {
console.log(`✅ Successfully Extracted: ${completed}`)
console.log(`⏭️ Skipped: ${skipped}`)
console.log(`❌ Failed: ${failed}`)
console.log(`📝 Functions Extracted: ${totalFunctionsExtracted}`)
console.log(`🗃️ Registry Total: ${this.extractionRegistry.functions.length} functions`)
if (skipped > 0) {
console.log('\n⏭ Skipped Files:')
this.results
.filter(f => f.status === 'skipped')
.forEach(f => console.log(` - ${f.path}: ${f.error}`))
}
if (failed > 0) {
console.log('\n❌ Failed Files:')
@@ -313,6 +449,13 @@ class AutoCodeExtractor3000 {
} else {
console.log('\n💾 Changes have been written to disk')
console.log(' Review the changes and run tests before committing')
if (totalFunctionsExtracted > 0) {
console.log(`\n📚 Extraction Registry:`)
console.log(` - ${totalFunctionsExtracted} new functions recorded`)
console.log(` - ${this.extractionRegistry.functions.length} total functions tracked`)
console.log(` - Registry saved to: docs/todo/EXTRACTION_REGISTRY.json`)
}
}
console.log('\n📝 Next Steps:')
@@ -336,6 +479,9 @@ class AutoCodeExtractor3000 {
console.log(`Batch Size: ${this.options.batchSize} files`)
console.log('='.repeat(70) + '\n')
// Load existing extraction registry
await this.loadExtractionRegistry()
// Phase 1: Scan and categorize
console.log('PHASE 1: SCANNING & EXTRACTION')
console.log('='.repeat(70) + '\n')
@@ -382,6 +528,7 @@ class AutoCodeExtractor3000 {
// Post-processing
await this.runLinting()
await this.runTests()
await this.saveExtractionRegistry()
await this.updateProgressReport()
await this.saveResults()