From 5b447e7a11994182a6aea34248c6e383d2ee98c0 Mon Sep 17 00:00:00 2001 From: jackwener Date: Fri, 20 Mar 2026 10:53:25 +0800 Subject: [PATCH] refactor: strictly type output and registry pipelines, removing any where possible --- package-lock.json | 3 +++ src/explore.ts | 18 ++++++++++-------- src/output.ts | 24 ++++++++++++------------ src/registry.ts | 6 +++--- 4 files changed, 28 insertions(+), 23 deletions(-) diff --git a/package-lock.json b/package-lock.json index 66d645c..151efc8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1557,6 +1557,7 @@ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=12" }, @@ -1752,6 +1753,7 @@ "integrity": "sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "esbuild": "~0.27.0", "get-tsconfig": "^4.7.5" @@ -1793,6 +1795,7 @@ "integrity": "sha512-fPGaRNj9Zytaf8LEiBhY7Z6ijnFKdzU/+mL8EFBaKr7Vw1/FWcTBAMW0wLPJAGMPX38ZPVCVgLceWiEqeoqL2Q==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@oxc-project/runtime": "0.115.0", "lightningcss": "^1.32.0", diff --git a/src/explore.ts b/src/explore.ts index e129ab8..d86bc06 100644 --- a/src/explore.ts +++ b/src/explore.ts @@ -53,7 +53,7 @@ export function slugify(value: string): string { interface NetworkEntry { method: string; url: string; status: number | null; - contentType: string; responseBody?: any; requestHeaders?: Record; + contentType: string; responseBody?: unknown; requestHeaders?: Record; } interface AnalyzedEndpoint { @@ -75,7 +75,7 @@ interface InferredCapability { * Parse raw network output from Playwright MCP. * Handles text format: [GET] url => [200] */ -function parseNetworkRequests(raw: any): NetworkEntry[] { +function parseNetworkRequests(raw: unknown): NetworkEntry[] { if (typeof raw === 'string') { const entries: NetworkEntry[] = []; for (const line of raw.split('\n')) { @@ -123,11 +123,11 @@ function detectAuthIndicators(headers?: Record): string[] { return indicators; } -function analyzeResponseBody(body: any): AnalyzedEndpoint['responseAnalysis'] { +function analyzeResponseBody(body: unknown): AnalyzedEndpoint['responseAnalysis'] { if (!body || typeof body !== 'object') return null; - const candidates: Array<{ path: string; items: any[] }> = []; + const candidates: Array<{ path: string; items: unknown[] }> = []; - function findArrays(obj: any, path: string, depth: number) { + function findArrays(obj: unknown, path: string, depth: number) { if (depth > 4) return; if (Array.isArray(obj) && obj.length >= 2 && obj.some(item => item && typeof item === 'object' && !Array.isArray(item))) { candidates.push({ path, items: obj }); @@ -154,13 +154,15 @@ function analyzeResponseBody(body: any): AnalyzedEndpoint['responseAnalysis'] { return { itemPath: best.path || null, itemCount: best.items.length, detectedFields, sampleFields }; } -function flattenFields(obj: any, prefix: string, maxDepth: number): string[] { +function flattenFields(obj: unknown, prefix: string, maxDepth: number): string[] { if (maxDepth <= 0 || !obj || typeof obj !== 'object') return []; const names: string[] = []; - for (const key of Object.keys(obj)) { + const record = obj as Record; + for (const key of Object.keys(record)) { const full = prefix ? `${prefix}.${key}` : key; names.push(full); - if (obj[key] && typeof obj[key] === 'object' && !Array.isArray(obj[key])) names.push(...flattenFields(obj[key], full, maxDepth - 1)); + const val = record[key]; + if (val && typeof val === 'object' && !Array.isArray(val)) names.push(...flattenFields(val, full, maxDepth - 1)); } return names; } diff --git a/src/output.ts b/src/output.ts index e031f07..d2cea78 100644 --- a/src/output.ts +++ b/src/output.ts @@ -14,7 +14,7 @@ export interface RenderOptions { source?: string; } -export function render(data: any, opts: RenderOptions = {}): void { +export function render(data: unknown, opts: RenderOptions = {}): void { const fmt = opts.fmt ?? 'table'; if (data === null || data === undefined) { console.log(data); @@ -29,8 +29,8 @@ export function render(data: any, opts: RenderOptions = {}): void { } } -function renderTable(data: any, opts: RenderOptions): void { - const rows: any[] = Array.isArray(data) ? data : [data]; +function renderTable(data: unknown, opts: RenderOptions): void { + const rows = Array.isArray(data) ? data : [data as Record]; if (!rows.length) { console.log(chalk.dim('(no data)')); return; } const columns = opts.columns ?? Object.keys(rows[0]); @@ -44,7 +44,7 @@ function renderTable(data: any, opts: RenderOptions): void { for (const row of rows) { table.push(columns.map(c => { - const v = row[c]; + const v = (row as Record)[c]; return v === null || v === undefined ? '' : String(v); })); } @@ -59,36 +59,36 @@ function renderTable(data: any, opts: RenderOptions): void { console.log(chalk.dim(footer.join(' ยท '))); } -function renderJson(data: any): void { +function renderJson(data: unknown): void { console.log(JSON.stringify(data, null, 2)); } -function renderMarkdown(data: any, opts: RenderOptions): void { - const rows: any[] = Array.isArray(data) ? data : [data]; +function renderMarkdown(data: unknown, opts: RenderOptions): void { + const rows = Array.isArray(data) ? data : [data as Record]; if (!rows.length) return; const columns = opts.columns ?? Object.keys(rows[0]); console.log('| ' + columns.join(' | ') + ' |'); console.log('| ' + columns.map(() => '---').join(' | ') + ' |'); for (const row of rows) { - console.log('| ' + columns.map(c => String(row[c] ?? '')).join(' | ') + ' |'); + console.log('| ' + columns.map(c => String((row as Record)[c] ?? '')).join(' | ') + ' |'); } } -function renderCsv(data: any, opts: RenderOptions): void { - const rows: any[] = Array.isArray(data) ? data : [data]; +function renderCsv(data: unknown, opts: RenderOptions): void { + const rows = Array.isArray(data) ? data : [data as Record]; if (!rows.length) return; const columns = opts.columns ?? Object.keys(rows[0]); console.log(columns.join(',')); for (const row of rows) { console.log(columns.map(c => { - const v = String(row[c] ?? ''); + const v = String((row as Record)[c] ?? ''); return v.includes(',') || v.includes('"') || v.includes('\n') ? `"${v.replace(/"/g, '""')}"` : v; }).join(',')); } } -function renderYaml(data: any): void { +function renderYaml(data: unknown): void { console.log(yaml.dump(data, { sortKeys: false, lineWidth: 120, noRefs: true })); } diff --git a/src/registry.ts b/src/registry.ts index 8dc57d5..894119d 100644 --- a/src/registry.ts +++ b/src/registry.ts @@ -15,7 +15,7 @@ export enum Strategy { export interface Arg { name: string; type?: string; - default?: any; + default?: unknown; required?: boolean; positional?: boolean; help?: string; @@ -31,8 +31,8 @@ export interface CliCommand { browser?: boolean; args: Arg[]; columns?: string[]; - func?: (page: IPage, kwargs: Record, debug?: boolean) => Promise; - pipeline?: any[]; + func?: (page: IPage, kwargs: Record, debug?: boolean) => Promise; + pipeline?: Record[]; timeoutSeconds?: number; source?: string; }