Files
Sankofa/api/scripts/fix-ts6133.py
defiQUG 33d50fb91e
Some checks failed
API CI / API Lint (push) Successful in 47s
API CI / API Type Check (push) Failing after 47s
API CI / API Test (push) Successful in 1m0s
API CI / API Build (push) Failing after 50s
API CI / Build Docker Image (push) Has been skipped
Build Crossplane Provider / build (push) Failing after 5m51s
CD Pipeline / Deploy to Staging (push) Failing after 29s
CI Pipeline / Lint and Type Check (push) Failing after 36s
CI Pipeline / Build (push) Has been skipped
CI Pipeline / Test Backend (push) Failing after 1m33s
CI Pipeline / Test Frontend (push) Failing after 30s
CI Pipeline / Security Scan (push) Failing after 1m16s
Crossplane Provider CI / Go Test (push) Failing after 3m23s
Crossplane Provider CI / Go Lint (push) Failing after 7m27s
Crossplane Provider CI / Go Build (push) Failing after 3m27s
Deploy to Staging / Deploy to Staging (push) Failing after 30s
Portal CI / Portal Lint (push) Failing after 21s
Portal CI / Portal Type Check (push) Failing after 21s
Portal CI / Portal Test (push) Failing after 21s
Portal CI / Portal Build (push) Failing after 22s
Test Suite / frontend-tests (push) Failing after 30s
Test Suite / api-tests (push) Failing after 49s
Test Suite / blockchain-tests (push) Failing after 30s
Type Check / type-check (map[directory:. name:root]) (push) Failing after 23s
Type Check / type-check (map[directory:api name:api]) (push) Failing after 21s
Type Check / type-check (map[directory:portal name:portal]) (push) Failing after 19s
Validate Configuration Files / validate (push) Failing after 1m52s
CD Pipeline / Deploy to Production (push) Has been skipped
chore: consolidate local WIP (repo cleanup 20260707)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-07 09:41:34 -07:00

137 lines
4.6 KiB
Python

#!/usr/bin/env python3
"""Fix TS6133 unused variable/import errors reported by tsc."""
import re
import subprocess
import sys
from pathlib import Path
ROOT = Path(__file__).resolve().parent.parent
def run_tsc() -> list[str]:
result = subprocess.run(
[str(ROOT / "node_modules/.bin/tsc"), "--noEmit"],
cwd=ROOT,
capture_output=True,
text=True,
)
lines = (result.stdout + result.stderr).splitlines()
return [l for l in lines if "error TS6133" in l or "error TS6198" in l]
def parse_error(line: str) -> tuple[str, int, str, str] | None:
m = re.match(
r"^(src/[^:]+)\((\d+),(\d+)\): error TS(6133|6198): '([^']+)'",
line,
)
if not m:
return None
path, row, col, code, name = m.groups()
return path, int(row), int(col), name, code
def fix_file(path: Path, row: int, name: str, code: str) -> bool:
lines = path.read_text().splitlines(keepends=True)
if row < 1 or row > len(lines):
return False
idx = row - 1
line = lines[idx]
if code == "6198":
# All destructured elements unused — prefix each binding with _
new_line = re.sub(r"\{([^}]+)\}", lambda m: "{" + ", ".join(
(p.strip() if p.strip().startswith("_") else "_" + p.strip().split(":")[0].strip() + (":" + ":".join(p.strip().split(":")[1:]) if ":" in p.strip() else ""))
for p in m.group(1).split(",")
) + "}", line, count=1)
if new_line != line:
lines[idx] = new_line
path.write_text("".join(lines))
return True
return False
# Unused import — remove named import or whole import line
if re.search(rf"\bimport\b.*\b{re.escape(name)}\b", line):
if re.match(r"import\s+\{" , line):
names = re.search(r"\{([^}]+)\}", line)
if names:
parts = [p.strip() for p in names.group(1).split(",")]
kept = []
for p in parts:
base = p.split(" as ")[0].strip()
if base != name:
kept.append(p)
if not kept:
lines[idx] = ""
path.write_text("".join(lines))
return True
new_import = re.sub(r"\{[^}]+\}", "{" + ", ".join(kept) + "}", line)
lines[idx] = new_import
path.write_text("".join(lines))
return True
if re.match(rf"import\s+{re.escape(name)}\s", line) or re.match(rf"import\s+\*\s+as\s+{re.escape(name)}\s", line):
lines[idx] = ""
path.write_text("".join(lines))
return True
# Parameter or local — prefix with underscore
patterns = [
(rf"\(({re.escape(name)})\:", rf"(_{name}:"),
(rf",\s*{re.escape(name)}\:", rf", _{name}:"),
(rf"\(\s*{re.escape(name)}\s*\)", rf"(_{name})"),
(rf"\(\s*{re.escape(name)}\s*,", rf"(_{name},"),
(rf",\s*{re.escape(name)}\s*\)", rf", _{name})"),
(rf"\b(const|let)\s+{re.escape(name)}\b", rf"\1 _{name}"),
(rf"\basync\s+{re.escape(name)}\b", rf"async _{name}"),
(rf"function\s+{re.escape(name)}\b", rf"function _{name}"),
]
new_line = line
for pat, repl in patterns:
new_line2 = re.sub(pat, repl, new_line)
if new_line2 != new_line:
new_line = new_line2
break
else:
# fallback: word boundary prefix in destructuring { name }
new_line = re.sub(rf"\{{([^}}]*)\b{re.escape(name)}\b", rf"{{\1_{name}", line, count=1)
if new_line == line:
new_line = re.sub(rf"\b{re.escape(name)}\b", f"_{name}", line, count=1)
if new_line != line:
lines[idx] = new_line
path.write_text("".join(lines))
return True
return False
def main() -> int:
fixed = 0
for _ in range(5):
errors = run_tsc()
if not errors:
break
changed = False
seen: set[tuple] = set()
for err in errors:
parsed = parse_error(err)
if not parsed:
continue
rel, row, col, name, code = parsed
key = (rel, row, name)
if key in seen:
continue
seen.add(key)
path = ROOT / rel
if fix_file(path, row, name, code):
fixed += 1
changed = True
if not changed:
break
print(f"Fixed {fixed} TS6133/6198 issues")
remaining = run_tsc()
print(f"Remaining TS6133/6198: {len(remaining)}")
return 0
if __name__ == "__main__":
sys.exit(main())