diff --git a/.tsc-baseline.json b/.tsc-baseline.json index 665341d57..112d5138d 100644 --- a/.tsc-baseline.json +++ b/.tsc-baseline.json @@ -1,6 +1,6 @@ { - "generatedAt": "2026-05-09T16:16:28.568Z", - "totalErrors": 1214, + "generatedAt": "2026-05-09T17:53:36Z", + "totalErrors": 1132, "counts": { "src/components/admin/DiscountApprovalQueue.tsx": { "TS18048": 1 @@ -358,9 +358,6 @@ "TS7006": 3, "TS7053": 1 }, - "src/components/quote/QuickQuoteFAB.tsx": { - "TS2322": 2 - }, "src/components/quotes/QuoteAutoSave.tsx": { "TS2339": 1 }, @@ -785,10 +782,7 @@ "TS7006": 14 }, "src/pages/ProductDetail.tsx": { - "TS2322": 3, - "TS2339": 85, - "TS2345": 1, - "TS2740": 2 + "TS2322": 9 }, "src/pages/ProductMatchPage.tsx": { "TS2322": 1, @@ -912,6 +906,9 @@ "TS2339": 6, "TS2345": 1, "TS2551": 1 + }, + "src/components/quotes/QuickQuoteFAB.tsx": { + "TS2322": 2 } } } diff --git a/scripts/gen-edges-readme.mjs b/scripts/gen-edges-readme.mjs index d4d6c5955..226b539f7 100755 --- a/scripts/gen-edges-readme.mjs +++ b/scripts/gen-edges-readme.mjs @@ -1,5 +1,15 @@ -import { readFileSync, statSync } from 'node:fs'; +#!/usr/bin/env node +/** + * Gera supabase/functions/README.md com catálogo das edge functions. + * + * Standalone: lê manifest + filesystem + faz scan de callers via grep. + * Não depende de arquivos temporários. + * + * Uso: node scripts/gen-edges-readme.mjs > supabase/functions/README.md + */ +import { readFileSync, readdirSync, statSync } from 'node:fs'; import { join } from 'node:path'; +import { execSync } from 'node:child_process'; const ROOT = process.cwd(); const FUNCS_DIR = join(ROOT, 'supabase/functions'); @@ -7,24 +17,36 @@ const FUNCS_DIR = join(ROOT, 'supabase/functions'); // 1. Parse manifest const manifestSrc = readFileSync(join(FUNCS_DIR, '_shared/edge-authz-manifest.ts'), 'utf8'); const manifest = {}; -// Regex captura: "name": { category: "X", rationale: "Y" } const re = /"([^"]+)":\s*\{\s*category:\s*"(\w+)",\s*rationale:\s*"([^"]+)"/g; let m; while ((m = re.exec(manifestSrc)) !== null) { manifest[m[1]] = { category: m[2], rationale: m[3] }; } -// 2. Lista de dirs -const allDirs = readFileSync('/tmp/edge-dirs.txt', 'utf8') - .split('\n').filter(s => s && !['.', '..', '_shared', 'tests', 'deno.json'].includes(s)); - -// 3. Callers (parse /tmp/edge-callers.txt) -const callersSrc = readFileSync('/tmp/edge-callers.txt', 'utf8'); +// 2. Lista de dirs (filesystem direto, ignora _shared/tests/deno.json) +const SKIP = new Set(['_shared', 'tests', 'deno.json']); +const allDirs = readdirSync(FUNCS_DIR) + .filter(name => { + if (SKIP.has(name)) return false; + try { + return statSync(join(FUNCS_DIR, name)).isDirectory(); + } catch { return false; } + }) + .sort(); + +// 3. Callers (grep direto no src/) const callers = {}; -for (const line of callersSrc.split('\n')) { - if (!line) continue; - const [name, count] = line.split('|'); - callers[name] = parseInt(count) || 0; +for (const dir of allDirs) { + try { + // grep retorna exit 1 se não encontra; capture stderr e ignore + const out = execSync( + `grep -rE "functions\\.invoke\\(['\\"']${dir}['\\"']|invoke\\(['\\"']${dir}['\\"']" --include='*.ts' --include='*.tsx' src/ 2>/dev/null || true`, + { encoding: 'utf8' } + ); + callers[dir] = out.trim() ? out.trim().split('\n').length : 0; + } catch { + callers[dir] = 0; + } } // 4. LOC do index.ts @@ -32,17 +54,12 @@ const loc = {}; for (const dir of allDirs) { try { const idxPath = join(FUNCS_DIR, dir, 'index.ts'); - const content = readFileSync(idxPath, 'utf8'); - loc[dir] = content.split('\n').length; - } catch (e) { - loc[dir] = 0; - } + loc[dir] = readFileSync(idxPath, 'utf8').split('\n').length; + } catch { loc[dir] = 0; } } // 5. Categorize -const byCategory = { - public: [], authenticated: [], supervisor: [], dev: [], service: [], scoped: [], '?': [] -}; +const byCategory = { public: [], authenticated: [], supervisor: [], dev: [], service: [], scoped: [], '?': [] }; for (const dir of allDirs) { const m = manifest[dir]; const cat = m?.category || '?'; @@ -55,13 +72,11 @@ for (const dir of allDirs) { }); } -// 6. Identificar órfãs (no manifest = "authenticated" ou "supervisor" ou "dev" mas sem caller) +// 6. Identificar órfãs const potentiallyOrphan = allDirs.filter(d => { const m = manifest[d]; if (!m) return false; - const cat = m.category; - // Funções front-callable que NÃO são chamadas - if (['authenticated', 'supervisor'].includes(cat) && (callers[d] || 0) === 0) return true; + if (['authenticated', 'supervisor'].includes(m.category) && (callers[d] || 0) === 0) return true; return false; }).sort(); @@ -102,7 +117,6 @@ if (potentiallyOrphan.length > 0) { } md += `\n_Total potencialmente órfãs: **${potentiallyOrphan.length}**_\n\n`; -// Tabelas detalhadas por categoria const catOrder = ['public', 'authenticated', 'supervisor', 'dev', 'service', 'scoped', '?']; const catTitles = { public: '🌐 Públicas (sem autenticação)', @@ -159,7 +173,7 @@ md += ` --- -_Doc gerado automaticamente. Pra atualizar: \`node scripts/gen-edges-readme.mjs\` (script preservado em \`scripts/\`)._ +_Doc gerado automaticamente. Pra atualizar: \`node scripts/gen-edges-readme.mjs > supabase/functions/README.md\`._ `; console.log(md);