Files
dalbodeule 47461c505f feat: Add script to refresh README from OpenAPI document
refactor: Improve error handling in PowerDNSAPIClient and streamline response processing

fix: Update RecordController to directly return records without unnecessary mapping

refactor: Update DomainRepository and RecordRepository to remove nullable types for IDs

fix: Change User domains fetch strategy to lazy loading for performance improvement

fix: Enhance user authentication handling in UserFilter to ensure authenticated user presence

refactor: Improve DomainService to enforce ownership checks before domain deletion

refactor: Update RecordService to streamline record retrieval and ensure proper domain association

test: Add OpenAPI generation test to validate API documentation endpoint

test: Implement PowerDNSAPIClient tests to verify HTTP method usage and error handling

test: Create DomainService tests to validate domain ownership and deletion logic

test: Add application-test.properties for in-memory database configuration during tests
2026-10-29 23:11:21 +09:00

100 lines
3.5 KiB
Python

#!/usr/bin/env python3
"""Refresh the generated README section from the root OpenAPI document."""
import json
from pathlib import Path
ROOT = Path(__file__).resolve().parents[1]
START = "<!-- BEGIN GENERATED API -->"
END = "<!-- END GENERATED API -->"
METHODS = ("get", "post", "put", "patch", "delete")
def schema_type(schema):
if not schema:
return "—"
if "$ref" in schema:
name = schema["$ref"].rsplit("/", 1)[-1]
return f"[{name}](#{name.lower()})"
if "oneOf" in schema:
return " or ".join(schema_type(part) for part in schema["oneOf"])
kind = schema.get("type", "object")
if isinstance(kind, list):
return " or ".join(
f"array of {schema_type(schema.get('items'))}" if part == "array" else part
for part in kind
)
if kind == "array":
return f"array of {schema_type(schema.get('items'))}"
return kind
def media_schema(content):
return schema_type(content.get("application/json", {}).get("schema"))
def cell(value):
return str(value or "—").replace("|", "\\|").replace("\n", " ")
def generate(spec):
lines = [
"Generated from [openapi.json](openapi.json). Do not edit this section by hand.",
"",
"### Endpoints",
"",
"| Method | Path | Summary | Request body | Success response |",
"| --- | --- | --- | --- | --- |",
]
for path, operations in sorted(spec["paths"].items()):
for method in METHODS:
operation = operations.get(method)
if not operation:
continue
request = media_schema(operation.get("requestBody", {}).get("content", {}))
responses = operation.get("responses", {})
success_code = next((code for code in sorted(responses) if code.startswith("2")), None)
response = responses.get(success_code, {})
result = media_schema(response.get("content", {}))
lines.append(
f"| `{method.upper()}` | `{path}` | {cell(operation.get('summary'))} | "
f"{cell(request)} | {cell(success_code)}: {cell(result)} |"
)
lines.extend(["", "### Schemas", ""])
for name, schema in sorted(spec.get("components", {}).get("schemas", {}).items()):
lines.extend([f"#### {name}", ""])
if schema.get("description"):
lines.extend([schema["description"], ""])
properties = schema.get("properties", {})
if not properties:
lines.extend([f"Type: {schema_type(schema)}", ""])
continue
required = set(schema.get("required", []))
lines.extend(["| Field | Type | Required | Description |", "| --- | --- | --- | --- |"])
for field, definition in properties.items():
lines.append(
f"| `{field}` | {cell(schema_type(definition))} | "
f"{'Yes' if field in required else 'No'} | {cell(definition.get('description'))} |"
)
lines.append("")
return "\n".join(lines).rstrip() + "\n"
def main():
spec = json.loads((ROOT / "openapi.json").read_text(encoding="utf-8"))
readme_path = ROOT / "README.md"
readme = readme_path.read_text(encoding="utf-8")
if readme.count(START) != 1 or readme.count(END) != 1:
raise ValueError("README.md must contain one pair of generated API markers")
before, remainder = readme.split(START, 1)
_, after = remainder.split(END, 1)
readme_path.write_text(before + START + "\n" + generate(spec) + END + after, encoding="utf-8")
if __name__ == "__main__":
main()