Python 88.3%
TypeScript 7.6%
Shell 4.1%
1#!/usr/bin/env python32"""Validate generated/fragments/**/*.json against schemas/*.schema.json.34 .venv/bin/python scripts/validate_fragments.py # report (exit 1 on schema errors)5 .venv/bin/python scripts/validate_fragments.py --lenient # report only67Kind → schema mapping is by directory name. Kinds without a schema are only checked for JSON validity8and the presence of `provider`.9"""10from __future__ import annotations1112import argparse13import json14import sys15from pathlib import Path1617ROOT = Path(__file__).resolve().parent.parent18SCHEMAS = ROOT / "schemas"19FRAG = ROOT / "generated" / "fragments"20KIND_TO_SCHEMA = {"models": "model", "endpoints": "endpoint", "parameters": "parameter", "tools": "tool",21 "streaming-events": "streaming-event", "errors": "error", "pricing": "price"}222324def main() -> int:25 ap = argparse.ArgumentParser()26 ap.add_argument("--lenient", action="store_true")27 args = ap.parse_args()28 try:29 import jsonschema30 from jsonschema import Draft202012Validator31 from referencing import Registry, Resource32 except ImportError:33 print("jsonschema not installed: .venv/bin/pip install jsonschema", file=sys.stderr)34 return 23536 resources = []37 for sf in SCHEMAS.glob("*.schema.json"):38 s = json.loads(sf.read_text())39 resources.append((s["$id"], Resource.from_contents(s)))40 resources.append((sf.name, Resource.from_contents(s)))41 registry = Registry().with_resources(resources)4243 errors = 044 records = 045 for kind_dir in sorted(p for p in FRAG.iterdir() if p.is_dir()) if FRAG.exists() else []:46 schema_name = KIND_TO_SCHEMA.get(kind_dir.name)47 validator = None48 if schema_name:49 schema = json.loads((SCHEMAS / f"{schema_name}.schema.json").read_text())50 validator = Draft202012Validator(schema, registry=registry)51 for f in sorted(kind_dir.glob("*.json")):52 try:53 data = json.loads(f.read_text())54 except Exception as e: # noqa: BLE00155 print(f"INVALID JSON {f.relative_to(ROOT)}: {e}")56 errors += 157 continue58 if isinstance(data, dict):59 data = data.get("records") or data.get("items") or data.get("data") or [data]60 if not isinstance(data, list):61 print(f"NOT A LIST {f.relative_to(ROOT)}")62 errors += 163 continue64 for i, rec in enumerate(data):65 records += 166 if not isinstance(rec, dict) or "provider" not in rec:67 print(f"{f.relative_to(ROOT)}[{i}]: missing provider")68 errors += 169 continue70 if validator:71 for err in sorted(validator.iter_errors(rec), key=lambda e: e.path):72 loc = "/".join(str(p) for p in err.path) or "<root>"73 print(f"{f.relative_to(ROOT)}[{i}] {loc}: {err.message[:160]}")74 errors += 175 print(f"records={records} errors={errors}")76 return 0 if (args.lenient or errors == 0) else 1777879if __name__ == "__main__":80 sys.exit(main())81