From 4d451dab460a0d237b8941eec832a18a71228125 Mon Sep 17 00:00:00 2001 From: JohnDoe6345789 Date: Tue, 30 Dec 2025 00:47:10 +0000 Subject: [PATCH] fix(types): enhance type safety across various components and utilities --- .../[packageId]/handlers/put-package-data.ts | 3 +- .../components/atoms/display/Icon.test.tsx | 4 +-- .../lua-editor/code/LuaCodeEditorSection.tsx | 6 ++-- .../lua/lua-editor/code/useLuaMonacoConfig.ts | 2 +- .../src/components/misc/data/RecordForm.tsx | 10 +++--- .../misc/demos/IRCWebchat/IRCWebchatUtils.ts | 12 +++---- .../IRCWebchatDeclarativeUtils.ts | 12 +++---- .../nextjs/src/lib/lua/functions/types.ts | 19 ++++++---- .../page/page-renderer/PageRendererUtils.ts | 36 +++++++++---------- .../src/lib/ui-pages/load-page-from-db.ts | 10 +++--- frontends/nextjs/src/lib/utils.test.ts | 20 +++++++---- .../__tests__/workflow-engine.errors.test.ts | 4 ++- .../workflow-engine.persistence.test.ts | 27 +++++++++++--- frontends/nextjs/src/types/utility-types.d.ts | 6 ++-- .../admin_dialog/tests/components.test.ts | 7 +++- .../arcade_lobby/tests/components.test.ts | 8 ++++- .../codegen_studio/tests/components.test.ts | 8 ++++- packages/dashboard/tests/components.test.ts | 8 ++++- packages/data_table/tests/components.test.ts | 8 ++++- .../form_builder/tests/components.test.ts | 8 ++++- packages/forum_forge/tests/components.test.ts | 8 ++++- packages/nav_menu/tests/components.test.ts | 7 +++- .../tests/components.test.ts | 7 +++- packages/social_hub/tests/components.test.ts | 8 ++++- packages/stream_cast/tests/components.test.ts | 8 ++++- .../generate-quality-summary/overview.ts | 9 ++++- .../stub-report/completeness-section.ts | 33 +++++++++++++++-- tools/misc/lint/parse-eslint-report.ts | 20 ++++++++--- tools/misc/metrics/parse-npm-audit.ts | 22 ++++++++---- 29 files changed, 248 insertions(+), 92 deletions(-) diff --git a/frontends/nextjs/src/app/api/packages/data/[packageId]/handlers/put-package-data.ts b/frontends/nextjs/src/app/api/packages/data/[packageId]/handlers/put-package-data.ts index 2174eadbc..af8cec1fa 100644 --- a/frontends/nextjs/src/app/api/packages/data/[packageId]/handlers/put-package-data.ts +++ b/frontends/nextjs/src/app/api/packages/data/[packageId]/handlers/put-package-data.ts @@ -3,9 +3,10 @@ import { NextResponse } from 'next/server' import { readJson } from '@/lib/api/read-json' import { setPackageData } from '@/lib/db/packages/set-package-data' +import type { JsonValue } from '@/types/utility-types' type PackageDataPayload = { - data?: Record + data?: Record } interface RouteParams { diff --git a/frontends/nextjs/src/components/atoms/display/Icon.test.tsx b/frontends/nextjs/src/components/atoms/display/Icon.test.tsx index 19085a9d6..757515e4b 100644 --- a/frontends/nextjs/src/components/atoms/display/Icon.test.tsx +++ b/frontends/nextjs/src/components/atoms/display/Icon.test.tsx @@ -1,7 +1,7 @@ import { render } from '@testing-library/react' import { describe, expect, it } from 'vitest' -import { Icon } from './Icon' +import { Icon, type IconName } from './Icon' describe('Icon', () => { it.each([ @@ -20,7 +20,7 @@ describe('Icon', () => { }) it('returns null for unknown icon', () => { - const { container } = render() + const { container } = render() expect(container.querySelector('svg')).toBeNull() }) }) diff --git a/frontends/nextjs/src/components/editors/lua/lua-editor/code/LuaCodeEditorSection.tsx b/frontends/nextjs/src/components/editors/lua/lua-editor/code/LuaCodeEditorSection.tsx index 6b723a123..a314ab028 100644 --- a/frontends/nextjs/src/components/editors/lua/lua-editor/code/LuaCodeEditorSection.tsx +++ b/frontends/nextjs/src/components/editors/lua/lua-editor/code/LuaCodeEditorSection.tsx @@ -17,6 +17,8 @@ import { } from '@/components/ui' import type { LuaScript } from '@/lib/level-types' import { getLuaExampleCode, getLuaExamplesList } from '@/lib/lua-examples' +import type { LuaExampleKey } from '@/lib/lua-examples' +import type { editor } from 'monaco-editor' import { useLuaMonacoConfig } from './useLuaMonacoConfig' @@ -37,7 +39,7 @@ export const LuaCodeEditorSection = ({ onShowSnippetLibraryChange, onUpdateScript, }: LuaCodeEditorSectionProps) => { - const editorRef = useRef(null) + const editorRef = useRef(null) const monaco = useMonaco() useLuaMonacoConfig(monaco) @@ -67,7 +69,7 @@ export const LuaCodeEditorSection = ({ } const handleExampleLoad = (value: string) => { - const exampleCode = getLuaExampleCode(value as any) + const exampleCode = getLuaExampleCode(value as LuaExampleKey) onUpdateScript({ code: exampleCode }) toast.success('Example loaded') } diff --git a/frontends/nextjs/src/components/editors/lua/lua-editor/code/useLuaMonacoConfig.ts b/frontends/nextjs/src/components/editors/lua/lua-editor/code/useLuaMonacoConfig.ts index 6e1709ebf..4003f87c8 100644 --- a/frontends/nextjs/src/components/editors/lua/lua-editor/code/useLuaMonacoConfig.ts +++ b/frontends/nextjs/src/components/editors/lua/lua-editor/code/useLuaMonacoConfig.ts @@ -15,7 +15,7 @@ export const useLuaMonacoConfig = (monaco: Monaco | null) => { endColumn: word.endColumn, } - const suggestions: any[] = [ + const suggestions: monaco.languages.CompletionItem[] = [ { label: 'context.data', kind: monaco.languages.CompletionItemKind.Property, diff --git a/frontends/nextjs/src/components/misc/data/RecordForm.tsx b/frontends/nextjs/src/components/misc/data/RecordForm.tsx index 77db3f9db..01464b04a 100644 --- a/frontends/nextjs/src/components/misc/data/RecordForm.tsx +++ b/frontends/nextjs/src/components/misc/data/RecordForm.tsx @@ -15,8 +15,8 @@ interface RecordFormProps { model: ModelSchema schema: SchemaConfig currentApp: string - record?: any - onSave: (record: any) => void + record?: Record + onSave: (record: Record) => void } export function RecordForm({ @@ -28,7 +28,7 @@ export function RecordForm({ record, onSave, }: RecordFormProps) { - const [formData, setFormData] = useState(record || createEmptyRecord(model)) + const [formData, setFormData] = useState>(record || createEmptyRecord(model)) const [errors, setErrors] = useState>({}) useEffect(() => { @@ -40,8 +40,8 @@ export function RecordForm({ setErrors({}) }, [record, model, open]) - const handleFieldChange = (fieldName: string, value: any) => { - setFormData((prev: any) => ({ + const handleFieldChange = (fieldName: string, value: unknown) => { + setFormData((prev) => ({ ...prev, [fieldName]: value, })) diff --git a/frontends/nextjs/src/components/misc/demos/IRCWebchat/IRCWebchatUtils.ts b/frontends/nextjs/src/components/misc/demos/IRCWebchat/IRCWebchatUtils.ts index d48789538..9a32ca0af 100644 --- a/frontends/nextjs/src/components/misc/demos/IRCWebchat/IRCWebchatUtils.ts +++ b/frontends/nextjs/src/components/misc/demos/IRCWebchat/IRCWebchatUtils.ts @@ -9,15 +9,15 @@ import { IRCWebchat } from './functions/i-r-c-webchat' * This is a convenience wrapper. Prefer importing individual functions. */ export class IRCWebchatUtils { - static IRCWebchat(...args: any[]) { - return IRCWebchat(...(args as any)) + static IRCWebchat(...args: Parameters) { + return IRCWebchat(...args) } - static handleSendMessage(...args: any[]) { - return handleSendMessage(...(args as any)) + static handleSendMessage(...args: Parameters) { + return handleSendMessage(...args) } - static formatTime(...args: any[]) { - return formatTime(...(args as any)) + static formatTime(...args: Parameters) { + return formatTime(...args) } } diff --git a/frontends/nextjs/src/components/misc/demos/IRCWebchatDeclarative/IRCWebchatDeclarativeUtils.ts b/frontends/nextjs/src/components/misc/demos/IRCWebchatDeclarative/IRCWebchatDeclarativeUtils.ts index bb19f0549..a84620bbe 100644 --- a/frontends/nextjs/src/components/misc/demos/IRCWebchatDeclarative/IRCWebchatDeclarativeUtils.ts +++ b/frontends/nextjs/src/components/misc/demos/IRCWebchatDeclarative/IRCWebchatDeclarativeUtils.ts @@ -9,15 +9,15 @@ import { IRCWebchatDeclarative } from './functions/i-r-c-webchat-declarative' * This is a convenience wrapper. Prefer importing individual functions. */ export class IRCWebchatDeclarativeUtils { - static IRCWebchatDeclarative(...args: any[]) { - return IRCWebchatDeclarative(...(args as any)) + static IRCWebchatDeclarative(...args: Parameters) { + return IRCWebchatDeclarative(...args) } - static async handleSendMessage(...args: any[]) { - return await handleSendMessage(...(args as any)) + static async handleSendMessage(...args: Parameters) { + return await handleSendMessage(...args) } - static async formatTime(...args: any[]) { - return await formatTime(...(args as any)) + static async formatTime(...args: Parameters) { + return await formatTime(...args) } } diff --git a/frontends/nextjs/src/lib/lua/functions/types.ts b/frontends/nextjs/src/lib/lua/functions/types.ts index 3c9bcf4b9..ab7d17896 100644 --- a/frontends/nextjs/src/lib/lua/functions/types.ts +++ b/frontends/nextjs/src/lib/lua/functions/types.ts @@ -3,19 +3,24 @@ * Shared type definitions for Lua execution */ +import type { JsonValue } from '@/types/utility-types' + +/** Fengari Lua state - opaque type from fengari-web */ +export type LuaState = ReturnType + export interface LuaExecutionContext { - data?: any - user?: any + data?: JsonValue + user?: JsonValue kv?: { - get: (key: string) => Promise - set: (key: string, value: any) => Promise + get: (key: string) => Promise + set: (key: string, value: JsonValue) => Promise } - log?: (...args: any[]) => void + log?: (...args: unknown[]) => void } export interface LuaExecutionResult { success: boolean - result?: any + result?: JsonValue error?: string logs: string[] } @@ -26,7 +31,7 @@ export interface LuaExecutionResult { */ export interface LuaEngineState { /** The Fengari Lua state */ - L: any + L: LuaState /** Logs captured during execution */ logs: string[] } diff --git a/frontends/nextjs/src/lib/rendering/page/page-renderer/PageRendererUtils.ts b/frontends/nextjs/src/lib/rendering/page/page-renderer/PageRendererUtils.ts index e67689a92..900cce843 100644 --- a/frontends/nextjs/src/lib/rendering/page/page-renderer/PageRendererUtils.ts +++ b/frontends/nextjs/src/lib/rendering/page/page-renderer/PageRendererUtils.ts @@ -15,39 +15,39 @@ import { registerPage } from './functions/register-page' * 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 registerPage(...args: Parameters) { + return await registerPage(...args) } - static async loadPages(...args: any[]) { - return await loadPages(...(args as any)) + static async loadPages(...args: Parameters) { + return await loadPages(...args) } - static getPage(...args: any[]) { - return getPage(...(args as any)) + static getPage(...args: Parameters) { + return getPage(...args) } - static getPagesByLevel(...args: any[]) { - return getPagesByLevel(...(args as any)) + static getPagesByLevel(...args: Parameters) { + return getPagesByLevel(...args) } - static async executeLuaScript(...args: any[]) { - return await executeLuaScript(...(args as any)) + static async executeLuaScript(...args: Parameters) { + return await executeLuaScript(...args) } - static async checkPermissions(...args: any[]) { - return await checkPermissions(...(args as any)) + static async checkPermissions(...args: Parameters) { + return await checkPermissions(...args) } - static async onPageLoad(...args: any[]) { - return await onPageLoad(...(args as any)) + static async onPageLoad(...args: Parameters) { + return await onPageLoad(...args) } - static async onPageUnload(...args: any[]) { - return await onPageUnload(...(args as any)) + static async onPageUnload(...args: Parameters) { + return await onPageUnload(...args) } - static getPageRenderer(...args: any[]) { - return getPageRenderer(...(args as any)) + static getPageRenderer(...args: Parameters) { + return getPageRenderer(...args) } } diff --git a/frontends/nextjs/src/lib/ui-pages/load-page-from-db.ts b/frontends/nextjs/src/lib/ui-pages/load-page-from-db.ts index e0f1169d2..d92c40bff 100644 --- a/frontends/nextjs/src/lib/ui-pages/load-page-from-db.ts +++ b/frontends/nextjs/src/lib/ui-pages/load-page-from-db.ts @@ -3,9 +3,9 @@ import { createLuaEngine } from '@/lib/lua/engine/core/create-lua-engine' import { executeLuaCode } from '@/lib/lua/functions/execution/execute-lua-code' import { normalizeLuaStructure } from '@/lib/lua/ui/normalize-lua-structure' import type { UIPageRecord } from '@/lib/seed/import-ui-pages' -import type { JsonObject } from '@/types/utility-types' +import type { JsonObject, JsonValue } from '@/types/utility-types' -export type LuaActionHandler = (payload?: Record) => Promise +export type LuaActionHandler = (payload?: JsonObject) => Promise /** * Load a UI page from database and optionally process with Lua @@ -25,7 +25,7 @@ export async function loadPageFromDB(path: string): Promise { const page = pages[0] // 2. Get associated Lua scripts if any (from actions field) - let processedLayout = page.layout + let processedLayout: JsonValue = page.layout const actionHandlers: Record = {} if (page.actions) { @@ -81,7 +81,7 @@ export async function loadPageFromDB(path: string): Promise { * Create a JavaScript wrapper for a Lua action handler */ function createLuaActionHandler(luaCode: string, actionName: string): LuaActionHandler { - return async (payload: Record = {}) => { + return async (payload: JsonObject = {}) => { const engine = createLuaEngine() try { @@ -97,7 +97,7 @@ function createLuaActionHandler(luaCode: string, actionName: string): LuaActionH throw new Error(result.error) } - return result.result + return (result.result ?? null) as JsonValue | null } finally { engine.destroy() } diff --git a/frontends/nextjs/src/lib/utils.test.ts b/frontends/nextjs/src/lib/utils.test.ts index c5de92ef0..465e6b861 100644 --- a/frontends/nextjs/src/lib/utils.test.ts +++ b/frontends/nextjs/src/lib/utils.test.ts @@ -1,3 +1,4 @@ +import type { ClassValue } from 'clsx' import { describe, expect, it } from 'vitest' import { cn } from '@/lib/utils' @@ -5,17 +6,22 @@ import { cn } from '@/lib/utils' describe('utils', () => { describe('cn', () => { // Note: cn() uses clsx, which concatenates classes without smart Tailwind merging - it.each([ + const cases: Array<{ + input: ClassValue[] + shouldContain: string[] + shouldNotContain: string[] + description: string + }> = [ { input: ['px-2 py-1', 'px-3'], shouldContain: ['px-2', 'py-1', 'px-3'], - shouldNotContain: [] as string[], + shouldNotContain: [], description: 'concatenate classes (no tailwind deduplication)', }, { input: ['px-2', 'py-2'], shouldContain: ['px-2', 'py-2'], - shouldNotContain: [] as string[], + shouldNotContain: [], description: 'handle simple classes', }, { @@ -27,7 +33,7 @@ describe('utils', () => { { input: ['px-2 py-1 bg-red-500', 'px-3 bg-blue-500'], shouldContain: ['px-2', 'px-3', 'py-1', 'bg-red-500', 'bg-blue-500'], - shouldNotContain: [] as string[], + shouldNotContain: [], description: 'concatenate all classes (no tailwind deduplication)', }, { @@ -42,8 +48,10 @@ describe('utils', () => { shouldNotContain: [], description: 'handle arrays of classes', }, - ])('should $description', ({ input, shouldContain, shouldNotContain }) => { - const result = cn(...(input as any)) + ] + + it.each(cases)('should $description', ({ input, shouldContain, shouldNotContain }) => { + const result = cn(...input) shouldContain.forEach(cls => { expect(result).toContain(cls) }) diff --git a/frontends/nextjs/src/lib/workflow/engine/__tests__/workflow-engine.errors.test.ts b/frontends/nextjs/src/lib/workflow/engine/__tests__/workflow-engine.errors.test.ts index e723b6a41..e44321d7a 100644 --- a/frontends/nextjs/src/lib/workflow/engine/__tests__/workflow-engine.errors.test.ts +++ b/frontends/nextjs/src/lib/workflow/engine/__tests__/workflow-engine.errors.test.ts @@ -1,12 +1,14 @@ import { describe, expect, it } from 'vitest' +import type { WorkflowNode } from '../../../types/level-types' import { WorkflowEngine } from '../workflow-engine' import { createContext, createNode, createWorkflow } from './workflow-engine.fixtures' describe('workflow-engine errors', () => { it('fails unknown node types with a clear error', async () => { + const invalidType = 'unknown' as WorkflowNode['type'] const workflow = createWorkflow('err-1', 'Unknown node', [ - createNode('mystery', 'unknown' as any, 'Mystery node'), + createNode('mystery', invalidType, 'Mystery node'), ]) const result = await WorkflowEngine.execute(workflow, createContext({})) diff --git a/frontends/nextjs/src/lib/workflow/engine/__tests__/workflow-engine.persistence.test.ts b/frontends/nextjs/src/lib/workflow/engine/__tests__/workflow-engine.persistence.test.ts index 5bbe45bd1..a4e04911b 100644 --- a/frontends/nextjs/src/lib/workflow/engine/__tests__/workflow-engine.persistence.test.ts +++ b/frontends/nextjs/src/lib/workflow/engine/__tests__/workflow-engine.persistence.test.ts @@ -1,7 +1,11 @@ import { afterEach, describe, expect, it, vi } from 'vitest' import * as SandboxFactory from '../../../lua/engine/sandbox/create-sandboxed-lua-engine' -import type { SandboxedLuaResult } from '../../../lua/engine/sandbox/sandboxed-lua-engine' +import type { + SandboxedLuaEngine, + SandboxedLuaResult, +} from '../../../lua/engine/sandbox/sandboxed-lua-engine' +import type { SecurityScanResult } from '../../../security/scanner/types' import { WorkflowEngine } from '../workflow-engine' import { createContext, createNode, createWorkflow } from './workflow-engine.fixtures' @@ -29,17 +33,30 @@ describe('workflow-engine persistence', () => { }) it('persists security warnings from Lua execution', async () => { + const securityResult: SecurityScanResult = { + safe: false, + severity: 'high', + issues: [ + { + type: 'dangerous', + severity: 'high', + message: 'uses os', + pattern: 'os', + }, + ], + } + const sandboxResult: SandboxedLuaResult = { execution: { success: true, result: 99, logs: ['lua log'] }, - security: { severity: 'high', issues: [{ message: 'uses os' }] } as any, + security: securityResult, } - const mockEngine = { + const mockEngine: SandboxedLuaEngine = { executeWithSandbox: vi.fn(async () => sandboxResult), destroy: vi.fn(), - } + } as SandboxedLuaEngine - vi.spyOn(SandboxFactory, 'createSandboxedLuaEngine').mockReturnValue(mockEngine as any) + vi.spyOn(SandboxFactory, 'createSandboxedLuaEngine').mockReturnValue(mockEngine) const workflow = createWorkflow('persist-2', 'Lua security', [ createNode('lua', 'lua', 'Sandboxed', { code: 'return 1' }), diff --git a/frontends/nextjs/src/types/utility-types.d.ts b/frontends/nextjs/src/types/utility-types.d.ts index 88176112c..bc1d3fddb 100644 --- a/frontends/nextjs/src/types/utility-types.d.ts +++ b/frontends/nextjs/src/types/utility-types.d.ts @@ -48,13 +48,13 @@ export interface LuaTable { /** * Lua function representation */ -export type LuaFunction = (...args: unknown[]) => unknown +export type LuaFunction = (...args: JsonValue[]) => JsonValue /** * Generic property bag for metadata and dynamic properties * Prefer specific interfaces when structure is known */ -export type PropertyBag = Record +export type PropertyBag = Record /** * Type-safe record with specific value type @@ -64,4 +64,4 @@ export type TypedRecord = Record /** * Unknown error type (for catch blocks) */ -export type UnknownError = unknown +export type UnknownError = Error | string diff --git a/packages/admin_dialog/tests/components.test.ts b/packages/admin_dialog/tests/components.test.ts index 45f486454..5d9c239c5 100644 --- a/packages/admin_dialog/tests/components.test.ts +++ b/packages/admin_dialog/tests/components.test.ts @@ -1,6 +1,11 @@ import { describe, it, expect } from 'vitest' import components from '../seed/components.json' +interface ComponentDefinition { + id: string + type: string +} + describe('Admin Dialog Components', () => { it('should be a valid array', () => { expect(components).toBeInstanceOf(Array) @@ -8,7 +13,7 @@ describe('Admin Dialog Components', () => { it('should have valid component structure if components exist', () => { if (components.length > 0) { - components.forEach((component: any) => { + components.forEach((component: ComponentDefinition) => { expect(component.id).toBeDefined() expect(component.type).toBeDefined() expect(typeof component.id).toBe('string') diff --git a/packages/arcade_lobby/tests/components.test.ts b/packages/arcade_lobby/tests/components.test.ts index 04260d1a0..cbb46942d 100644 --- a/packages/arcade_lobby/tests/components.test.ts +++ b/packages/arcade_lobby/tests/components.test.ts @@ -1,6 +1,12 @@ import { describe, it, expect } from 'vitest' import components from '../seed/components.json' +interface ComponentDefinition { + id: string + type: string + children: unknown[] +} + describe('Arcade Lobby Components', () => { it('should be a valid array', () => { expect(components).toBeInstanceOf(Array) @@ -8,7 +14,7 @@ describe('Arcade Lobby Components', () => { it('should have valid component structure if components exist', () => { if (components.length > 0) { - components.forEach((component: any) => { + components.forEach((component: ComponentDefinition) => { expect(component.id).toBeDefined() expect(component.type).toBeDefined() expect(typeof component.id).toBe('string') diff --git a/packages/codegen_studio/tests/components.test.ts b/packages/codegen_studio/tests/components.test.ts index e339e8c6f..2736b1682 100644 --- a/packages/codegen_studio/tests/components.test.ts +++ b/packages/codegen_studio/tests/components.test.ts @@ -1,6 +1,12 @@ import { describe, it, expect } from 'vitest' import components from '../seed/components.json' +interface ComponentDefinition { + id: string + type: string + children: unknown[] +} + describe('Codegen Studio Components', () => { it('should be a valid array', () => { expect(components).toBeInstanceOf(Array) @@ -8,7 +14,7 @@ describe('Codegen Studio Components', () => { it('should have valid component structure if components exist', () => { if (components.length > 0) { - components.forEach((component: any) => { + components.forEach((component: ComponentDefinition) => { expect(component.id).toBeDefined() expect(component.type).toBeDefined() expect(typeof component.id).toBe('string') diff --git a/packages/dashboard/tests/components.test.ts b/packages/dashboard/tests/components.test.ts index b899ec5d9..ee7abfd52 100644 --- a/packages/dashboard/tests/components.test.ts +++ b/packages/dashboard/tests/components.test.ts @@ -1,6 +1,12 @@ import { describe, it, expect } from 'vitest' import components from '../seed/components.json' +interface ComponentDefinition { + id: string + type: string + children: unknown[] +} + describe('Dashboard Components', () => { it('should be a valid array', () => { expect(components).toBeInstanceOf(Array) @@ -8,7 +14,7 @@ describe('Dashboard Components', () => { it('should have valid component structure if components exist', () => { if (components.length > 0) { - components.forEach((component: any) => { + components.forEach((component: ComponentDefinition) => { expect(component.id).toBeDefined() expect(component.type).toBeDefined() expect(typeof component.id).toBe('string') diff --git a/packages/data_table/tests/components.test.ts b/packages/data_table/tests/components.test.ts index c95805a9c..eaee10d25 100644 --- a/packages/data_table/tests/components.test.ts +++ b/packages/data_table/tests/components.test.ts @@ -1,6 +1,12 @@ import { describe, it, expect } from 'vitest' import components from '../seed/components.json' +interface ComponentDefinition { + id: string + type: string + children: unknown[] +} + describe('Data Table Components', () => { it('should be a valid array', () => { expect(components).toBeInstanceOf(Array) @@ -8,7 +14,7 @@ describe('Data Table Components', () => { it('should have valid component structure if components exist', () => { if (components.length > 0) { - components.forEach((component: any) => { + components.forEach((component: ComponentDefinition) => { expect(component.id).toBeDefined() expect(component.type).toBeDefined() expect(typeof component.id).toBe('string') diff --git a/packages/form_builder/tests/components.test.ts b/packages/form_builder/tests/components.test.ts index 7a3137bb6..f96d4c503 100644 --- a/packages/form_builder/tests/components.test.ts +++ b/packages/form_builder/tests/components.test.ts @@ -1,6 +1,12 @@ import { describe, it, expect } from 'vitest' import components from '../seed/components.json' +interface ComponentDefinition { + id: string + type: string + children: unknown[] +} + describe('Form Builder Components', () => { it('should be a valid array', () => { expect(components).toBeInstanceOf(Array) @@ -8,7 +14,7 @@ describe('Form Builder Components', () => { it('should have valid component structure if components exist', () => { if (components.length > 0) { - components.forEach((component: any) => { + components.forEach((component: ComponentDefinition) => { expect(component.id).toBeDefined() expect(component.type).toBeDefined() expect(typeof component.id).toBe('string') diff --git a/packages/forum_forge/tests/components.test.ts b/packages/forum_forge/tests/components.test.ts index ae03b064b..2d18faac5 100644 --- a/packages/forum_forge/tests/components.test.ts +++ b/packages/forum_forge/tests/components.test.ts @@ -1,6 +1,12 @@ import { describe, it, expect } from 'vitest' import components from '../seed/components.json' +interface ComponentDefinition { + id: string + type: string + children: unknown[] +} + describe('Forum Forge Components', () => { it('should be a valid array', () => { expect(components).toBeInstanceOf(Array) @@ -8,7 +14,7 @@ describe('Forum Forge Components', () => { it('should have valid component structure if components exist', () => { if (components.length > 0) { - components.forEach((component: any) => { + components.forEach((component: ComponentDefinition) => { expect(component.id).toBeDefined() expect(component.type).toBeDefined() expect(typeof component.id).toBe('string') diff --git a/packages/nav_menu/tests/components.test.ts b/packages/nav_menu/tests/components.test.ts index f10ebb0fc..525fadae6 100644 --- a/packages/nav_menu/tests/components.test.ts +++ b/packages/nav_menu/tests/components.test.ts @@ -1,6 +1,11 @@ import { describe, it, expect } from 'vitest' import components from '../seed/components.json' +interface ComponentDefinition { + id: string + type: string +} + describe('Nav Menu Components', () => { it('should be a valid array', () => { expect(components).toBeInstanceOf(Array) @@ -8,7 +13,7 @@ describe('Nav Menu Components', () => { it('should have valid component structure if components exist', () => { if (components.length > 0) { - components.forEach((component: any) => { + components.forEach((component: ComponentDefinition) => { expect(component.id).toBeDefined() expect(component.type).toBeDefined() expect(typeof component.id).toBe('string') diff --git a/packages/notification_center/tests/components.test.ts b/packages/notification_center/tests/components.test.ts index 983067b17..523ba170a 100644 --- a/packages/notification_center/tests/components.test.ts +++ b/packages/notification_center/tests/components.test.ts @@ -1,6 +1,11 @@ import { describe, it, expect } from 'vitest' import components from '../seed/components.json' +interface ComponentDefinition { + id: string + type: string +} + describe('Notification Center Components', () => { it('should be a valid array', () => { expect(components).toBeInstanceOf(Array) @@ -8,7 +13,7 @@ describe('Notification Center Components', () => { it('should have valid component structure if components exist', () => { if (components.length > 0) { - components.forEach((component: any) => { + components.forEach((component: ComponentDefinition) => { expect(component.id).toBeDefined() expect(component.type).toBeDefined() expect(typeof component.id).toBe('string') diff --git a/packages/social_hub/tests/components.test.ts b/packages/social_hub/tests/components.test.ts index 4933f7f99..bf92b1031 100644 --- a/packages/social_hub/tests/components.test.ts +++ b/packages/social_hub/tests/components.test.ts @@ -1,6 +1,12 @@ import { describe, it, expect } from 'vitest' import components from '../seed/components.json' +interface ComponentDefinition { + id: string + type: string + children: unknown[] +} + describe('Social Hub Components', () => { it('should be a valid array', () => { expect(components).toBeInstanceOf(Array) @@ -8,7 +14,7 @@ describe('Social Hub Components', () => { it('should have valid component structure if components exist', () => { if (components.length > 0) { - components.forEach((component: any) => { + components.forEach((component: ComponentDefinition) => { expect(component.id).toBeDefined() expect(component.type).toBeDefined() expect(typeof component.id).toBe('string') diff --git a/packages/stream_cast/tests/components.test.ts b/packages/stream_cast/tests/components.test.ts index 6102c7edb..f0e25ea87 100644 --- a/packages/stream_cast/tests/components.test.ts +++ b/packages/stream_cast/tests/components.test.ts @@ -1,6 +1,12 @@ import { describe, it, expect } from 'vitest' import components from '../seed/components.json' +interface ComponentDefinition { + id: string + type: string + children: unknown[] +} + describe('Stream Cast Components', () => { it('should be a valid array', () => { expect(components).toBeInstanceOf(Array) @@ -8,7 +14,7 @@ describe('Stream Cast Components', () => { it('should have valid component structure if components exist', () => { if (components.length > 0) { - components.forEach((component: any) => { + components.forEach((component: ComponentDefinition) => { expect(component.id).toBeDefined() expect(component.type).toBeDefined() expect(typeof component.id).toBe('string') diff --git a/tools/generation/generate-quality-summary/overview.ts b/tools/generation/generate-quality-summary/overview.ts index 50ba31b7d..b1ff872ef 100644 --- a/tools/generation/generate-quality-summary/overview.ts +++ b/tools/generation/generate-quality-summary/overview.ts @@ -6,7 +6,14 @@ type OverviewStatus = { details: string } -const selectDetails = (data: any): OverviewStatus | undefined => { +interface ReportData { + coverage?: number + totalIssues?: number + critical?: number + averageCoverage?: number +} + +const selectDetails = (data: ReportData | null): OverviewStatus | undefined => { if (data?.coverage !== undefined) { return { status: data.coverage >= 80 ? '✅ Pass' : '⚠️ Warning', diff --git a/tools/generation/stub-report/completeness-section.ts b/tools/generation/stub-report/completeness-section.ts index 047b12691..0a831914c 100644 --- a/tools/generation/stub-report/completeness-section.ts +++ b/tools/generation/stub-report/completeness-section.ts @@ -1,10 +1,31 @@ import { existsSync, readFileSync } from 'fs' +interface StubInfo { + name: string + file: string + line: number + type: string + flags: string[] + summary: string +} + +interface CompletenessAnalysis { + averageCompleteness: number + bySeverity: { + critical: number + high: number + medium: number + low: number + } + flagTypes: Record + criticalStubs?: StubInfo[] +} + export const buildCompletenessSection = (): string => { if (!existsSync('implementation-analysis.json')) return '' try { - const completeness = JSON.parse(readFileSync('implementation-analysis.json', 'utf8')) + const completeness: CompletenessAnalysis = JSON.parse(readFileSync('implementation-analysis.json', 'utf8')) let section = '## Implementation Completeness Analysis\n\n' section += `**Average Completeness Score**: ${completeness.averageCompleteness}%\n\n` @@ -27,7 +48,15 @@ export const buildCompletenessSection = (): string => { if (completeness.criticalStubs && completeness.criticalStubs.length > 0) { section += '### 🔴 Incomplete Implementations (0% Completeness)\n\n' section += '
Click to expand\n\n' - completeness.criticalStubs.forEach((stub: any) => { + interface CriticalStub { + name: string + file: string + line: number + type: string + flags: string[] + summary: string + } + completeness.criticalStubs.forEach((stub: CriticalStub) => { section += `#### \`${stub.name}\` in \`${stub.file}:${stub.line}\`\n` section += `**Type**: ${stub.type}\n` section += `**Flags**: ${stub.flags.join(', ')}\n` diff --git a/tools/misc/lint/parse-eslint-report.ts b/tools/misc/lint/parse-eslint-report.ts index 75fa564ec..2a29c9885 100644 --- a/tools/misc/lint/parse-eslint-report.ts +++ b/tools/misc/lint/parse-eslint-report.ts @@ -1,12 +1,24 @@ import { readFileSync } from 'fs' +interface ESLintMessage { + severity: number + message: string + line: number + column: number +} + +interface ESLintFileReport { + filePath: string + messages: ESLintMessage[] +} + try { - const report = JSON.parse(readFileSync('eslint-report.json', 'utf8')) + const report: ESLintFileReport[] = JSON.parse(readFileSync('eslint-report.json', 'utf8')) const summary = { totalFiles: report.length, - filesWithIssues: report.filter((f: any) => f.messages.length > 0).length, - errors: report.reduce((sum: number, f: any) => sum + f.messages.filter((m: any) => m.severity === 2).length, 0), - warnings: report.reduce((sum: number, f: any) => sum + f.messages.filter((m: any) => m.severity === 1).length, 0), + filesWithIssues: report.filter((f) => f.messages.length > 0).length, + errors: report.reduce((sum: number, f) => sum + f.messages.filter((m) => m.severity === 2).length, 0), + warnings: report.reduce((sum: number, f) => sum + f.messages.filter((m) => m.severity === 1).length, 0), timestamp: new Date().toISOString() } console.log(JSON.stringify(summary, null, 2)) diff --git a/tools/misc/metrics/parse-npm-audit.ts b/tools/misc/metrics/parse-npm-audit.ts index c382444c4..b2e480d4f 100644 --- a/tools/misc/metrics/parse-npm-audit.ts +++ b/tools/misc/metrics/parse-npm-audit.ts @@ -3,6 +3,13 @@ // Parse npm audit JSON and format results import { execSync } from 'child_process' +interface NpmVulnerability { + name: string + severity: string + version: string + fixAvailable: boolean +} + try { const audit = JSON.parse(execSync('npm audit --json 2>/dev/null || echo "{}"', { encoding: 'utf8' })) @@ -15,12 +22,15 @@ try { info: audit.metadata?.vulnerabilities?.info || 0 }, totalVulnerabilities: audit.metadata?.totalVulnerabilities || 0, - advisories: Object.values(audit.vulnerabilities || {}).map((v: any) => ({ - name: v.name, - severity: v.severity, - version: v.version, - fixAvailable: v.fixAvailable - })), + advisories: Object.values(audit.vulnerabilities || {}).map((v) => { + const vuln = v as NpmVulnerability + return { + name: vuln.name, + severity: vuln.severity, + version: vuln.version, + fixAvailable: vuln.fixAvailable + } + }), timestamp: new Date().toISOString() }